diff options
author | peter <peter@FreeBSD.org> | 2008-06-01 00:03:21 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2008-06-01 00:03:21 +0000 |
commit | a2be5f0c15218b0177d73b17d9bcb7589965d685 (patch) | |
tree | c9f0cd9c22378356a1716d32e13e70bc90f98b9c /libstdc++/include | |
parent | 9e0f3cc19c9df1594c9cc36cfd8fddc83c52ad12 (diff) | |
download | FreeBSD-src-a2be5f0c15218b0177d73b17d9bcb7589965d685.zip FreeBSD-src-a2be5f0c15218b0177d73b17d9bcb7589965d685.tar.gz |
Reorganize the gcc vendor import work area. This flattens out a bunch
of unnecessary path components that are relics of cvs2svn.
(These are directory moves)
Diffstat (limited to 'libstdc++/include')
570 files changed, 148786 insertions, 0 deletions
diff --git a/libstdc++/include/Makefile.am b/libstdc++/include/Makefile.am new file mode 100644 index 0000000..6ba5a54 --- /dev/null +++ b/libstdc++/include/Makefile.am @@ -0,0 +1,1211 @@ +## Makefile for the include subdirectory of the GNU C++ Standard library. +## +## Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +## Free Software Foundation, Inc. +## +## This file is part of the libstdc++ version 3 distribution. +## Process this file with automake to produce Makefile.in. + +## 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 $(top_srcdir)/fragment.am + +# Standard C++ includes. +std_srcdir = ${glibcxx_srcdir}/include/std +std_builddir = . +std_headers = \ + ${std_srcdir}/std_algorithm.h \ + ${std_srcdir}/std_bitset.h \ + ${std_srcdir}/std_complex.h \ + ${std_srcdir}/std_deque.h \ + ${std_srcdir}/std_fstream.h \ + ${std_srcdir}/std_functional.h \ + ${std_srcdir}/std_iomanip.h \ + ${std_srcdir}/std_ios.h \ + ${std_srcdir}/std_iosfwd.h \ + ${std_srcdir}/std_iostream.h \ + ${std_srcdir}/std_istream.h \ + ${std_srcdir}/std_iterator.h \ + ${std_srcdir}/std_limits.h \ + ${std_srcdir}/std_list.h \ + ${std_srcdir}/std_locale.h \ + ${std_srcdir}/std_map.h \ + ${std_srcdir}/std_memory.h \ + ${std_srcdir}/std_numeric.h \ + ${std_srcdir}/std_ostream.h \ + ${std_srcdir}/std_queue.h \ + ${std_srcdir}/std_set.h \ + ${std_srcdir}/std_sstream.h \ + ${std_srcdir}/std_stack.h \ + ${std_srcdir}/std_stdexcept.h \ + ${std_srcdir}/std_streambuf.h \ + ${std_srcdir}/std_string.h \ + ${std_srcdir}/std_utility.h \ + ${std_srcdir}/std_valarray.h \ + ${std_srcdir}/std_vector.h +# Renamed at build time. +std_headers_rename = \ + algorithm \ + bitset \ + complex \ + deque \ + fstream \ + functional \ + iomanip \ + ios \ + iosfwd \ + iostream \ + istream \ + iterator \ + limits \ + list \ + locale \ + map \ + memory \ + numeric \ + ostream \ + queue \ + set \ + sstream \ + stack \ + stdexcept \ + streambuf \ + string \ + utility \ + valarray \ + vector + +bits_srcdir = ${glibcxx_srcdir}/include/bits +bits_builddir = ./bits +bits_headers = \ + ${bits_srcdir}/allocator.h \ + ${bits_srcdir}/basic_ios.h \ + ${bits_srcdir}/basic_ios.tcc \ + ${bits_srcdir}/basic_string.h \ + ${bits_srcdir}/basic_string.tcc \ + ${bits_srcdir}/boost_concept_check.h \ + ${bits_srcdir}/char_traits.h \ + ${bits_srcdir}/codecvt.h \ + ${bits_srcdir}/concept_check.h \ + ${bits_srcdir}/cpp_type_traits.h \ + ${bits_srcdir}/deque.tcc \ + ${bits_srcdir}/fstream.tcc \ + ${bits_srcdir}/functexcept.h \ + ${bits_srcdir}/gslice.h \ + ${bits_srcdir}/gslice_array.h \ + ${bits_srcdir}/indirect_array.h \ + ${bits_srcdir}/ios_base.h \ + ${bits_srcdir}/istream.tcc \ + ${bits_srcdir}/list.tcc \ + ${bits_srcdir}/locale_classes.h \ + ${bits_srcdir}/locale_facets.h \ + ${bits_srcdir}/locale_facets.tcc \ + ${bits_srcdir}/localefwd.h \ + ${bits_srcdir}/mask_array.h \ + ${bits_srcdir}/ostream.tcc \ + ${bits_srcdir}/ostream_insert.h \ + ${bits_srcdir}/postypes.h \ + ${bits_srcdir}/stream_iterator.h \ + ${bits_srcdir}/streambuf_iterator.h \ + ${bits_srcdir}/slice_array.h \ + ${bits_srcdir}/sstream.tcc \ + ${bits_srcdir}/stl_algo.h \ + ${bits_srcdir}/stl_algobase.h \ + ${bits_srcdir}/stl_bvector.h \ + ${bits_srcdir}/stl_construct.h \ + ${bits_srcdir}/stl_deque.h \ + ${bits_srcdir}/stl_function.h \ + ${bits_srcdir}/stl_heap.h \ + ${bits_srcdir}/stl_iterator.h \ + ${bits_srcdir}/stl_iterator_base_funcs.h \ + ${bits_srcdir}/stl_iterator_base_types.h \ + ${bits_srcdir}/stl_list.h \ + ${bits_srcdir}/stl_map.h \ + ${bits_srcdir}/stl_multimap.h \ + ${bits_srcdir}/stl_multiset.h \ + ${bits_srcdir}/stl_numeric.h \ + ${bits_srcdir}/stl_pair.h \ + ${bits_srcdir}/stl_queue.h \ + ${bits_srcdir}/stl_raw_storage_iter.h \ + ${bits_srcdir}/stl_relops.h \ + ${bits_srcdir}/stl_set.h \ + ${bits_srcdir}/stl_stack.h \ + ${bits_srcdir}/stl_tempbuf.h \ + ${bits_srcdir}/stl_tree.h \ + ${bits_srcdir}/stl_uninitialized.h \ + ${bits_srcdir}/stl_vector.h \ + ${bits_srcdir}/streambuf.tcc \ + ${bits_srcdir}/stringfwd.h \ + ${bits_srcdir}/valarray_array.h \ + ${bits_srcdir}/valarray_array.tcc \ + ${bits_srcdir}/valarray_before.h \ + ${bits_srcdir}/valarray_after.h \ + ${bits_srcdir}/vector.tcc + +backward_srcdir = ${glibcxx_srcdir}/include/backward +backward_builddir = ./backward +backward_headers = \ + ${backward_srcdir}/complex.h \ + ${backward_srcdir}/iomanip.h \ + ${backward_srcdir}/istream.h \ + ${backward_srcdir}/ostream.h \ + ${backward_srcdir}/stream.h \ + ${backward_srcdir}/streambuf.h \ + ${backward_srcdir}/algo.h \ + ${backward_srcdir}/algobase.h \ + ${backward_srcdir}/alloc.h \ + ${backward_srcdir}/bvector.h \ + ${backward_srcdir}/defalloc.h \ + ${backward_srcdir}/deque.h \ + ${backward_srcdir}/function.h \ + ${backward_srcdir}/hash_map.h \ + ${backward_srcdir}/hash_set.h \ + ${backward_srcdir}/hashtable.h \ + ${backward_srcdir}/heap.h \ + ${backward_srcdir}/iostream.h \ + ${backward_srcdir}/iterator.h \ + ${backward_srcdir}/list.h \ + ${backward_srcdir}/map.h \ + ${backward_srcdir}/multimap.h \ + ${backward_srcdir}/new.h \ + ${backward_srcdir}/multiset.h \ + ${backward_srcdir}/pair.h \ + ${backward_srcdir}/queue.h \ + ${backward_srcdir}/rope.h \ + ${backward_srcdir}/set.h \ + ${backward_srcdir}/slist.h \ + ${backward_srcdir}/stack.h \ + ${backward_srcdir}/tempbuf.h \ + ${backward_srcdir}/tree.h \ + ${backward_srcdir}/vector.h \ + ${backward_srcdir}/fstream.h \ + ${backward_srcdir}/strstream \ + ${backward_srcdir}/backward_warning.h + + +pb_srcdir = ${glibcxx_srcdir}/include/ext/pb_ds +pb_builddir = ./ext/pb_ds + +pb_subdirs = \ + ${pb_builddir}/detail \ + ${pb_builddir}/detail/pairing_heap_ \ + ${pb_builddir}/detail/splay_tree_ \ + ${pb_builddir}/detail/list_update_map_ \ + ${pb_builddir}/detail/basic_tree_policy \ + ${pb_builddir}/detail/trie_policy \ + ${pb_builddir}/detail/gp_hash_table_map_ \ + ${pb_builddir}/detail/tree_policy \ + ${pb_builddir}/detail/binomial_heap_base_ \ + ${pb_builddir}/detail/resize_policy \ + ${pb_builddir}/detail/bin_search_tree_ \ + ${pb_builddir}/detail/binomial_heap_ \ + ${pb_builddir}/detail/thin_heap_ \ + ${pb_builddir}/detail/pat_trie_ \ + ${pb_builddir}/detail/cc_hash_table_map_ \ + ${pb_builddir}/detail/rc_binomial_heap_ \ + ${pb_builddir}/detail/left_child_next_sibling_heap_ \ + ${pb_builddir}/detail/unordered_iterator \ + ${pb_builddir}/detail/binary_heap_ \ + ${pb_builddir}/detail/ov_tree_map_ \ + ${pb_builddir}/detail/hash_fn \ + ${pb_builddir}/detail/eq_fn \ + ${pb_builddir}/detail/rb_tree_map_ \ + ${pb_builddir}/detail/list_update_policy + +# The ability for make and the underlying host to deal with this +# unweildy list as one entire entity is not a sure thing, and may +# cause build errors. Thus, split one list into many smaller +# mini-lists, with the maximum size per mini-list of no more than 42. + +pb_headers1 = \ + ${pb_srcdir}/assoc_container.hpp \ + ${pb_srcdir}/exception.hpp \ + ${pb_srcdir}/hash_policy.hpp \ + ${pb_srcdir}/list_update_policy.hpp \ + ${pb_srcdir}/priority_queue.hpp \ + ${pb_srcdir}/tag_and_trait.hpp \ + ${pb_srcdir}/tree_policy.hpp \ + ${pb_srcdir}/trie_policy.hpp \ + ${pb_srcdir}/detail/basic_tree_policy/basic_tree_policy_base.hpp \ + ${pb_srcdir}/detail/basic_tree_policy/null_node_metadata.hpp \ + ${pb_srcdir}/detail/basic_tree_policy/traits.hpp \ + ${pb_srcdir}/detail/basic_types.hpp \ + ${pb_srcdir}/detail/binary_heap_/binary_heap_.hpp \ + ${pb_srcdir}/detail/binary_heap_/const_iterator.hpp \ + ${pb_srcdir}/detail/binary_heap_/const_point_iterator.hpp \ + ${pb_srcdir}/detail/binary_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/entry_cmp.hpp \ + ${pb_srcdir}/detail/binary_heap_/entry_pred.hpp \ + ${pb_srcdir}/detail/binary_heap_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/resize_policy.hpp \ + ${pb_srcdir}/detail/binary_heap_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/binomial_heap_base_.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_/binomial_heap_.hpp \ + ${pb_srcdir}/detail/binomial_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/bin_search_tree_.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/cond_dtor_entry_dealtor.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/cond_key_dtor_entry_dealtor.hpp + +pb_headers2 = \ + ${pb_srcdir}/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/node_iterators.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/point_iterators.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/r_erase_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/rotate_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/traits.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/cc_ht_map_.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/cmp_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/entry_list_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/resize_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/size_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/standard_policies.hpp + +pb_headers3 = \ + ${pb_srcdir}/detail/cc_hash_table_map_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/cond_dealtor.hpp \ + ${pb_srcdir}/detail/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/container_base_dispatch.hpp \ + ${pb_srcdir}/detail/eq_fn/eq_by_less.hpp \ + ${pb_srcdir}/detail/eq_fn/hash_eq_fn.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/gp_ht_map_.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/iterator_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/resize_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/standard_policies.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/hash_fn/direct_mask_range_hashing_imp.hpp \ + ${pb_srcdir}/detail/hash_fn/direct_mod_range_hashing_imp.hpp \ + ${pb_srcdir}/detail/hash_fn/linear_probe_fn_imp.hpp \ + ${pb_srcdir}/detail/hash_fn/mask_based_range_hashing.hpp \ + ${pb_srcdir}/detail/hash_fn/mod_based_range_hashing.hpp \ + ${pb_srcdir}/detail/hash_fn/probe_fn_base.hpp \ + ${pb_srcdir}/detail/hash_fn/quadratic_probe_fn_imp.hpp \ + ${pb_srcdir}/detail/hash_fn/ranged_hash_fn.hpp \ + ${pb_srcdir}/detail/hash_fn/ranged_probe_fn.hpp + +pb_headers4 = \ + ${pb_srcdir}/detail/hash_fn/sample_probe_fn.hpp \ + ${pb_srcdir}/detail/hash_fn/sample_ranged_hash_fn.hpp \ + ${pb_srcdir}/detail/hash_fn/sample_ranged_probe_fn.hpp \ + ${pb_srcdir}/detail/hash_fn/sample_range_hashing.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/const_iterator.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/const_point_iterator.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/node.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/null_metadata.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/constructor_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/entry_metadata_base.hpp \ + ${pb_srcdir}/detail/list_update_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/lu_map_.hpp \ + ${pb_srcdir}/detail/list_update_map_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_policy/counter_lu_metadata.hpp \ + ${pb_srcdir}/detail/list_update_policy/counter_lu_policy_imp.hpp \ + ${pb_srcdir}/detail/list_update_policy/mtf_lu_policy_imp.hpp \ + ${pb_srcdir}/detail/list_update_policy/sample_update_policy.hpp \ + ${pb_srcdir}/detail/map_debug_base.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/cond_dtor.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/node_iterators.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/ov_tree_map_.hpp + +pb_headers5 = \ + ${pb_srcdir}/detail/ov_tree_map_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/traits.hpp \ + ${pb_srcdir}/detail/pairing_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/pairing_heap_.hpp \ + ${pb_srcdir}/detail/pairing_heap_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/child_iterator.hpp \ + ${pb_srcdir}/detail/pat_trie_/cond_dtor_entry_dealtor.hpp \ + ${pb_srcdir}/detail/pat_trie_/const_child_iterator.hpp \ + ${pb_srcdir}/detail/pat_trie_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/head.hpp \ + ${pb_srcdir}/detail/pat_trie_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/insert_join_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/internal_node.hpp \ + ${pb_srcdir}/detail/pat_trie_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/leaf.hpp \ + ${pb_srcdir}/detail/pat_trie_/node_base.hpp \ + ${pb_srcdir}/detail/pat_trie_/node_iterators.hpp \ + ${pb_srcdir}/detail/pat_trie_/node_metadata_base.hpp \ + ${pb_srcdir}/detail/pat_trie_/pat_trie_.hpp \ + ${pb_srcdir}/detail/pat_trie_/point_iterators.hpp \ + ${pb_srcdir}/detail/pat_trie_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/r_erase_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/rotate_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/split_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/split_join_branch_bag.hpp \ + ${pb_srcdir}/detail/pat_trie_/synth_e_access_traits.hpp \ + ${pb_srcdir}/detail/pat_trie_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/traits.hpp \ + ${pb_srcdir}/detail/pat_trie_/update_fn_imps.hpp \ + ${pb_srcdir}/detail/priority_queue_base_dispatch.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/debug_fn_imps.hpp + +pb_headers6 = \ + ${pb_srcdir}/detail/rb_tree_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/node.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/rb_tree_.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/traits.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/rc_binomial_heap_.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/rc.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_exponential_size_policy_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_prime_size_policy_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_standard_resize_policy_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/sample_resize_policy.hpp \ + ${pb_srcdir}/detail/resize_policy/sample_resize_trigger.hpp \ + ${pb_srcdir}/detail/resize_policy/sample_size_policy.hpp \ + ${pb_srcdir}/detail/splay_tree_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/node.hpp \ + ${pb_srcdir}/detail/splay_tree_/splay_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/splay_tree_.hpp \ + ${pb_srcdir}/detail/splay_tree_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/traits.hpp \ + ${pb_srcdir}/detail/standard_policies.hpp \ + ${pb_srcdir}/detail/thin_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/erase_fn_imps.hpp + +pb_headers7 = \ + ${pb_srcdir}/detail/thin_heap_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/thin_heap_.hpp \ + ${pb_srcdir}/detail/thin_heap_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/tree_policy/node_metadata_selector.hpp \ + ${pb_srcdir}/detail/tree_policy/null_node_update_imp.hpp \ + ${pb_srcdir}/detail/tree_policy/order_statistics_imp.hpp \ + ${pb_srcdir}/detail/tree_policy/sample_tree_node_update.hpp \ + ${pb_srcdir}/detail/tree_trace_base.hpp \ + ${pb_srcdir}/detail/trie_policy/node_metadata_selector.hpp \ + ${pb_srcdir}/detail/trie_policy/null_node_update_imp.hpp \ + ${pb_srcdir}/detail/trie_policy/order_statistics_imp.hpp \ + ${pb_srcdir}/detail/trie_policy/prefix_search_node_update_imp.hpp \ + ${pb_srcdir}/detail/trie_policy/sample_trie_e_access_traits.hpp \ + ${pb_srcdir}/detail/trie_policy/sample_trie_node_update.hpp \ + ${pb_srcdir}/detail/trie_policy/string_trie_e_access_traits_imp.hpp \ + ${pb_srcdir}/detail/trie_policy/trie_policy_base.hpp \ + ${pb_srcdir}/detail/types_traits.hpp \ + ${pb_srcdir}/detail/type_utils.hpp \ + ${pb_srcdir}/detail/unordered_iterator/const_iterator.hpp \ + ${pb_srcdir}/detail/unordered_iterator/const_point_iterator.hpp \ + ${pb_srcdir}/detail/unordered_iterator/iterator.hpp \ + ${pb_srcdir}/detail/unordered_iterator/point_iterator.hpp + + + +ext_srcdir = ${glibcxx_srcdir}/include/ext +ext_builddir = ./ext +ext_headers = \ + ${ext_srcdir}/algorithm \ + ${ext_srcdir}/atomicity.h \ + ${ext_srcdir}/array_allocator.h \ + ${ext_srcdir}/bitmap_allocator.h \ + ${ext_srcdir}/codecvt_specializations.h \ + ${ext_srcdir}/concurrence.h \ + ${ext_srcdir}/debug_allocator.h \ + ${ext_srcdir}/stdio_filebuf.h \ + ${ext_srcdir}/stdio_sync_filebuf.h \ + ${ext_srcdir}/functional \ + ${ext_srcdir}/hash_map \ + ${ext_srcdir}/hash_set \ + ${ext_srcdir}/hash_fun.h \ + ${ext_srcdir}/hashtable.h \ + ${ext_srcdir}/iterator \ + ${ext_srcdir}/malloc_allocator.h \ + ${ext_srcdir}/memory \ + ${ext_srcdir}/mt_allocator.h \ + ${ext_srcdir}/new_allocator.h \ + ${ext_srcdir}/numeric \ + ${ext_srcdir}/numeric_traits.h \ + ${ext_srcdir}/pod_char_traits.h \ + ${ext_srcdir}/pool_allocator.h \ + ${ext_srcdir}/rb_tree \ + ${ext_srcdir}/rope \ + ${ext_srcdir}/ropeimpl.h \ + ${ext_srcdir}/slist \ + ${ext_srcdir}/throw_allocator.h \ + ${ext_srcdir}/typelist.h \ + ${ext_srcdir}/type_traits.h \ + ${ext_srcdir}/rc_string_base.h \ + ${ext_srcdir}/sso_string_base.h \ + ${ext_srcdir}/vstring.h \ + ${ext_srcdir}/vstring.tcc \ + ${ext_srcdir}/vstring_fwd.h \ + ${ext_srcdir}/vstring_util.h + + +tr1_srcdir = ${glibcxx_srcdir}/include/tr1 +tr1_builddir = ./tr1 +tr1_headers = \ + ${tr1_srcdir}/array \ + ${tr1_srcdir}/bind_repeat.h \ + ${tr1_srcdir}/bind_iterate.h \ + ${tr1_srcdir}/boost_shared_ptr.h \ + ${tr1_srcdir}/cctype \ + ${tr1_srcdir}/cfenv \ + ${tr1_srcdir}/cfloat \ + ${tr1_srcdir}/cinttypes \ + ${tr1_srcdir}/climits \ + ${tr1_srcdir}/cmath \ + ${tr1_srcdir}/common.h \ + ${tr1_srcdir}/complex \ + ${tr1_srcdir}/cstdarg \ + ${tr1_srcdir}/cstdbool \ + ${tr1_srcdir}/cstdint \ + ${tr1_srcdir}/cstdio \ + ${tr1_srcdir}/cstdlib \ + ${tr1_srcdir}/ctgmath \ + ${tr1_srcdir}/ctime \ + ${tr1_srcdir}/ctype.h \ + ${tr1_srcdir}/cwchar \ + ${tr1_srcdir}/cwctype \ + ${tr1_srcdir}/fenv.h \ + ${tr1_srcdir}/float.h \ + ${tr1_srcdir}/functional \ + ${tr1_srcdir}/functional_hash.h \ + ${tr1_srcdir}/functional_iterate.h \ + ${tr1_srcdir}/hashtable \ + ${tr1_srcdir}/hashtable_policy.h \ + ${tr1_srcdir}/inttypes.h \ + ${tr1_srcdir}/limits.h \ + ${tr1_srcdir}/math.h \ + ${tr1_srcdir}/memory \ + ${tr1_srcdir}/mu_iterate.h \ + ${tr1_srcdir}/random \ + ${tr1_srcdir}/random.tcc \ + ${tr1_srcdir}/ref_fwd.h \ + ${tr1_srcdir}/ref_wrap_iterate.h \ + ${tr1_srcdir}/repeat.h \ + ${tr1_srcdir}/stdarg.h \ + ${tr1_srcdir}/stdbool.h \ + ${tr1_srcdir}/stdint.h \ + ${tr1_srcdir}/stdio.h \ + ${tr1_srcdir}/stdlib.h \ + ${tr1_srcdir}/tgmath.h \ + ${tr1_srcdir}/tuple \ + ${tr1_srcdir}/tuple_defs.h \ + ${tr1_srcdir}/tuple_iterate.h \ + ${tr1_srcdir}/type_traits \ + ${tr1_srcdir}/type_traits_fwd.h \ + ${tr1_srcdir}/unordered_set \ + ${tr1_srcdir}/unordered_map \ + ${tr1_srcdir}/utility \ + ${tr1_srcdir}/wchar.h \ + ${tr1_srcdir}/wctype.h + + +# This is the common subset of files that all three "C" header models use. +c_base_srcdir = $(C_INCLUDE_DIR) +c_base_builddir = . +c_base_headers = \ + ${c_base_srcdir}/std_cassert.h \ + ${c_base_srcdir}/std_cctype.h \ + ${c_base_srcdir}/std_cerrno.h \ + ${c_base_srcdir}/std_cfloat.h \ + ${c_base_srcdir}/std_ciso646.h \ + ${c_base_srcdir}/std_climits.h \ + ${c_base_srcdir}/std_clocale.h \ + ${c_base_srcdir}/std_cmath.h \ + ${c_base_srcdir}/std_csetjmp.h \ + ${c_base_srcdir}/std_csignal.h \ + ${c_base_srcdir}/std_cstdarg.h \ + ${c_base_srcdir}/std_cstddef.h \ + ${c_base_srcdir}/std_cstdio.h \ + ${c_base_srcdir}/std_cstdlib.h \ + ${c_base_srcdir}/std_cstring.h \ + ${c_base_srcdir}/std_ctime.h \ + ${c_base_srcdir}/std_cwchar.h \ + ${c_base_srcdir}/std_cwctype.h +c_base_headers_rename = \ + cassert \ + cctype \ + cerrno \ + cfloat \ + ciso646 \ + climits \ + clocale \ + cmath \ + csetjmp \ + csignal \ + cstdarg \ + cstddef \ + cstdio \ + cstdlib \ + cstring \ + ctime \ + cwchar \ + cwctype + +# "C" compatibility headers. +c_compatibility_srcdir = ${glibcxx_srcdir}/include/c_compatibility +c_compatibility_builddir = . +c_compatibility_headers = \ + ${c_compatibility_srcdir}/assert.h \ + ${c_compatibility_srcdir}/ctype.h \ + ${c_compatibility_srcdir}/errno.h \ + ${c_compatibility_srcdir}/float.h \ + ${c_compatibility_srcdir}/iso646.h \ + ${c_compatibility_srcdir}/limits.h \ + ${c_compatibility_srcdir}/locale.h \ + ${c_compatibility_srcdir}/math.h \ + ${c_compatibility_srcdir}/setjmp.h \ + ${c_compatibility_srcdir}/signal.h \ + ${c_compatibility_srcdir}/stdarg.h \ + ${c_compatibility_srcdir}/stddef.h \ + ${c_compatibility_srcdir}/stdio.h \ + ${c_compatibility_srcdir}/stdlib.h \ + ${c_compatibility_srcdir}/string.h \ + ${c_compatibility_srcdir}/time.h \ + ${c_compatibility_srcdir}/wchar.h \ + ${c_compatibility_srcdir}/wctype.h + +# Debug mode headers +debug_srcdir = ${glibcxx_srcdir}/include/debug +debug_builddir = ./debug +debug_headers = \ + ${debug_srcdir}/bitset \ + ${debug_srcdir}/debug.h \ + ${debug_srcdir}/deque \ + ${debug_srcdir}/formatter.h \ + ${debug_srcdir}/functions.h \ + ${debug_srcdir}/hash_map \ + ${debug_srcdir}/hash_map.h \ + ${debug_srcdir}/hash_multimap.h \ + ${debug_srcdir}/hash_multiset.h \ + ${debug_srcdir}/hash_set \ + ${debug_srcdir}/hash_set.h \ + ${debug_srcdir}/list \ + ${debug_srcdir}/map \ + ${debug_srcdir}/macros.h \ + ${debug_srcdir}/map.h \ + ${debug_srcdir}/multimap.h \ + ${debug_srcdir}/multiset.h \ + ${debug_srcdir}/safe_base.h \ + ${debug_srcdir}/safe_iterator.h \ + ${debug_srcdir}/safe_iterator.tcc \ + ${debug_srcdir}/safe_sequence.h \ + ${debug_srcdir}/set \ + ${debug_srcdir}/set.h \ + ${debug_srcdir}/string \ + ${debug_srcdir}/vector + +# Some of the different "C" header models need extra files. +# Some "C" header schemes require the "C" compatibility headers. +# For --enable-cheaders=c_std +if GLIBCXX_C_HEADERS_C_STD +c_base_headers_extra = ${c_base_srcdir}/cmath.tcc +else +c_base_headers_extra = +endif + +if GLIBCXX_C_HEADERS_COMPATIBILITY +c_compatibility_headers_extra = ${c_compatibility_headers} +else +c_compatibility_headers_extra = +endif + +host_srcdir = ${glibcxx_srcdir}/$(OS_INC_SRCDIR) +host_builddir = ./${host_alias}/bits +host_installdir = ${gxx_include_dir}/${host_alias}$(MULTISUBDIR)/bits +host_headers = \ + ${host_srcdir}/ctype_base.h \ + ${host_srcdir}/ctype_inline.h \ + ${host_srcdir}/ctype_noninline.h \ + ${host_srcdir}/os_defines.h \ + ${glibcxx_srcdir}/$(ATOMIC_WORD_SRCDIR)/atomic_word.h \ + ${glibcxx_srcdir}/$(ABI_TWEAKS_SRCDIR)/cxxabi_tweaks.h \ + ${glibcxx_srcdir}/$(CPU_DEFINES_SRCDIR)/cpu_defines.h + +# Non-installed host_header files. +COMPATIBILITY_H = config/abi/compatibility.h +host_headers_noinst = \ + ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) \ + ${glibcxx_srcdir}/$(COMPATIBILITY_H) + +# These host_headers_extra files are all built with ad hoc naming rules. +host_headers_extra = \ + ${host_builddir}/basic_file.h \ + ${host_builddir}/c++config.h \ + ${host_builddir}/c++allocator.h \ + ${host_builddir}/c++io.h \ + ${host_builddir}/c++locale.h \ + ${host_builddir}/messages_members.h \ + ${host_builddir}/time_members.h + +thread_host_headers = \ + ${host_builddir}/gthr.h \ + ${host_builddir}/gthr-single.h \ + ${host_builddir}/gthr-posix.h \ + ${host_builddir}/gthr-tpf.h \ + ${host_builddir}/gthr-default.h + + +pch1_source = ${glibcxx_srcdir}/include/precompiled/stdc++.h +pch1_output_builddir = ${host_builddir}/stdc++.h.gch +pch1_output_anchor = ${host_builddir}/stdc++.h +pch1_output_installdir = ${host_installdir}/stdc++.h.gch +pch1a_output = ${pch1_output_builddir}/O0g.gch +pch1b_output = ${pch1_output_builddir}/O2g.gch +pch1_output = ${pch1a_output} ${pch1b_output} + +pch2_source = ${glibcxx_srcdir}/include/precompiled/stdtr1c++.h +pch2_output_builddir = ${host_builddir}/stdtr1c++.h.gch +pch2_output_anchor = ${host_builddir}/stdtr1c++.h +pch2_output_installdir = ${host_installdir}/stdtr1c++.h.gch +pch2_output = ${pch2_output_builddir}/O2g.gch + +pch3_source = ${glibcxx_srcdir}/include/precompiled/extc++.h +pch3_output_builddir = ${host_builddir}/extc++.h.gch +pch3_output_anchor = ${host_builddir}/extc++.h +pch3_output_installdir = ${host_installdir}/extc++.h.gch +pch3_output = ${pch3_output_builddir}/O2g.gch + + +pch_output = ${pch1_output} ${pch2_output} ${pch3_output} +pch_output_dirs = \ + ${pch1_output_builddir} ${pch2_output_builddir} ${pch3_output_builddir} +pch_output_anchors = \ + ${pch1_output_anchor} ${pch2_output_anchor} ${pch3_output_anchor} +PCHFLAGS=-Winvalid-pch -Wno-deprecated -x c++-header $(CXXFLAGS) +if GLIBCXX_BUILD_PCH +pch_build = ${pch_output} +pch_install = install-pch +else +pch_build = +pch_install = +endif + +# List of all timestamp files. By keeping only one copy of this list, both +# CLEANFILES and all-local are kept up-to-date. +allstamped = \ + stamp-std stamp-bits stamp-c_base stamp-c_compatibility \ + stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-debug stamp-host + +# List of all files that are created by explicit building, editing, or +# catenation. +allcreated = \ + ${host_builddir}/c++config.h \ + ${thread_host_headers} \ + ${pch_build} + +# Here are the rules for building the headers +all-local: ${allstamped} ${allcreated} + +# This rule is slightly different, in that we must change the name of the +# local file from std_foo.h to foo. +stamp-std: ${std_headers} + @if [ ! -d "${std_builddir}" ]; then \ + mkdir -p ${std_builddir} ;\ + fi ;\ + if [ ! -f stamp-std ]; then \ + (cd ${std_builddir} && for h in $?; do \ + build_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ + $(LN_S) $$h ./$${build_name} || true ;\ + done) ;\ + fi ;\ + $(STAMP) stamp-std + +stamp-bits: ${bits_headers} + @if [ ! -d "${bits_builddir}" ]; then \ + mkdir -p ${bits_builddir} ;\ + fi ;\ + if [ ! -f stamp-bits ]; then \ + (cd ${bits_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-bits + +stamp-c_base: stamp-bits ${c_base_headers} ${c_base_headers_extra} + @if [ ! -d "${c_base_builddir}" ]; then \ + mkdir -p ${c_base_builddir} ;\ + fi ;\ + if [ ! -f stamp-c_base ]; then \ + (cd ${c_base_builddir} && for h in ${c_base_headers}; do \ + build_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ + $(LN_S) $$h ./$${build_name} || true ;\ + done) ;\ + if [ ! -z "${c_base_headers_extra}" ]; then \ + (cd ${bits_builddir} && $(LN_S) ${c_base_headers_extra} . || true) ;\ + fi ;\ + fi ;\ + $(STAMP) stamp-c_base + +stamp-c_compatibility: ${c_compatibility_headers_extra} + @if [ ! -d "${c_compatibility_builddir}" ]; then \ + mkdir -p ${c_compatibility_builddir} ;\ + fi ;\ + if [ ! -f stamp-c_compatibility ]; then \ + if [ ! -z "${c_compatibility_headers_extra}" ]; then \ + (cd ${c_compatibility_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + fi ;\ + $(STAMP) stamp-c_compatibility + +stamp-backward: ${backward_headers} + @if [ ! -d "${backward_builddir}" ]; then \ + mkdir -p ${backward_builddir} ;\ + fi ;\ + if [ ! -f stamp-backward ]; then \ + (cd ${backward_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-backward + +stamp-ext: ${ext_headers} + @if [ ! -d "${ext_builddir}" ]; then \ + mkdir -p ${ext_builddir} ;\ + fi ;\ + if [ ! -f stamp-ext ]; then \ + (cd ${ext_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-ext + +# Have to deal with nested include directories, gah! Strip off source +# directory before making the link. +# XXX check ${pb_headers} +stamp-pb: + @if [ ! -d "${pb_builddir}" ]; then \ + mkdir -p ${pb_subdirs} ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers1}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers2}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers3}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers4}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers5}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers6}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers7}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + $(STAMP) stamp-pb + +stamp-tr1: ${tr1_headers} + @if [ ! -d "${tr1_builddir}" ]; then \ + mkdir -p ${tr1_builddir} ;\ + fi ;\ + if [ ! -f stamp-tr1 ]; then \ + (cd ${tr1_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-tr1 + +stamp-debug: ${debug_headers} + @if [ ! -d "${debug_builddir}" ]; then \ + mkdir -p ${debug_builddir} ;\ + fi ;\ + if [ ! -f stamp-debug ]; then \ + (cd ${debug_builddir} && @LN_S@ $? . || true) ;\ + fi ;\ + $(STAMP) stamp-debug + +stamp-${host_alias}: + @if [ ! -d ${host_builddir} ]; then \ + mkdir -p ${host_builddir} ;\ + fi ;\ + $(STAMP) stamp-${host_alias} + +# Host includes static. +# XXX Missing dependency info for {host_headers_extra} +stamp-host: ${host_headers} ${host_headers_noinst} stamp-${host_alias} + @if [ ! -f stamp-host ]; then \ + (cd ${host_builddir} ;\ + $(LN_S) ${host_headers} . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_H) basic_file.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(ALLOCATOR_H) c++allocator.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CSTDIO_H) c++io.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_H) c++locale.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(COMPATIBILITY_H) . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CMESSAGES_H) messages_members.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CTIME_H) time_members.h || true);\ + fi ;\ + $(STAMP) stamp-host + +# Host includes dynamic. +if ENABLE_SYMVERS_GNU_NAMESPACE +stamp-namespace-version: + echo 1 > stamp-namespace-version +else +stamp-namespace-version: + echo 0 > stamp-namespace-version +endif + +if ENABLE_VISIBILITY +stamp-visibility: + echo 1 > stamp-visibility +else +stamp-visibility: + echo 0 > stamp-visibility +endif + +# NB: The non-empty default ldbl_compat works around an AIX sed +# oddity, see libstdc++/31957 for details. +${host_builddir}/c++config.h: ${CONFIG_HEADER} \ + ${glibcxx_srcdir}/include/bits/c++config \ + stamp-${host_alias} \ + ${toplevel_srcdir}/gcc/DATESTAMP \ + stamp-namespace-version \ + stamp-visibility + @date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\ + nsa_version=`cat stamp-namespace-version` ;\ + visibility=`cat stamp-visibility` ;\ + ldbl_compat='s,g,g,' ;\ + grep "^[ ]*#[ ]*define[ ][ ]*_GLIBCXX_LONG_DOUBLE_COMPAT[ ][ ]*1[ ]*$$" \ + ${CONFIG_HEADER} > /dev/null 2>&1 \ + && ldbl_compat='s,^#undef _GLIBCXX_LONG_DOUBLE_COMPAT$$,#define _GLIBCXX_LONG_DOUBLE_COMPAT 1,' ;\ + sed -e "s,define __GLIBCXX__,define __GLIBCXX__ $$date," \ + -e "s,define _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION, define _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION $$nsa_version," \ + -e "s,define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY, define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY $$visibility," \ + -e "$$ldbl_compat" \ + < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\ + sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \ + -e 's/PACKAGE/_GLIBCXX_PACKAGE/g' \ + -e 's/VERSION/_GLIBCXX_VERSION/g' \ + -e 's/WORDS_/_GLIBCXX_WORDS_/g' \ + -e '/[ ]_GLIBCXX_LONG_DOUBLE_COMPAT[ ]/d' \ + < ${CONFIG_HEADER} >> $@ ;\ + echo "" >> $@ ;\ + echo "#endif // _CXXCONFIG_" >> $@ + +# Host includes for threads +uppercase = [ABCDEFGHIJKLMNOPQRSTUVWXYZ_] + +${host_builddir}/gthr.h: ${toplevel_srcdir}/gcc/gthr.h stamp-${host_alias} + sed -e '/^#pragma/b' \ + -e '/^#/s/\(${uppercase}${uppercase}*\)/_GLIBCXX_\1/g' \ + -e 's/_GLIBCXX_SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's,^#include "\(.*\)",#include <bits/\1>,g' \ + < ${toplevel_srcdir}/gcc/gthr.h > $@ + +${host_builddir}/gthr-single.h: ${toplevel_srcdir}/gcc/gthr-single.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + < ${toplevel_srcdir}/gcc/gthr-single.h > $@ + +${host_builddir}/gthr-posix.h: ${toplevel_srcdir}/gcc/gthr-posix.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ + < ${toplevel_srcdir}/gcc/gthr-posix.h > $@ + +${host_builddir}/gthr-tpf.h: ${toplevel_srcdir}/gcc/gthr-tpf.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ + < ${toplevel_srcdir}/gcc/gthr-tpf.h > $@ + +${host_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcxx_thread_h} \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ + -e 's,^#include "\(.*\)",#include <bits/\1>,g' \ + < ${toplevel_srcdir}/gcc/${glibcxx_thread_h} > $@ + +# Build two precompiled C++ includes, stdc++.h.gch/*.gch +${pch1a_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source} + if [ ! -d "${pch1_output_builddir}" ]; then \ + mkdir -p ${pch1_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O0 -g ${pch1_source} -o $@ + touch ${pch1_output_anchor} + +${pch1b_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source} + if [ ! -d "${pch1_output_builddir}" ]; then \ + mkdir -p ${pch1_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g ${pch1_source} -o $@ + touch ${pch1_output_anchor} + +# Build a precompiled TR1 include, stdtr1c++.h.gch/O2.gch +${pch2_output}: ${pch2_source} ${pch1_output} + if [ ! -d "${pch2_output_builddir}" ]; then \ + mkdir -p ${pch2_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g ${pch2_source} -o $@ + touch ${pch2_output_anchor} + +# Build a precompiled extension include, extc++.h.gch/O2.gch +${pch3_output}: ${pch3_source} ${pch2_output} + if [ ! -d "${pch3_output_builddir}" ]; then \ + mkdir -p ${pch3_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g ${pch3_source} -o $@ + touch ${pch3_output_anchor} + +# For robustness sake (in light of junk files or in-source +# configuration), copy from the build or source tree to the install +# tree using only the human-maintained file lists and directory +# components. Yes, with minor differences, this is sheer duplication +# of the staging rules above using $(INSTALL_DATA) instead of LN_S and +# `$(mkinstalldirs)' instead of `mkdir -p'. In particular, +# host_headers_extra are taken out of the build tree staging area; +# the rest are taken from the original source tree. + +if GLIBCXX_HOSTED +install-data-local: install-headers ${pch_install} +else +install-data-local: install-freestanding-headers +endif + +# This is a subset of the full install-headers rule. We only need <cstddef>, +# <limits>, <cstdlib>, <cstdarg>, <new>, <typeinfo>, <exception>, and any +# files which they include (and which we provide). The last three headers +# are installed by libsupc++, so only the first four and the sub-includes +# are copied here. +install-freestanding-headers: + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} + $(mkinstalldirs) $(DESTDIR)${host_installdir} + for file in ${host_srcdir}/os_defines.h ${host_builddir}/c++config.h; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} + $(INSTALL_DATA) ${std_builddir}/limits $(DESTDIR)${gxx_include_dir}/${std_builddir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} + for file in cstddef cstdlib cstdarg; do \ + $(INSTALL_DATA) ${c_base_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done + +# The real deal. +install-headers: + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${bits_builddir} + for file in ${bits_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${bits_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${backward_builddir} + for file in ${backward_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${backward_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${ext_builddir} + for file in ${ext_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${ext_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${pb_builddir} + for dir in ${pb_subdirs}; do \ + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/$${dir} ; done + for file in ${pb_headers1}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers2}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers3}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers4}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers5}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers6}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers7}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${tr1_builddir} + for file in ${tr1_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${tr1_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} + for file in ${c_base_headers_rename}; do \ + $(INSTALL_DATA) ${c_base_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done + c_base_headers_extra_install='$(c_base_headers_extra)';\ + for file in $$c_base_headers_extra_install; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}/${bits_builddir}; done + c_compatibility_headers_install='$(c_compatibility_headers_extra)';\ + for file in $$c_compatibility_headers_install; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} + for file in ${std_headers_rename}; do \ + $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${debug_builddir} + for file in ${debug_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${debug_builddir}; done + $(mkinstalldirs) $(DESTDIR)${host_installdir} + for file in ${host_headers} ${host_headers_extra} \ + ${thread_host_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}; done + +install-pch: + $(mkinstalldirs) $(DESTDIR)${pch1_output_installdir} + for file in ${pch1_output_builddir}/*; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${pch1_output_installdir}; done + $(mkinstalldirs) $(DESTDIR)${pch2_output_installdir} + for file in ${pch2_output_builddir}/*; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${pch2_output_installdir}; done + $(INSTALL_DATA) ${pch1_output_anchor} $(DESTDIR)${host_installdir} + $(INSTALL_DATA) ${pch2_output_anchor} $(DESTDIR)${host_installdir} + +# By adding these files here, automake will remove them for 'make clean' +CLEANFILES = ${pch_output} ${pch_output_anchors} + +# To remove directories. +clean-local: + rm -rf ${pch_output_dirs} + +# Stop implicit '.o' make rules from ever stomping on extensionless +# headers, in the improbable case where some foolish, crack-addled +# developer tries to create them via make in the include build +# directory. (This is more of an example of how this kind of rule can +# be made.) +.PRECIOUS: $(std_headers_rename) $(c_base_headers_rename) +$(std_headers_rename): ; @: +$(c_base_headers_rename): ; @: diff --git a/libstdc++/include/Makefile.in b/libstdc++/include/Makefile.in new file mode 100644 index 0000000..12ed4d3 --- /dev/null +++ b/libstdc++/include/Makefile.in @@ -0,0 +1,1582 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/fragment.am +subdir = include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/no-executables.m4 \ + $(top_srcdir)/../config/unwind_ipinfo.m4 \ + $(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \ + $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +depcomp = +am__depfiles_maybe = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ABI_TWEAKS_SRCDIR = @ABI_TWEAKS_SRCDIR@ +ACLOCAL = @ACLOCAL@ +ALLOCATOR_H = @ALLOCATOR_H@ +ALLOCATOR_NAME = @ALLOCATOR_NAME@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +ATOMICITY_SRCDIR = @ATOMICITY_SRCDIR@ +ATOMIC_WORD_SRCDIR = @ATOMIC_WORD_SRCDIR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASIC_FILE_CC = @BASIC_FILE_CC@ +BASIC_FILE_H = @BASIC_FILE_H@ +CC = @CC@ +CCODECVT_CC = @CCODECVT_CC@ +CCOLLATE_CC = @CCOLLATE_CC@ +CCTYPE_CC = @CCTYPE_CC@ +CFLAGS = @CFLAGS@ +CLOCALE_CC = @CLOCALE_CC@ +CLOCALE_H = @CLOCALE_H@ +CLOCALE_INTERNAL_H = @CLOCALE_INTERNAL_H@ +CMESSAGES_CC = @CMESSAGES_CC@ +CMESSAGES_H = @CMESSAGES_H@ +CMONEY_CC = @CMONEY_CC@ +CNUMERIC_CC = @CNUMERIC_CC@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU_DEFINES_SRCDIR = @CPU_DEFINES_SRCDIR@ +CSTDIO_H = @CSTDIO_H@ +CTIME_CC = @CTIME_CC@ +CTIME_H = @CTIME_H@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +C_INCLUDE_DIR = @C_INCLUDE_DIR@ +DEBUG_FLAGS = @DEBUG_FLAGS@ +DEFS = @DEFS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@ +ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@ +ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@ +ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@ +ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@ +ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ +ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@ +ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@ +ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@ +ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@ +EXEEXT = @EXEEXT@ +EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@ +GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@ +GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@ +GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@ +GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@ +GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@ +GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@ +GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@ +GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@ +GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@ +GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@ +GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@ +GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@ +GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@ +GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@ +GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LIBICONV = @LIBICONV@ +LIBMATHOBJS = @LIBMATHOBJS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@ +OPT_LDFLAGS = @OPT_LDFLAGS@ +OS_INC_SRCDIR = @OS_INC_SRCDIR@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SECTION_FLAGS = @SECTION_FLAGS@ +SECTION_LDFLAGS = @SECTION_LDFLAGS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYMVER_FILE = @SYMVER_FILE@ +TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARN_FLAGS = @WARN_FLAGS@ +WERROR = @WERROR@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_AS = @ac_ct_AS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +baseline_dir = @baseline_dir@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +check_msgfmt = @check_msgfmt@ +datadir = @datadir@ +enable_shared = @enable_shared@ +enable_static = @enable_static@ +exec_prefix = @exec_prefix@ +glibcxx_MOFILES = @glibcxx_MOFILES@ +glibcxx_PCHFLAGS = @glibcxx_PCHFLAGS@ +glibcxx_POFILES = @glibcxx_POFILES@ +glibcxx_builddir = @glibcxx_builddir@ +glibcxx_localedir = @glibcxx_localedir@ +glibcxx_prefixdir = @glibcxx_prefixdir@ +glibcxx_srcdir = @glibcxx_srcdir@ +glibcxx_thread_h = @glibcxx_thread_h@ +glibcxx_toolexecdir = @glibcxx_toolexecdir@ +glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@ +gxx_include_dir = @gxx_include_dir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libtool_VERSION = @libtool_VERSION@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +oldincludedir = @oldincludedir@ +port_specific_symbol_files = @port_specific_symbol_files@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +toplevel_srcdir = @toplevel_srcdir@ + +# May be used by various substitution variables. +gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) +MAINT_CHARSET = latin1 +mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs +PWD_COMMAND = $${PWDCMD-pwd} +STAMP = echo timestamp > +toolexecdir = $(glibcxx_toolexecdir) +toolexeclibdir = $(glibcxx_toolexeclibdir) + +# These bits are all figured out from configure. Look in acinclude.m4 +# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS. +CONFIG_CXXFLAGS = \ + $(SECTION_FLAGS) $(EXTRA_CXX_FLAGS) + +WARN_CXXFLAGS = \ + $(WARN_FLAGS) $(WERROR) -fdiagnostics-show-location=once + + +# -I/-D flags to pass when compiling. +AM_CPPFLAGS = $(GLIBCXX_INCLUDES) + +# Standard C++ includes. +std_srcdir = ${glibcxx_srcdir}/include/std +std_builddir = . +std_headers = \ + ${std_srcdir}/std_algorithm.h \ + ${std_srcdir}/std_bitset.h \ + ${std_srcdir}/std_complex.h \ + ${std_srcdir}/std_deque.h \ + ${std_srcdir}/std_fstream.h \ + ${std_srcdir}/std_functional.h \ + ${std_srcdir}/std_iomanip.h \ + ${std_srcdir}/std_ios.h \ + ${std_srcdir}/std_iosfwd.h \ + ${std_srcdir}/std_iostream.h \ + ${std_srcdir}/std_istream.h \ + ${std_srcdir}/std_iterator.h \ + ${std_srcdir}/std_limits.h \ + ${std_srcdir}/std_list.h \ + ${std_srcdir}/std_locale.h \ + ${std_srcdir}/std_map.h \ + ${std_srcdir}/std_memory.h \ + ${std_srcdir}/std_numeric.h \ + ${std_srcdir}/std_ostream.h \ + ${std_srcdir}/std_queue.h \ + ${std_srcdir}/std_set.h \ + ${std_srcdir}/std_sstream.h \ + ${std_srcdir}/std_stack.h \ + ${std_srcdir}/std_stdexcept.h \ + ${std_srcdir}/std_streambuf.h \ + ${std_srcdir}/std_string.h \ + ${std_srcdir}/std_utility.h \ + ${std_srcdir}/std_valarray.h \ + ${std_srcdir}/std_vector.h + +# Renamed at build time. +std_headers_rename = \ + algorithm \ + bitset \ + complex \ + deque \ + fstream \ + functional \ + iomanip \ + ios \ + iosfwd \ + iostream \ + istream \ + iterator \ + limits \ + list \ + locale \ + map \ + memory \ + numeric \ + ostream \ + queue \ + set \ + sstream \ + stack \ + stdexcept \ + streambuf \ + string \ + utility \ + valarray \ + vector + +bits_srcdir = ${glibcxx_srcdir}/include/bits +bits_builddir = ./bits +bits_headers = \ + ${bits_srcdir}/allocator.h \ + ${bits_srcdir}/basic_ios.h \ + ${bits_srcdir}/basic_ios.tcc \ + ${bits_srcdir}/basic_string.h \ + ${bits_srcdir}/basic_string.tcc \ + ${bits_srcdir}/boost_concept_check.h \ + ${bits_srcdir}/char_traits.h \ + ${bits_srcdir}/codecvt.h \ + ${bits_srcdir}/concept_check.h \ + ${bits_srcdir}/cpp_type_traits.h \ + ${bits_srcdir}/deque.tcc \ + ${bits_srcdir}/fstream.tcc \ + ${bits_srcdir}/functexcept.h \ + ${bits_srcdir}/gslice.h \ + ${bits_srcdir}/gslice_array.h \ + ${bits_srcdir}/indirect_array.h \ + ${bits_srcdir}/ios_base.h \ + ${bits_srcdir}/istream.tcc \ + ${bits_srcdir}/list.tcc \ + ${bits_srcdir}/locale_classes.h \ + ${bits_srcdir}/locale_facets.h \ + ${bits_srcdir}/locale_facets.tcc \ + ${bits_srcdir}/localefwd.h \ + ${bits_srcdir}/mask_array.h \ + ${bits_srcdir}/ostream.tcc \ + ${bits_srcdir}/ostream_insert.h \ + ${bits_srcdir}/postypes.h \ + ${bits_srcdir}/stream_iterator.h \ + ${bits_srcdir}/streambuf_iterator.h \ + ${bits_srcdir}/slice_array.h \ + ${bits_srcdir}/sstream.tcc \ + ${bits_srcdir}/stl_algo.h \ + ${bits_srcdir}/stl_algobase.h \ + ${bits_srcdir}/stl_bvector.h \ + ${bits_srcdir}/stl_construct.h \ + ${bits_srcdir}/stl_deque.h \ + ${bits_srcdir}/stl_function.h \ + ${bits_srcdir}/stl_heap.h \ + ${bits_srcdir}/stl_iterator.h \ + ${bits_srcdir}/stl_iterator_base_funcs.h \ + ${bits_srcdir}/stl_iterator_base_types.h \ + ${bits_srcdir}/stl_list.h \ + ${bits_srcdir}/stl_map.h \ + ${bits_srcdir}/stl_multimap.h \ + ${bits_srcdir}/stl_multiset.h \ + ${bits_srcdir}/stl_numeric.h \ + ${bits_srcdir}/stl_pair.h \ + ${bits_srcdir}/stl_queue.h \ + ${bits_srcdir}/stl_raw_storage_iter.h \ + ${bits_srcdir}/stl_relops.h \ + ${bits_srcdir}/stl_set.h \ + ${bits_srcdir}/stl_stack.h \ + ${bits_srcdir}/stl_tempbuf.h \ + ${bits_srcdir}/stl_tree.h \ + ${bits_srcdir}/stl_uninitialized.h \ + ${bits_srcdir}/stl_vector.h \ + ${bits_srcdir}/streambuf.tcc \ + ${bits_srcdir}/stringfwd.h \ + ${bits_srcdir}/valarray_array.h \ + ${bits_srcdir}/valarray_array.tcc \ + ${bits_srcdir}/valarray_before.h \ + ${bits_srcdir}/valarray_after.h \ + ${bits_srcdir}/vector.tcc + +backward_srcdir = ${glibcxx_srcdir}/include/backward +backward_builddir = ./backward +backward_headers = \ + ${backward_srcdir}/complex.h \ + ${backward_srcdir}/iomanip.h \ + ${backward_srcdir}/istream.h \ + ${backward_srcdir}/ostream.h \ + ${backward_srcdir}/stream.h \ + ${backward_srcdir}/streambuf.h \ + ${backward_srcdir}/algo.h \ + ${backward_srcdir}/algobase.h \ + ${backward_srcdir}/alloc.h \ + ${backward_srcdir}/bvector.h \ + ${backward_srcdir}/defalloc.h \ + ${backward_srcdir}/deque.h \ + ${backward_srcdir}/function.h \ + ${backward_srcdir}/hash_map.h \ + ${backward_srcdir}/hash_set.h \ + ${backward_srcdir}/hashtable.h \ + ${backward_srcdir}/heap.h \ + ${backward_srcdir}/iostream.h \ + ${backward_srcdir}/iterator.h \ + ${backward_srcdir}/list.h \ + ${backward_srcdir}/map.h \ + ${backward_srcdir}/multimap.h \ + ${backward_srcdir}/new.h \ + ${backward_srcdir}/multiset.h \ + ${backward_srcdir}/pair.h \ + ${backward_srcdir}/queue.h \ + ${backward_srcdir}/rope.h \ + ${backward_srcdir}/set.h \ + ${backward_srcdir}/slist.h \ + ${backward_srcdir}/stack.h \ + ${backward_srcdir}/tempbuf.h \ + ${backward_srcdir}/tree.h \ + ${backward_srcdir}/vector.h \ + ${backward_srcdir}/fstream.h \ + ${backward_srcdir}/strstream \ + ${backward_srcdir}/backward_warning.h + +pb_srcdir = ${glibcxx_srcdir}/include/ext/pb_ds +pb_builddir = ./ext/pb_ds +pb_subdirs = \ + ${pb_builddir}/detail \ + ${pb_builddir}/detail/pairing_heap_ \ + ${pb_builddir}/detail/splay_tree_ \ + ${pb_builddir}/detail/list_update_map_ \ + ${pb_builddir}/detail/basic_tree_policy \ + ${pb_builddir}/detail/trie_policy \ + ${pb_builddir}/detail/gp_hash_table_map_ \ + ${pb_builddir}/detail/tree_policy \ + ${pb_builddir}/detail/binomial_heap_base_ \ + ${pb_builddir}/detail/resize_policy \ + ${pb_builddir}/detail/bin_search_tree_ \ + ${pb_builddir}/detail/binomial_heap_ \ + ${pb_builddir}/detail/thin_heap_ \ + ${pb_builddir}/detail/pat_trie_ \ + ${pb_builddir}/detail/cc_hash_table_map_ \ + ${pb_builddir}/detail/rc_binomial_heap_ \ + ${pb_builddir}/detail/left_child_next_sibling_heap_ \ + ${pb_builddir}/detail/unordered_iterator \ + ${pb_builddir}/detail/binary_heap_ \ + ${pb_builddir}/detail/ov_tree_map_ \ + ${pb_builddir}/detail/hash_fn \ + ${pb_builddir}/detail/eq_fn \ + ${pb_builddir}/detail/rb_tree_map_ \ + ${pb_builddir}/detail/list_update_policy + + +# The ability for make and the underlying host to deal with this +# unweildy list as one entire entity is not a sure thing, and may +# cause build errors. Thus, split one list into many smaller +# mini-lists, with the maximum size per mini-list of no more than 42. +pb_headers1 = \ + ${pb_srcdir}/assoc_container.hpp \ + ${pb_srcdir}/exception.hpp \ + ${pb_srcdir}/hash_policy.hpp \ + ${pb_srcdir}/list_update_policy.hpp \ + ${pb_srcdir}/priority_queue.hpp \ + ${pb_srcdir}/tag_and_trait.hpp \ + ${pb_srcdir}/tree_policy.hpp \ + ${pb_srcdir}/trie_policy.hpp \ + ${pb_srcdir}/detail/basic_tree_policy/basic_tree_policy_base.hpp \ + ${pb_srcdir}/detail/basic_tree_policy/null_node_metadata.hpp \ + ${pb_srcdir}/detail/basic_tree_policy/traits.hpp \ + ${pb_srcdir}/detail/basic_types.hpp \ + ${pb_srcdir}/detail/binary_heap_/binary_heap_.hpp \ + ${pb_srcdir}/detail/binary_heap_/const_iterator.hpp \ + ${pb_srcdir}/detail/binary_heap_/const_point_iterator.hpp \ + ${pb_srcdir}/detail/binary_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/entry_cmp.hpp \ + ${pb_srcdir}/detail/binary_heap_/entry_pred.hpp \ + ${pb_srcdir}/detail/binary_heap_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/resize_policy.hpp \ + ${pb_srcdir}/detail/binary_heap_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/binary_heap_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/binomial_heap_base_.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_base_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_/binomial_heap_.hpp \ + ${pb_srcdir}/detail/binomial_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/binomial_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/bin_search_tree_.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/cond_dtor_entry_dealtor.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/cond_key_dtor_entry_dealtor.hpp + +pb_headers2 = \ + ${pb_srcdir}/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/node_iterators.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/point_iterators.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/r_erase_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/rotate_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/bin_search_tree_/traits.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/cc_ht_map_.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/cmp_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/entry_list_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/resize_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/size_fn_imps.hpp \ + ${pb_srcdir}/detail/cc_hash_table_map_/standard_policies.hpp + +pb_headers3 = \ + ${pb_srcdir}/detail/cc_hash_table_map_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/cond_dealtor.hpp \ + ${pb_srcdir}/detail/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/container_base_dispatch.hpp \ + ${pb_srcdir}/detail/eq_fn/eq_by_less.hpp \ + ${pb_srcdir}/detail/eq_fn/hash_eq_fn.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/gp_ht_map_.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/iterator_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/resize_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/standard_policies.hpp \ + ${pb_srcdir}/detail/gp_hash_table_map_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/hash_fn/direct_mask_range_hashing_imp.hpp \ + ${pb_srcdir}/detail/hash_fn/direct_mod_range_hashing_imp.hpp \ + ${pb_srcdir}/detail/hash_fn/linear_probe_fn_imp.hpp \ + ${pb_srcdir}/detail/hash_fn/mask_based_range_hashing.hpp \ + ${pb_srcdir}/detail/hash_fn/mod_based_range_hashing.hpp \ + ${pb_srcdir}/detail/hash_fn/probe_fn_base.hpp \ + ${pb_srcdir}/detail/hash_fn/quadratic_probe_fn_imp.hpp \ + ${pb_srcdir}/detail/hash_fn/ranged_hash_fn.hpp \ + ${pb_srcdir}/detail/hash_fn/ranged_probe_fn.hpp + +pb_headers4 = \ + ${pb_srcdir}/detail/hash_fn/sample_probe_fn.hpp \ + ${pb_srcdir}/detail/hash_fn/sample_ranged_hash_fn.hpp \ + ${pb_srcdir}/detail/hash_fn/sample_ranged_probe_fn.hpp \ + ${pb_srcdir}/detail/hash_fn/sample_range_hashing.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/const_iterator.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/const_point_iterator.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/node.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/null_metadata.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/constructor_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/entry_metadata_base.hpp \ + ${pb_srcdir}/detail/list_update_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_map_/lu_map_.hpp \ + ${pb_srcdir}/detail/list_update_map_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/list_update_policy/counter_lu_metadata.hpp \ + ${pb_srcdir}/detail/list_update_policy/counter_lu_policy_imp.hpp \ + ${pb_srcdir}/detail/list_update_policy/mtf_lu_policy_imp.hpp \ + ${pb_srcdir}/detail/list_update_policy/sample_update_policy.hpp \ + ${pb_srcdir}/detail/map_debug_base.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/cond_dtor.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/node_iterators.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/ov_tree_map_.hpp + +pb_headers5 = \ + ${pb_srcdir}/detail/ov_tree_map_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/ov_tree_map_/traits.hpp \ + ${pb_srcdir}/detail/pairing_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/pairing_heap_/pairing_heap_.hpp \ + ${pb_srcdir}/detail/pairing_heap_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/child_iterator.hpp \ + ${pb_srcdir}/detail/pat_trie_/cond_dtor_entry_dealtor.hpp \ + ${pb_srcdir}/detail/pat_trie_/const_child_iterator.hpp \ + ${pb_srcdir}/detail/pat_trie_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/head.hpp \ + ${pb_srcdir}/detail/pat_trie_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/insert_join_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/internal_node.hpp \ + ${pb_srcdir}/detail/pat_trie_/iterators_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/leaf.hpp \ + ${pb_srcdir}/detail/pat_trie_/node_base.hpp \ + ${pb_srcdir}/detail/pat_trie_/node_iterators.hpp \ + ${pb_srcdir}/detail/pat_trie_/node_metadata_base.hpp \ + ${pb_srcdir}/detail/pat_trie_/pat_trie_.hpp \ + ${pb_srcdir}/detail/pat_trie_/point_iterators.hpp \ + ${pb_srcdir}/detail/pat_trie_/policy_access_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/r_erase_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/rotate_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/split_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/split_join_branch_bag.hpp \ + ${pb_srcdir}/detail/pat_trie_/synth_e_access_traits.hpp \ + ${pb_srcdir}/detail/pat_trie_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/pat_trie_/traits.hpp \ + ${pb_srcdir}/detail/pat_trie_/update_fn_imps.hpp \ + ${pb_srcdir}/detail/priority_queue_base_dispatch.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/debug_fn_imps.hpp + +pb_headers6 = \ + ${pb_srcdir}/detail/rb_tree_map_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/node.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/rb_tree_.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/rb_tree_map_/traits.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/rc_binomial_heap_.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/rc.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/rc_binomial_heap_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_exponential_size_policy_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_prime_size_policy_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/hash_standard_resize_policy_imp.hpp \ + ${pb_srcdir}/detail/resize_policy/sample_resize_policy.hpp \ + ${pb_srcdir}/detail/resize_policy/sample_resize_trigger.hpp \ + ${pb_srcdir}/detail/resize_policy/sample_size_policy.hpp \ + ${pb_srcdir}/detail/splay_tree_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/erase_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/info_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/node.hpp \ + ${pb_srcdir}/detail/splay_tree_/splay_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/splay_tree_.hpp \ + ${pb_srcdir}/detail/splay_tree_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/splay_tree_/traits.hpp \ + ${pb_srcdir}/detail/standard_policies.hpp \ + ${pb_srcdir}/detail/thin_heap_/constructors_destructor_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/debug_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/erase_fn_imps.hpp + +pb_headers7 = \ + ${pb_srcdir}/detail/thin_heap_/find_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/insert_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/split_join_fn_imps.hpp \ + ${pb_srcdir}/detail/thin_heap_/thin_heap_.hpp \ + ${pb_srcdir}/detail/thin_heap_/trace_fn_imps.hpp \ + ${pb_srcdir}/detail/tree_policy/node_metadata_selector.hpp \ + ${pb_srcdir}/detail/tree_policy/null_node_update_imp.hpp \ + ${pb_srcdir}/detail/tree_policy/order_statistics_imp.hpp \ + ${pb_srcdir}/detail/tree_policy/sample_tree_node_update.hpp \ + ${pb_srcdir}/detail/tree_trace_base.hpp \ + ${pb_srcdir}/detail/trie_policy/node_metadata_selector.hpp \ + ${pb_srcdir}/detail/trie_policy/null_node_update_imp.hpp \ + ${pb_srcdir}/detail/trie_policy/order_statistics_imp.hpp \ + ${pb_srcdir}/detail/trie_policy/prefix_search_node_update_imp.hpp \ + ${pb_srcdir}/detail/trie_policy/sample_trie_e_access_traits.hpp \ + ${pb_srcdir}/detail/trie_policy/sample_trie_node_update.hpp \ + ${pb_srcdir}/detail/trie_policy/string_trie_e_access_traits_imp.hpp \ + ${pb_srcdir}/detail/trie_policy/trie_policy_base.hpp \ + ${pb_srcdir}/detail/types_traits.hpp \ + ${pb_srcdir}/detail/type_utils.hpp \ + ${pb_srcdir}/detail/unordered_iterator/const_iterator.hpp \ + ${pb_srcdir}/detail/unordered_iterator/const_point_iterator.hpp \ + ${pb_srcdir}/detail/unordered_iterator/iterator.hpp \ + ${pb_srcdir}/detail/unordered_iterator/point_iterator.hpp + +ext_srcdir = ${glibcxx_srcdir}/include/ext +ext_builddir = ./ext +ext_headers = \ + ${ext_srcdir}/algorithm \ + ${ext_srcdir}/atomicity.h \ + ${ext_srcdir}/array_allocator.h \ + ${ext_srcdir}/bitmap_allocator.h \ + ${ext_srcdir}/codecvt_specializations.h \ + ${ext_srcdir}/concurrence.h \ + ${ext_srcdir}/debug_allocator.h \ + ${ext_srcdir}/stdio_filebuf.h \ + ${ext_srcdir}/stdio_sync_filebuf.h \ + ${ext_srcdir}/functional \ + ${ext_srcdir}/hash_map \ + ${ext_srcdir}/hash_set \ + ${ext_srcdir}/hash_fun.h \ + ${ext_srcdir}/hashtable.h \ + ${ext_srcdir}/iterator \ + ${ext_srcdir}/malloc_allocator.h \ + ${ext_srcdir}/memory \ + ${ext_srcdir}/mt_allocator.h \ + ${ext_srcdir}/new_allocator.h \ + ${ext_srcdir}/numeric \ + ${ext_srcdir}/numeric_traits.h \ + ${ext_srcdir}/pod_char_traits.h \ + ${ext_srcdir}/pool_allocator.h \ + ${ext_srcdir}/rb_tree \ + ${ext_srcdir}/rope \ + ${ext_srcdir}/ropeimpl.h \ + ${ext_srcdir}/slist \ + ${ext_srcdir}/throw_allocator.h \ + ${ext_srcdir}/typelist.h \ + ${ext_srcdir}/type_traits.h \ + ${ext_srcdir}/rc_string_base.h \ + ${ext_srcdir}/sso_string_base.h \ + ${ext_srcdir}/vstring.h \ + ${ext_srcdir}/vstring.tcc \ + ${ext_srcdir}/vstring_fwd.h \ + ${ext_srcdir}/vstring_util.h + +tr1_srcdir = ${glibcxx_srcdir}/include/tr1 +tr1_builddir = ./tr1 +tr1_headers = \ + ${tr1_srcdir}/array \ + ${tr1_srcdir}/bind_repeat.h \ + ${tr1_srcdir}/bind_iterate.h \ + ${tr1_srcdir}/boost_shared_ptr.h \ + ${tr1_srcdir}/cctype \ + ${tr1_srcdir}/cfenv \ + ${tr1_srcdir}/cfloat \ + ${tr1_srcdir}/cinttypes \ + ${tr1_srcdir}/climits \ + ${tr1_srcdir}/cmath \ + ${tr1_srcdir}/common.h \ + ${tr1_srcdir}/complex \ + ${tr1_srcdir}/cstdarg \ + ${tr1_srcdir}/cstdbool \ + ${tr1_srcdir}/cstdint \ + ${tr1_srcdir}/cstdio \ + ${tr1_srcdir}/cstdlib \ + ${tr1_srcdir}/ctgmath \ + ${tr1_srcdir}/ctime \ + ${tr1_srcdir}/ctype.h \ + ${tr1_srcdir}/cwchar \ + ${tr1_srcdir}/cwctype \ + ${tr1_srcdir}/fenv.h \ + ${tr1_srcdir}/float.h \ + ${tr1_srcdir}/functional \ + ${tr1_srcdir}/functional_hash.h \ + ${tr1_srcdir}/functional_iterate.h \ + ${tr1_srcdir}/hashtable \ + ${tr1_srcdir}/hashtable_policy.h \ + ${tr1_srcdir}/inttypes.h \ + ${tr1_srcdir}/limits.h \ + ${tr1_srcdir}/math.h \ + ${tr1_srcdir}/memory \ + ${tr1_srcdir}/mu_iterate.h \ + ${tr1_srcdir}/random \ + ${tr1_srcdir}/random.tcc \ + ${tr1_srcdir}/ref_fwd.h \ + ${tr1_srcdir}/ref_wrap_iterate.h \ + ${tr1_srcdir}/repeat.h \ + ${tr1_srcdir}/stdarg.h \ + ${tr1_srcdir}/stdbool.h \ + ${tr1_srcdir}/stdint.h \ + ${tr1_srcdir}/stdio.h \ + ${tr1_srcdir}/stdlib.h \ + ${tr1_srcdir}/tgmath.h \ + ${tr1_srcdir}/tuple \ + ${tr1_srcdir}/tuple_defs.h \ + ${tr1_srcdir}/tuple_iterate.h \ + ${tr1_srcdir}/type_traits \ + ${tr1_srcdir}/type_traits_fwd.h \ + ${tr1_srcdir}/unordered_set \ + ${tr1_srcdir}/unordered_map \ + ${tr1_srcdir}/utility \ + ${tr1_srcdir}/wchar.h \ + ${tr1_srcdir}/wctype.h + + +# This is the common subset of files that all three "C" header models use. +c_base_srcdir = $(C_INCLUDE_DIR) +c_base_builddir = . +c_base_headers = \ + ${c_base_srcdir}/std_cassert.h \ + ${c_base_srcdir}/std_cctype.h \ + ${c_base_srcdir}/std_cerrno.h \ + ${c_base_srcdir}/std_cfloat.h \ + ${c_base_srcdir}/std_ciso646.h \ + ${c_base_srcdir}/std_climits.h \ + ${c_base_srcdir}/std_clocale.h \ + ${c_base_srcdir}/std_cmath.h \ + ${c_base_srcdir}/std_csetjmp.h \ + ${c_base_srcdir}/std_csignal.h \ + ${c_base_srcdir}/std_cstdarg.h \ + ${c_base_srcdir}/std_cstddef.h \ + ${c_base_srcdir}/std_cstdio.h \ + ${c_base_srcdir}/std_cstdlib.h \ + ${c_base_srcdir}/std_cstring.h \ + ${c_base_srcdir}/std_ctime.h \ + ${c_base_srcdir}/std_cwchar.h \ + ${c_base_srcdir}/std_cwctype.h + +c_base_headers_rename = \ + cassert \ + cctype \ + cerrno \ + cfloat \ + ciso646 \ + climits \ + clocale \ + cmath \ + csetjmp \ + csignal \ + cstdarg \ + cstddef \ + cstdio \ + cstdlib \ + cstring \ + ctime \ + cwchar \ + cwctype + + +# "C" compatibility headers. +c_compatibility_srcdir = ${glibcxx_srcdir}/include/c_compatibility +c_compatibility_builddir = . +c_compatibility_headers = \ + ${c_compatibility_srcdir}/assert.h \ + ${c_compatibility_srcdir}/ctype.h \ + ${c_compatibility_srcdir}/errno.h \ + ${c_compatibility_srcdir}/float.h \ + ${c_compatibility_srcdir}/iso646.h \ + ${c_compatibility_srcdir}/limits.h \ + ${c_compatibility_srcdir}/locale.h \ + ${c_compatibility_srcdir}/math.h \ + ${c_compatibility_srcdir}/setjmp.h \ + ${c_compatibility_srcdir}/signal.h \ + ${c_compatibility_srcdir}/stdarg.h \ + ${c_compatibility_srcdir}/stddef.h \ + ${c_compatibility_srcdir}/stdio.h \ + ${c_compatibility_srcdir}/stdlib.h \ + ${c_compatibility_srcdir}/string.h \ + ${c_compatibility_srcdir}/time.h \ + ${c_compatibility_srcdir}/wchar.h \ + ${c_compatibility_srcdir}/wctype.h + + +# Debug mode headers +debug_srcdir = ${glibcxx_srcdir}/include/debug +debug_builddir = ./debug +debug_headers = \ + ${debug_srcdir}/bitset \ + ${debug_srcdir}/debug.h \ + ${debug_srcdir}/deque \ + ${debug_srcdir}/formatter.h \ + ${debug_srcdir}/functions.h \ + ${debug_srcdir}/hash_map \ + ${debug_srcdir}/hash_map.h \ + ${debug_srcdir}/hash_multimap.h \ + ${debug_srcdir}/hash_multiset.h \ + ${debug_srcdir}/hash_set \ + ${debug_srcdir}/hash_set.h \ + ${debug_srcdir}/list \ + ${debug_srcdir}/map \ + ${debug_srcdir}/macros.h \ + ${debug_srcdir}/map.h \ + ${debug_srcdir}/multimap.h \ + ${debug_srcdir}/multiset.h \ + ${debug_srcdir}/safe_base.h \ + ${debug_srcdir}/safe_iterator.h \ + ${debug_srcdir}/safe_iterator.tcc \ + ${debug_srcdir}/safe_sequence.h \ + ${debug_srcdir}/set \ + ${debug_srcdir}/set.h \ + ${debug_srcdir}/string \ + ${debug_srcdir}/vector + +@GLIBCXX_C_HEADERS_C_STD_FALSE@c_base_headers_extra = + +# Some of the different "C" header models need extra files. +# Some "C" header schemes require the "C" compatibility headers. +# For --enable-cheaders=c_std +@GLIBCXX_C_HEADERS_C_STD_TRUE@c_base_headers_extra = ${c_base_srcdir}/cmath.tcc +@GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@c_compatibility_headers_extra = +@GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@c_compatibility_headers_extra = ${c_compatibility_headers} +host_srcdir = ${glibcxx_srcdir}/$(OS_INC_SRCDIR) +host_builddir = ./${host_alias}/bits +host_installdir = ${gxx_include_dir}/${host_alias}$(MULTISUBDIR)/bits +host_headers = \ + ${host_srcdir}/ctype_base.h \ + ${host_srcdir}/ctype_inline.h \ + ${host_srcdir}/ctype_noninline.h \ + ${host_srcdir}/os_defines.h \ + ${glibcxx_srcdir}/$(ATOMIC_WORD_SRCDIR)/atomic_word.h \ + ${glibcxx_srcdir}/$(ABI_TWEAKS_SRCDIR)/cxxabi_tweaks.h \ + ${glibcxx_srcdir}/$(CPU_DEFINES_SRCDIR)/cpu_defines.h + + +# Non-installed host_header files. +COMPATIBILITY_H = config/abi/compatibility.h +host_headers_noinst = \ + ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) \ + ${glibcxx_srcdir}/$(COMPATIBILITY_H) + + +# These host_headers_extra files are all built with ad hoc naming rules. +host_headers_extra = \ + ${host_builddir}/basic_file.h \ + ${host_builddir}/c++config.h \ + ${host_builddir}/c++allocator.h \ + ${host_builddir}/c++io.h \ + ${host_builddir}/c++locale.h \ + ${host_builddir}/messages_members.h \ + ${host_builddir}/time_members.h + +thread_host_headers = \ + ${host_builddir}/gthr.h \ + ${host_builddir}/gthr-single.h \ + ${host_builddir}/gthr-posix.h \ + ${host_builddir}/gthr-tpf.h \ + ${host_builddir}/gthr-default.h + +pch1_source = ${glibcxx_srcdir}/include/precompiled/stdc++.h +pch1_output_builddir = ${host_builddir}/stdc++.h.gch +pch1_output_anchor = ${host_builddir}/stdc++.h +pch1_output_installdir = ${host_installdir}/stdc++.h.gch +pch1a_output = ${pch1_output_builddir}/O0g.gch +pch1b_output = ${pch1_output_builddir}/O2g.gch +pch1_output = ${pch1a_output} ${pch1b_output} +pch2_source = ${glibcxx_srcdir}/include/precompiled/stdtr1c++.h +pch2_output_builddir = ${host_builddir}/stdtr1c++.h.gch +pch2_output_anchor = ${host_builddir}/stdtr1c++.h +pch2_output_installdir = ${host_installdir}/stdtr1c++.h.gch +pch2_output = ${pch2_output_builddir}/O2g.gch +pch3_source = ${glibcxx_srcdir}/include/precompiled/extc++.h +pch3_output_builddir = ${host_builddir}/extc++.h.gch +pch3_output_anchor = ${host_builddir}/extc++.h +pch3_output_installdir = ${host_installdir}/extc++.h.gch +pch3_output = ${pch3_output_builddir}/O2g.gch +pch_output = ${pch1_output} ${pch2_output} ${pch3_output} +pch_output_dirs = \ + ${pch1_output_builddir} ${pch2_output_builddir} ${pch3_output_builddir} + +pch_output_anchors = \ + ${pch1_output_anchor} ${pch2_output_anchor} ${pch3_output_anchor} + +PCHFLAGS = -Winvalid-pch -Wno-deprecated -x c++-header $(CXXFLAGS) +@GLIBCXX_BUILD_PCH_FALSE@pch_build = +@GLIBCXX_BUILD_PCH_TRUE@pch_build = ${pch_output} +@GLIBCXX_BUILD_PCH_FALSE@pch_install = +@GLIBCXX_BUILD_PCH_TRUE@pch_install = install-pch + +# List of all timestamp files. By keeping only one copy of this list, both +# CLEANFILES and all-local are kept up-to-date. +allstamped = \ + stamp-std stamp-bits stamp-c_base stamp-c_compatibility \ + stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-debug stamp-host + + +# List of all files that are created by explicit building, editing, or +# catenation. +allcreated = \ + ${host_builddir}/c++config.h \ + ${thread_host_headers} \ + ${pch_build} + + +# Host includes for threads +uppercase = [ABCDEFGHIJKLMNOPQRSTUVWXYZ_] + +# By adding these files here, automake will remove them for 'make clean' +CLEANFILES = ${pch_output} ${pch_output_anchors} +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/fragment.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps include/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign --ignore-deps include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + $(mkdir_p) $(distdir)/.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile all-local +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-local mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-data-local + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am all-local check check-am clean clean-generic \ + clean-libtool clean-local distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-local install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + + +# Here are the rules for building the headers +all-local: ${allstamped} ${allcreated} + +# This rule is slightly different, in that we must change the name of the +# local file from std_foo.h to foo. +stamp-std: ${std_headers} + @if [ ! -d "${std_builddir}" ]; then \ + mkdir -p ${std_builddir} ;\ + fi ;\ + if [ ! -f stamp-std ]; then \ + (cd ${std_builddir} && for h in $?; do \ + build_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ + $(LN_S) $$h ./$${build_name} || true ;\ + done) ;\ + fi ;\ + $(STAMP) stamp-std + +stamp-bits: ${bits_headers} + @if [ ! -d "${bits_builddir}" ]; then \ + mkdir -p ${bits_builddir} ;\ + fi ;\ + if [ ! -f stamp-bits ]; then \ + (cd ${bits_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-bits + +stamp-c_base: stamp-bits ${c_base_headers} ${c_base_headers_extra} + @if [ ! -d "${c_base_builddir}" ]; then \ + mkdir -p ${c_base_builddir} ;\ + fi ;\ + if [ ! -f stamp-c_base ]; then \ + (cd ${c_base_builddir} && for h in ${c_base_headers}; do \ + build_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ + $(LN_S) $$h ./$${build_name} || true ;\ + done) ;\ + if [ ! -z "${c_base_headers_extra}" ]; then \ + (cd ${bits_builddir} && $(LN_S) ${c_base_headers_extra} . || true) ;\ + fi ;\ + fi ;\ + $(STAMP) stamp-c_base + +stamp-c_compatibility: ${c_compatibility_headers_extra} + @if [ ! -d "${c_compatibility_builddir}" ]; then \ + mkdir -p ${c_compatibility_builddir} ;\ + fi ;\ + if [ ! -f stamp-c_compatibility ]; then \ + if [ ! -z "${c_compatibility_headers_extra}" ]; then \ + (cd ${c_compatibility_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + fi ;\ + $(STAMP) stamp-c_compatibility + +stamp-backward: ${backward_headers} + @if [ ! -d "${backward_builddir}" ]; then \ + mkdir -p ${backward_builddir} ;\ + fi ;\ + if [ ! -f stamp-backward ]; then \ + (cd ${backward_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-backward + +stamp-ext: ${ext_headers} + @if [ ! -d "${ext_builddir}" ]; then \ + mkdir -p ${ext_builddir} ;\ + fi ;\ + if [ ! -f stamp-ext ]; then \ + (cd ${ext_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-ext + +# Have to deal with nested include directories, gah! Strip off source +# directory before making the link. +# XXX check ${pb_headers} +stamp-pb: + @if [ ! -d "${pb_builddir}" ]; then \ + mkdir -p ${pb_subdirs} ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers1}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers2}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers3}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers4}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers5}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers6}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + @if [ ! -f stamp-pb ]; then \ + cd ${pb_builddir} && for h in ${pb_headers7}; do \ + build_name=`echo $$h | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(LN_S) $$h $${build_name} || true ;\ + done ;\ + fi + $(STAMP) stamp-pb + +stamp-tr1: ${tr1_headers} + @if [ ! -d "${tr1_builddir}" ]; then \ + mkdir -p ${tr1_builddir} ;\ + fi ;\ + if [ ! -f stamp-tr1 ]; then \ + (cd ${tr1_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-tr1 + +stamp-debug: ${debug_headers} + @if [ ! -d "${debug_builddir}" ]; then \ + mkdir -p ${debug_builddir} ;\ + fi ;\ + if [ ! -f stamp-debug ]; then \ + (cd ${debug_builddir} && @LN_S@ $? . || true) ;\ + fi ;\ + $(STAMP) stamp-debug + +stamp-${host_alias}: + @if [ ! -d ${host_builddir} ]; then \ + mkdir -p ${host_builddir} ;\ + fi ;\ + $(STAMP) stamp-${host_alias} + +# Host includes static. +# XXX Missing dependency info for {host_headers_extra} +stamp-host: ${host_headers} ${host_headers_noinst} stamp-${host_alias} + @if [ ! -f stamp-host ]; then \ + (cd ${host_builddir} ;\ + $(LN_S) ${host_headers} . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_H) basic_file.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(ALLOCATOR_H) c++allocator.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CSTDIO_H) c++io.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_H) c++locale.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(COMPATIBILITY_H) . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CMESSAGES_H) messages_members.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CTIME_H) time_members.h || true);\ + fi ;\ + $(STAMP) stamp-host + +# Host includes dynamic. +@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@stamp-namespace-version: +@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ echo 1 > stamp-namespace-version +@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@stamp-namespace-version: +@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@ echo 0 > stamp-namespace-version + +@ENABLE_VISIBILITY_TRUE@stamp-visibility: +@ENABLE_VISIBILITY_TRUE@ echo 1 > stamp-visibility +@ENABLE_VISIBILITY_FALSE@stamp-visibility: +@ENABLE_VISIBILITY_FALSE@ echo 0 > stamp-visibility + +# NB: The non-empty default ldbl_compat works around an AIX sed +# oddity, see libstdc++/31957 for details. +${host_builddir}/c++config.h: ${CONFIG_HEADER} \ + ${glibcxx_srcdir}/include/bits/c++config \ + stamp-${host_alias} \ + ${toplevel_srcdir}/gcc/DATESTAMP \ + stamp-namespace-version \ + stamp-visibility + @date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\ + nsa_version=`cat stamp-namespace-version` ;\ + visibility=`cat stamp-visibility` ;\ + ldbl_compat='s,g,g,' ;\ + grep "^[ ]*#[ ]*define[ ][ ]*_GLIBCXX_LONG_DOUBLE_COMPAT[ ][ ]*1[ ]*$$" \ + ${CONFIG_HEADER} > /dev/null 2>&1 \ + && ldbl_compat='s,^#undef _GLIBCXX_LONG_DOUBLE_COMPAT$$,#define _GLIBCXX_LONG_DOUBLE_COMPAT 1,' ;\ + sed -e "s,define __GLIBCXX__,define __GLIBCXX__ $$date," \ + -e "s,define _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION, define _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION $$nsa_version," \ + -e "s,define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY, define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY $$visibility," \ + -e "$$ldbl_compat" \ + < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\ + sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \ + -e 's/PACKAGE/_GLIBCXX_PACKAGE/g' \ + -e 's/VERSION/_GLIBCXX_VERSION/g' \ + -e 's/WORDS_/_GLIBCXX_WORDS_/g' \ + -e '/[ ]_GLIBCXX_LONG_DOUBLE_COMPAT[ ]/d' \ + < ${CONFIG_HEADER} >> $@ ;\ + echo "" >> $@ ;\ + echo "#endif // _CXXCONFIG_" >> $@ + +${host_builddir}/gthr.h: ${toplevel_srcdir}/gcc/gthr.h stamp-${host_alias} + sed -e '/^#pragma/b' \ + -e '/^#/s/\(${uppercase}${uppercase}*\)/_GLIBCXX_\1/g' \ + -e 's/_GLIBCXX_SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's,^#include "\(.*\)",#include <bits/\1>,g' \ + < ${toplevel_srcdir}/gcc/gthr.h > $@ + +${host_builddir}/gthr-single.h: ${toplevel_srcdir}/gcc/gthr-single.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + < ${toplevel_srcdir}/gcc/gthr-single.h > $@ + +${host_builddir}/gthr-posix.h: ${toplevel_srcdir}/gcc/gthr-posix.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ + < ${toplevel_srcdir}/gcc/gthr-posix.h > $@ + +${host_builddir}/gthr-tpf.h: ${toplevel_srcdir}/gcc/gthr-tpf.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ + < ${toplevel_srcdir}/gcc/gthr-tpf.h > $@ + +${host_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcxx_thread_h} \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ + -e 's,^#include "\(.*\)",#include <bits/\1>,g' \ + < ${toplevel_srcdir}/gcc/${glibcxx_thread_h} > $@ + +# Build two precompiled C++ includes, stdc++.h.gch/*.gch +${pch1a_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source} + if [ ! -d "${pch1_output_builddir}" ]; then \ + mkdir -p ${pch1_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O0 -g ${pch1_source} -o $@ + touch ${pch1_output_anchor} + +${pch1b_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source} + if [ ! -d "${pch1_output_builddir}" ]; then \ + mkdir -p ${pch1_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g ${pch1_source} -o $@ + touch ${pch1_output_anchor} + +# Build a precompiled TR1 include, stdtr1c++.h.gch/O2.gch +${pch2_output}: ${pch2_source} ${pch1_output} + if [ ! -d "${pch2_output_builddir}" ]; then \ + mkdir -p ${pch2_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g ${pch2_source} -o $@ + touch ${pch2_output_anchor} + +# Build a precompiled extension include, extc++.h.gch/O2.gch +${pch3_output}: ${pch3_source} ${pch2_output} + if [ ! -d "${pch3_output_builddir}" ]; then \ + mkdir -p ${pch3_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g ${pch3_source} -o $@ + touch ${pch3_output_anchor} + +# For robustness sake (in light of junk files or in-source +# configuration), copy from the build or source tree to the install +# tree using only the human-maintained file lists and directory +# components. Yes, with minor differences, this is sheer duplication +# of the staging rules above using $(INSTALL_DATA) instead of LN_S and +# `$(mkinstalldirs)' instead of `mkdir -p'. In particular, +# host_headers_extra are taken out of the build tree staging area; +# the rest are taken from the original source tree. + +@GLIBCXX_HOSTED_TRUE@install-data-local: install-headers ${pch_install} +@GLIBCXX_HOSTED_FALSE@install-data-local: install-freestanding-headers + +# This is a subset of the full install-headers rule. We only need <cstddef>, +# <limits>, <cstdlib>, <cstdarg>, <new>, <typeinfo>, <exception>, and any +# files which they include (and which we provide). The last three headers +# are installed by libsupc++, so only the first four and the sub-includes +# are copied here. +install-freestanding-headers: + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} + $(mkinstalldirs) $(DESTDIR)${host_installdir} + for file in ${host_srcdir}/os_defines.h ${host_builddir}/c++config.h; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} + $(INSTALL_DATA) ${std_builddir}/limits $(DESTDIR)${gxx_include_dir}/${std_builddir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} + for file in cstddef cstdlib cstdarg; do \ + $(INSTALL_DATA) ${c_base_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done + +# The real deal. +install-headers: + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${bits_builddir} + for file in ${bits_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${bits_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${backward_builddir} + for file in ${backward_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${backward_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${ext_builddir} + for file in ${ext_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${ext_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${pb_builddir} + for dir in ${pb_subdirs}; do \ + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/$${dir} ; done + for file in ${pb_headers1}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers2}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers3}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers4}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers5}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers6}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + for file in ${pb_headers7}; do \ + install_base=$(DESTDIR)${gxx_include_dir}/${pb_builddir} ; \ + relative_name=`echo $$file | sed -e "s|${pb_srcdir}|.|g"` ;\ + $(INSTALL_DATA) $${file} $${install_base}/$${relative_name} ; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${tr1_builddir} + for file in ${tr1_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${tr1_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} + for file in ${c_base_headers_rename}; do \ + $(INSTALL_DATA) ${c_base_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done + c_base_headers_extra_install='$(c_base_headers_extra)';\ + for file in $$c_base_headers_extra_install; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}/${bits_builddir}; done + c_compatibility_headers_install='$(c_compatibility_headers_extra)';\ + for file in $$c_compatibility_headers_install; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} + for file in ${std_headers_rename}; do \ + $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${debug_builddir} + for file in ${debug_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${debug_builddir}; done + $(mkinstalldirs) $(DESTDIR)${host_installdir} + for file in ${host_headers} ${host_headers_extra} \ + ${thread_host_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}; done + +install-pch: + $(mkinstalldirs) $(DESTDIR)${pch1_output_installdir} + for file in ${pch1_output_builddir}/*; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${pch1_output_installdir}; done + $(mkinstalldirs) $(DESTDIR)${pch2_output_installdir} + for file in ${pch2_output_builddir}/*; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${pch2_output_installdir}; done + $(INSTALL_DATA) ${pch1_output_anchor} $(DESTDIR)${host_installdir} + $(INSTALL_DATA) ${pch2_output_anchor} $(DESTDIR)${host_installdir} + +# To remove directories. +clean-local: + rm -rf ${pch_output_dirs} + +# Stop implicit '.o' make rules from ever stomping on extensionless +# headers, in the improbable case where some foolish, crack-addled +# developer tries to create them via make in the include build +# directory. (This is more of an example of how this kind of rule can +# be made.) +.PRECIOUS: $(std_headers_rename) $(c_base_headers_rename) +$(std_headers_rename): ; @: +$(c_base_headers_rename): ; @: +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libstdc++/include/backward/algo.h b/libstdc++/include/backward/algo.h new file mode 100644 index 0000000..2474601 --- /dev/null +++ b/libstdc++/include/backward/algo.h @@ -0,0 +1,145 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ALGO_H +#define _BACKWARD_ALGO_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "tempbuf.h" +#include "iterator.h" +#include <bits/stl_algo.h> +#include <bits/stl_numeric.h> +#include <ext/algorithm> +#include <ext/numeric> + +// Names from <stl_algo.h> +using std::for_each; +using std::find; +using std::find_if; +using std::adjacent_find; +using std::count; +using std::count_if; +using std::search; +using std::search_n; +using std::swap_ranges; +using std::transform; +using std::replace; +using std::replace_if; +using std::replace_copy; +using std::replace_copy_if; +using std::generate; +using std::generate_n; +using std::remove; +using std::remove_if; +using std::remove_copy; +using std::remove_copy_if; +using std::unique; +using std::unique_copy; +using std::reverse; +using std::reverse_copy; +using std::rotate; +using std::rotate_copy; +using std::random_shuffle; +using std::partition; +using std::stable_partition; +using std::sort; +using std::stable_sort; +using std::partial_sort; +using std::partial_sort_copy; +using std::nth_element; +using std::lower_bound; +using std::upper_bound; +using std::equal_range; +using std::binary_search; +using std::merge; +using std::inplace_merge; +using std::includes; +using std::set_union; +using std::set_intersection; +using std::set_difference; +using std::set_symmetric_difference; +using std::min_element; +using std::max_element; +using std::next_permutation; +using std::prev_permutation; +using std::find_first_of; +using std::find_end; + +// Names from stl_heap.h +using std::push_heap; +using std::pop_heap; +using std::make_heap; +using std::sort_heap; + +// Names from stl_numeric.h +using std::accumulate; +using std::inner_product; +using std::partial_sum; +using std::adjacent_difference; + +// Names from ext/algorithm +using __gnu_cxx::random_sample; +using __gnu_cxx::random_sample_n; +using __gnu_cxx::is_sorted; +using __gnu_cxx::is_heap; +using __gnu_cxx::count; // Extension returning void +using __gnu_cxx::count_if; // Extension returning void + +// Names from ext/numeric +using __gnu_cxx::power; +using __gnu_cxx::iota; + +#endif /* _BACKWARD_ALGO_H */ diff --git a/libstdc++/include/backward/algobase.h b/libstdc++/include/backward/algobase.h new file mode 100644 index 0000000..289e988 --- /dev/null +++ b/libstdc++/include/backward/algobase.h @@ -0,0 +1,91 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ALGOBASE_H +#define _BACKWARD_ALGOBASE_H 1 + +#include "backward_warning.h" +#include "pair.h" +#include "iterator.h" +#include <bits/stl_algobase.h> +#include <bits/stl_uninitialized.h> +#include <ext/algorithm> +#include <ext/memory> + +// Names from stl_algobase.h +using std::iter_swap; +using std::swap; +using std::min; +using std::max; +using std::copy; +using std::copy_backward; +using std::fill; +using std::fill_n; +using std::mismatch; +using std::equal; +using std::lexicographical_compare; + +// Names from stl_uninitialized.h +using std::uninitialized_copy; +using std::uninitialized_fill; +using std::uninitialized_fill_n; + +// Names from ext/algorithm +using __gnu_cxx::copy_n; +using __gnu_cxx::lexicographical_compare_3way; + +// Names from ext/memory +using __gnu_cxx::uninitialized_copy_n; + +#endif /* _BACKWARD_ALGOBASE_H */ diff --git a/libstdc++/include/backward/alloc.h b/libstdc++/include/backward/alloc.h new file mode 100644 index 0000000..40a0af1 --- /dev/null +++ b/libstdc++/include/backward/alloc.h @@ -0,0 +1,52 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ALLOC_H +#define _BACKWARD_ALLOC_H 1 + +#include "backward_warning.h" +#include <bits/c++config.h> +#include <bits/allocator.h> + +using std::allocator; + +#endif diff --git a/libstdc++/include/backward/backward_warning.h b/libstdc++/include/backward/backward_warning.h new file mode 100644 index 0000000..80eabfe --- /dev/null +++ b/libstdc++/include/backward/backward_warning.h @@ -0,0 +1,39 @@ +// Copyright (C) 2001 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 _BACKWARD_BACKWARD_WARNING_H +#define _BACKWARD_BACKWARD_WARNING_H 1 + +#ifdef __DEPRECATED +#warning This file includes at least one deprecated or antiquated header. \ +Please consider using one of the 32 headers found in section 17.4.1.2 of the \ +C++ standard. Examples include substituting the <X> header for the <X.h> \ +header for C++ includes, or <iostream> instead of the deprecated header \ +<iostream.h>. To disable this warning use -Wno-deprecated. +#endif + +#endif diff --git a/libstdc++/include/backward/bvector.h b/libstdc++/include/backward/bvector.h new file mode 100644 index 0000000..9a2c44d --- /dev/null +++ b/libstdc++/include/backward/bvector.h @@ -0,0 +1,64 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_BVECTOR_H +#define _BACKWARD_BVECTOR_H 1 + +#include "backward_warning.h" +#include <vector> + +typedef std::vector<bool, std::allocator<bool> > bit_vector; + +#endif /* _BACKWARD_BVECTOR_H */ diff --git a/libstdc++/include/backward/complex.h b/libstdc++/include/backward/complex.h new file mode 100644 index 0000000..7972cf7 --- /dev/null +++ b/libstdc++/include/backward/complex.h @@ -0,0 +1,39 @@ +// Copyright (C) 2000 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 _BACKWARD_COMPLEX_H +#define _BACKWARD_COMPLEX_H 1 + +#include "backward_warning.h" +#include <complex> + +using std::complex; +typedef complex<float> float_complex; +typedef complex<double> double_complex; +typedef complex<long double> long_double_complex; + +#endif diff --git a/libstdc++/include/backward/defalloc.h b/libstdc++/include/backward/defalloc.h new file mode 100644 index 0000000..ffa9b16 --- /dev/null +++ b/libstdc++/include/backward/defalloc.h @@ -0,0 +1,117 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +// Inclusion of this file is DEPRECATED. This is the original HP +// default allocator. It is provided only for backward compatibility. +// This file WILL BE REMOVED in a future release. +// +// DO NOT USE THIS FILE unless you have an old container implementation +// that requires an allocator with the HP-style interface. +// +// Standard-conforming allocators have a very different interface. The +// standard default allocator is declared in the header <memory>. + +#ifndef _BACKWARD_DEFALLOC_H +#define _BACKWARD_DEFALLOC_H 1 + +#include "backward_warning.h" +#include "new.h" +#include <stddef.h> +#include <stdlib.h> +#include <limits.h> +#include "iostream.h" +#include "algobase.h" + + +template <class _Tp> +inline _Tp* allocate(ptrdiff_t __size, _Tp*) { + set_new_handler(0); + _Tp* __tmp = (_Tp*)(::operator new((size_t)(__size * sizeof(_Tp)))); + if (__tmp == 0) { + cerr << "out of memory" << endl; + exit(1); + } + return __tmp; +} + + +template <class _Tp> +inline void deallocate(_Tp* __buffer) { + ::operator delete(__buffer); +} + +template <class _Tp> +class allocator { +public: + typedef _Tp value_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + pointer allocate(size_type __n) { + return ::allocate((difference_type)__n, (pointer)0); + } + void deallocate(pointer __p) { ::deallocate(__p); } + pointer address(reference __x) { return (pointer)&__x; } + const_pointer const_address(const_reference __x) { + return (const_pointer)&__x; + } + size_type init_page_size() { + return max(size_type(1), size_type(4096/sizeof(_Tp))); + } + size_type max_size() const { + return max(size_type(1), size_type(UINT_MAX/sizeof(_Tp))); + } +}; + +class allocator<void> { +public: + typedef void* pointer; +}; + + + +#endif /* _BACKWARD_DEFALLOC_H */ diff --git a/libstdc++/include/backward/deque.h b/libstdc++/include/backward/deque.h new file mode 100644 index 0000000..a4a6b41 --- /dev/null +++ b/libstdc++/include/backward/deque.h @@ -0,0 +1,66 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_DEQUE_H +#define _BACKWARD_DEQUE_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "alloc.h" +#include <deque> + +using std::deque; + +#endif /* _BACKWARD_DEQUE_H */ diff --git a/libstdc++/include/backward/fstream.h b/libstdc++/include/backward/fstream.h new file mode 100644 index 0000000..92835f9 --- /dev/null +++ b/libstdc++/include/backward/fstream.h @@ -0,0 +1,48 @@ +// Copyright (C) 2000, 2001 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 _BACKWARD_FSTREAM_H +#define _BACKWARD_FSTREAM_H 1 + +#include "backward_warning.h" +#include <fstream> + +using std::filebuf; +using std::ifstream; +using std::ofstream; +using std::fstream; +using std::streampos; + +#ifdef _GLIBCXX_USE_WCHAR_T +using std::wfilebuf; +using std::wifstream; +using std::wofstream; +using std::wfstream; +using std::wstreampos; +#endif + +#endif diff --git a/libstdc++/include/backward/function.h b/libstdc++/include/backward/function.h new file mode 100644 index 0000000..b5be371 --- /dev/null +++ b/libstdc++/include/backward/function.h @@ -0,0 +1,126 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_FUNCTION_H +#define _BACKWARD_FUNCTION_H 1 + +#include "backward_warning.h" +#include <bits/c++config.h> +#include <stddef.h> +#include <bits/stl_function.h> +#include <ext/functional> + +// Names from stl_function.h +using std::unary_function; +using std::binary_function; +using std::plus; +using std::minus; +using std::multiplies; +using std::divides; +using std::modulus; +using std::negate; +using std::equal_to; +using std::not_equal_to; +using std::greater; +using std::less; +using std::greater_equal; +using std::less_equal; +using std::logical_and; +using std::logical_or; +using std::logical_not; +using std::unary_negate; +using std::binary_negate; +using std::not1; +using std::not2; +using std::binder1st; +using std::binder2nd; +using std::bind1st; +using std::bind2nd; +using std::pointer_to_unary_function; +using std::pointer_to_binary_function; +using std::ptr_fun; +using std::mem_fun_t; +using std::const_mem_fun_t; +using std::mem_fun_ref_t; +using std::const_mem_fun_ref_t; +using std::mem_fun1_t; +using std::const_mem_fun1_t; +using std::mem_fun1_ref_t; +using std::const_mem_fun1_ref_t; +using std::mem_fun; +using std::mem_fun_ref; + +// Names from ext/functional +using __gnu_cxx::identity_element; +using __gnu_cxx::unary_compose; +using __gnu_cxx::binary_compose; +using __gnu_cxx::compose1; +using __gnu_cxx::compose2; +using __gnu_cxx::identity; +using __gnu_cxx::select1st; +using __gnu_cxx::select2nd; +using __gnu_cxx::project1st; +using __gnu_cxx::project2nd; +using __gnu_cxx::constant_void_fun; +using __gnu_cxx::constant_unary_fun; +using __gnu_cxx::constant_binary_fun; +using __gnu_cxx::constant0; +using __gnu_cxx::constant1; +using __gnu_cxx::constant2; +using __gnu_cxx::subtractive_rng; +using __gnu_cxx::mem_fun1; +using __gnu_cxx::mem_fun1_ref; + +#endif /* _BACKWARD_FUNCTION_H */ diff --git a/libstdc++/include/backward/hash_map.h b/libstdc++/include/backward/hash_map.h new file mode 100644 index 0000000..aa14522 --- /dev/null +++ b/libstdc++/include/backward/hash_map.h @@ -0,0 +1,68 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_HASH_MAP_H +#define _BACKWARD_HASH_MAP_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include <ext/hash_map> + +using __gnu_cxx::hash; +using __gnu_cxx::hashtable; +using __gnu_cxx::hash_map; +using __gnu_cxx::hash_multimap; + +#endif /* _BACKWARD_HASH_MAP_H */ diff --git a/libstdc++/include/backward/hash_set.h b/libstdc++/include/backward/hash_set.h new file mode 100644 index 0000000..c2c6e39 --- /dev/null +++ b/libstdc++/include/backward/hash_set.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_HASH_SET_H +#define _BACKWARD_HASH_SET_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include <ext/hash_set> + +using __gnu_cxx::hash; +using __gnu_cxx::hashtable; +using __gnu_cxx::hash_set; +using __gnu_cxx::hash_multiset; + +#endif /* _BACKWARD_HASH_SET_H */ + diff --git a/libstdc++/include/backward/hashtable.h b/libstdc++/include/backward/hashtable.h new file mode 100644 index 0000000..7b7511b --- /dev/null +++ b/libstdc++/include/backward/hashtable.h @@ -0,0 +1,72 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef _BACKWARD_HASHTABLE_H +#define _BACKWARD_HASHTABLE_H 1 + +#include "backward_warning.h" +#include <ext/hashtable.h> +#include "algo.h" +#include "alloc.h" +#include "vector.h" + +using __gnu_cxx::hash; +using __gnu_cxx::hashtable; + +#endif /* _BACKWARD_HASHTABLE_H */ diff --git a/libstdc++/include/backward/heap.h b/libstdc++/include/backward/heap.h new file mode 100644 index 0000000..ef2e684 --- /dev/null +++ b/libstdc++/include/backward/heap.h @@ -0,0 +1,67 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_HEAP_H +#define _BACKWARD_HEAP_H 1 + +#include "backward_warning.h" +#include <bits/c++config.h> +#include <bits/stl_heap.h> + +using std::push_heap; +using std::pop_heap; +using std::make_heap; +using std::sort_heap; + +#endif /* _BACKWARD_HEAP_H */ diff --git a/libstdc++/include/backward/iomanip.h b/libstdc++/include/backward/iomanip.h new file mode 100644 index 0000000..a4099a7 --- /dev/null +++ b/libstdc++/include/backward/iomanip.h @@ -0,0 +1,66 @@ +// Copyright (C) 2000 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 _BACKWARD_IOMANIP_H +#define _BACKWARD_IOMANIP_H 1 + +#include "backward_warning.h" +#include "iostream.h" +#include <iomanip> + +// These are from <ios> as per [27.4]. +using std::boolalpha; +using std::noboolalpha; +using std::showbase; +using std::noshowbase; +using std::showpoint; +using std::noshowpoint; +using std::showpos; +using std::noshowpos; +using std::skipws; +using std::noskipws; +using std::uppercase; +using std::nouppercase; +using std::internal; +using std::left; +using std::right; +using std::dec; +using std::hex; +using std::oct; +using std::fixed; +using std::scientific; + +// These are from <iomanip> as per [27.6]. Manipulators from <istream> +// and <ostream> (e.g., endl) are made available via <iostream.h>. +using std::resetiosflags; +using std::setiosflags; +using std::setbase; +using std::setfill; +using std::setprecision; +using std::setw; + +#endif diff --git a/libstdc++/include/backward/iostream.h b/libstdc++/include/backward/iostream.h new file mode 100644 index 0000000..ed275ff --- /dev/null +++ b/libstdc++/include/backward/iostream.h @@ -0,0 +1,56 @@ +// Copyright (C) 1997-1999, 2000 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 _BACKWARD_IOSTREAM_H +#define _BACKWARD_IOSTREAM_H 1 + +#include "backward_warning.h" +#include <iostream> + +using std::iostream; +using std::ostream; +using std::istream; +using std::ios; +using std::streambuf; + +using std::cout; +using std::cin; +using std::cerr; +using std::clog; +#ifdef _GLIBCXX_USE_WCHAR_T +using std::wcout; +using std::wcin; +using std::wcerr; +using std::wclog; +#endif + +using std::ws; +using std::endl; +using std::ends; +using std::flush; + +#endif diff --git a/libstdc++/include/backward/istream.h b/libstdc++/include/backward/istream.h new file mode 100644 index 0000000..b1c55d1 --- /dev/null +++ b/libstdc++/include/backward/istream.h @@ -0,0 +1,34 @@ +// Copyright (C) 2000 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 _BACKWARD_ISTREAM_H +#define _BACKWARD_ISTREAM_H 1 + +#include "backward_warning.h" +#include "iostream.h" + +#endif diff --git a/libstdc++/include/backward/iterator.h b/libstdc++/include/backward/iterator.h new file mode 100644 index 0000000..89496fb --- /dev/null +++ b/libstdc++/include/backward/iterator.h @@ -0,0 +1,187 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ITERATOR_H +#define _BACKWARD_ITERATOR_H 1 + +#include "backward_warning.h" +#include "function.h" +#include <stddef.h> +#include "iostream.h" +#include <iterator> + +#include <bits/stl_construct.h> +#include <bits/stl_raw_storage_iter.h> + +#include <ext/iterator> // For 3-parameter distance extension + +// Names from stl_iterator.h +using std::input_iterator_tag; +using std::output_iterator_tag; +using std::forward_iterator_tag; +using std::bidirectional_iterator_tag; +using std::random_access_iterator_tag; + +#if 0 +using std::iterator; +#endif + +// The base classes input_iterator, output_iterator, forward_iterator, +// bidirectional_iterator, and random_access_iterator are not part of +// the C++ standard. (They have been replaced by struct iterator.) +// They are included for backward compatibility with the HP STL. +template<typename _Tp, typename _Distance> + struct input_iterator { + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +struct output_iterator { + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; +}; + +template<typename _Tp, typename _Distance> + struct forward_iterator { + typedef forward_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +template<typename _Tp, typename _Distance> + struct bidirectional_iterator { + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +template<typename _Tp, typename _Distance> + struct random_access_iterator { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +using std::iterator_traits; + +template <class _Iter> + inline typename iterator_traits<_Iter>::iterator_category + iterator_category(const _Iter& __i) + { return __iterator_category(__i); } + +template <class _Iter> + inline typename iterator_traits<_Iter>::difference_type* + distance_type(const _Iter&) + { return static_cast<typename iterator_traits<_Iter>::difference_type*>(0); } + +template<class _Iter> + inline typename iterator_traits<_Iter>::value_type* + value_type(const _Iter& __i) + { return static_cast<typename iterator_traits<_Iter>::value_type*>(0); } + +using std::distance; +using __gnu_cxx::distance; // 3-parameter extension +using std::advance; + +using std::insert_iterator; +using std::front_insert_iterator; +using std::back_insert_iterator; +using std::inserter; +using std::front_inserter; +using std::back_inserter; + +using std::reverse_iterator; + +using std::istream_iterator; +using std::ostream_iterator; + +// Names from stl_construct.h +template<class _T1, class _T2> + inline void + construct(_T1* __p, const _T2& __value) + { std::_Construct(__p, __value); } + +template<class _T1> + inline void + construct(_T1* __p) + { std::_Construct(__p); } + +template <class _Tp> + inline void + destroy(_Tp* __pointer) + { std::_Destroy(__pointer); } + +template <class _ForwardIterator> + inline void + destroy(_ForwardIterator __first, _ForwardIterator __last) + { std::_Destroy(__first, __last); } + + +// Names from stl_raw_storage_iter.h +using std::raw_storage_iterator; + +#endif /* _BACKWARD_ITERATOR_H */ diff --git a/libstdc++/include/backward/list.h b/libstdc++/include/backward/list.h new file mode 100644 index 0000000..d70a6e4 --- /dev/null +++ b/libstdc++/include/backward/list.h @@ -0,0 +1,66 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_LIST_H +#define _BACKWARD_LIST_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "alloc.h" +#include <list> + +using std::list; + +#endif /* _BACKWARD_LIST_H */ diff --git a/libstdc++/include/backward/map.h b/libstdc++/include/backward/map.h new file mode 100644 index 0000000..2ff3cec --- /dev/null +++ b/libstdc++/include/backward/map.h @@ -0,0 +1,65 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_MAP_H +#define _BACKWARD_MAP_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include <map> + +using std::map; + +#endif /* _BACKWARD_MAP_H */ diff --git a/libstdc++/include/backward/multimap.h b/libstdc++/include/backward/multimap.h new file mode 100644 index 0000000..515d299 --- /dev/null +++ b/libstdc++/include/backward/multimap.h @@ -0,0 +1,65 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_MULTIMAP_H +#define _BACKWARD_MULTIMAP_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include <map> + +using std::multimap; + +#endif /* _BACKWARD_MULTIMAP_H */ diff --git a/libstdc++/include/backward/multiset.h b/libstdc++/include/backward/multiset.h new file mode 100644 index 0000000..1f857ae --- /dev/null +++ b/libstdc++/include/backward/multiset.h @@ -0,0 +1,65 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_MULTISET_H +#define _BACKWARD_MULTISET_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include <set> + +using std::multiset; + +#endif /* _BACKWARD_MULTISET_H */ diff --git a/libstdc++/include/backward/new.h b/libstdc++/include/backward/new.h new file mode 100644 index 0000000..9cfbab2 --- /dev/null +++ b/libstdc++/include/backward/new.h @@ -0,0 +1,42 @@ +// -*- C++ -*- forwarding header. +// Copyright (C) 2000 Free Software Foundation + +// This file is part of GCC. +// +// GCC 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. +// +// GCC 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 GCC; 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 _BACKWARD_NEW_H +#define _BACKWARD_NEW_H 1 + +#include "backward_warning.h" +#include <new> + +using std::bad_alloc; +using std::nothrow_t; +using std::nothrow; +using std::new_handler; +using std::set_new_handler; + +#endif diff --git a/libstdc++/include/backward/ostream.h b/libstdc++/include/backward/ostream.h new file mode 100644 index 0000000..07ef9b0 --- /dev/null +++ b/libstdc++/include/backward/ostream.h @@ -0,0 +1,34 @@ +// Copyright (C) 2000 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 _BACKWARD_OSTREAM_H +#define _BACKWARD_OSTREAM_H 1 + +#include "backward_warning.h" +#include "iostream.h" + +#endif diff --git a/libstdc++/include/backward/pair.h b/libstdc++/include/backward/pair.h new file mode 100644 index 0000000..4985bcb --- /dev/null +++ b/libstdc++/include/backward/pair.h @@ -0,0 +1,66 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_PAIR_H +#define _BACKWARD_PAIR_H 1 + +#include "backward_warning.h" +#include <bits/c++config.h> +#include <bits/stl_pair.h> + +using std::pair; +using std::make_pair; + +#endif /* _BACKWARD_PAIR_H */ diff --git a/libstdc++/include/backward/queue.h b/libstdc++/include/backward/queue.h new file mode 100644 index 0000000..da7505c --- /dev/null +++ b/libstdc++/include/backward/queue.h @@ -0,0 +1,37 @@ +// Copyright (C) 2001 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 _BACKWARD_QUEUE_H +#define _BACKWARD_QUEUE_H 1 + +#include "backward_warning.h" +#include <queue> + +using std::queue; +using std::priority_queue; + +#endif diff --git a/libstdc++/include/backward/rope.h b/libstdc++/include/backward/rope.h new file mode 100644 index 0000000..71e8815 --- /dev/null +++ b/libstdc++/include/backward/rope.h @@ -0,0 +1,56 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ROPE_H +#define _BACKWARD_ROPE_H 1 + +#include "backward_warning.h" +#include "hashtable.h" +#include <ext/rope> + +using __gnu_cxx::char_producer; +using __gnu_cxx::sequence_buffer; +using __gnu_cxx::rope; +using __gnu_cxx::crope; +using __gnu_cxx::wrope; + +#endif /* _BACKWARD_ROPE_H */ diff --git a/libstdc++/include/backward/set.h b/libstdc++/include/backward/set.h new file mode 100644 index 0000000..3c6a390 --- /dev/null +++ b/libstdc++/include/backward/set.h @@ -0,0 +1,65 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_SET_H +#define _BACKWARD_SET_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include <set> + +using std::set; + +#endif /* _BACKWARD_SET_H */ diff --git a/libstdc++/include/backward/slist.h b/libstdc++/include/backward/slist.h new file mode 100644 index 0000000..9b9a43d --- /dev/null +++ b/libstdc++/include/backward/slist.h @@ -0,0 +1,52 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_SLIST_H +#define _BACKWARD_SLIST_H 1 + +#include "backward_warning.h" +#include <ext/slist> + +using __gnu_cxx::slist; + +#endif /* _BACKWARD_SLIST_H */ diff --git a/libstdc++/include/backward/stack.h b/libstdc++/include/backward/stack.h new file mode 100644 index 0000000..07df417 --- /dev/null +++ b/libstdc++/include/backward/stack.h @@ -0,0 +1,68 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_STACK_H +#define _BACKWARD_STACK_H 1 + +#include "backward_warning.h" +#include "vector.h" +#include "deque.h" +#include "heap.h" +#include "queue.h" +#include <stack> + +using std::stack; + +#endif /* _BACKWARD_STACK_H */ diff --git a/libstdc++/include/backward/stream.h b/libstdc++/include/backward/stream.h new file mode 100644 index 0000000..c137601 --- /dev/null +++ b/libstdc++/include/backward/stream.h @@ -0,0 +1,34 @@ +// Copyright (C) 2000 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 _BACKWARD_STREAM_H +#define _BACKWARD_STREAM_H 1 + +#include "backward_warning.h" +#include "iostream.h" + +#endif diff --git a/libstdc++/include/backward/streambuf.h b/libstdc++/include/backward/streambuf.h new file mode 100644 index 0000000..bac2449 --- /dev/null +++ b/libstdc++/include/backward/streambuf.h @@ -0,0 +1,36 @@ +// Copyright (C) 2000 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 _BACKWARD_STREAMBUF_H +#define _BACKWARD_STREAMBUF_H 1 + +#include "backward_warning.h" +#include <streambuf> + +using std::streambuf; + +#endif diff --git a/libstdc++/include/backward/strstream b/libstdc++/include/backward/strstream new file mode 100644 index 0000000..d0d5a13 --- /dev/null +++ b/libstdc++/include/backward/strstream @@ -0,0 +1,181 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +// WARNING: The classes defined in this header are DEPRECATED. This +// header is defined in section D.7.1 of the C++ standard, and it +// MAY BE REMOVED in a future standard revision. You should use the +// header <sstream> instead. + +#ifndef __SGI_STL_STRSTREAM +#define __SGI_STL_STRSTREAM + +#include "backward_warning.h" +#include <iosfwd> +#include <ios> +#include <istream> +#include <ostream> +#include <string> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Class strstreambuf, a streambuf class that manages an array of char. + // Note that this class is not a template. + class strstreambuf : public basic_streambuf<char, char_traits<char> > + { + public: + // Types. + typedef char_traits<char> _Traits; + typedef basic_streambuf<char, _Traits> _Base; + + public: + // Constructor, destructor + explicit strstreambuf(streamsize __initial_capacity = 0); + strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*)); + + strstreambuf(char* __get, streamsize __n, char* __put = 0); + strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0); + strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0); + + strstreambuf(const char* __get, streamsize __n); + strstreambuf(const signed char* __get, streamsize __n); + strstreambuf(const unsigned char* __get, streamsize __n); + + virtual ~strstreambuf(); + + public: + void freeze(bool = true); + char* str(); + int pcount() const; + + protected: + virtual int_type overflow(int_type __c = _Traits::eof()); + virtual int_type pbackfail(int_type __c = _Traits::eof()); + virtual int_type underflow(); + virtual _Base* setbuf(char* __buf, streamsize __n); + virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir, + ios_base::openmode __mode + = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode + = ios_base::in | ios_base::out); + + private: + strstreambuf& + operator=(const strstreambuf&); + + strstreambuf(const strstreambuf&); + + // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun. + char* _M_alloc(size_t); + void _M_free(char*); + + // Helper function used in constructors. + void _M_setup(char* __get, char* __put, streamsize __n); + + private: + // Data members. + void* (*_M_alloc_fun)(size_t); + void (*_M_free_fun)(void*); + + bool _M_dynamic : 1; + bool _M_frozen : 1; + bool _M_constant : 1; + }; + + // Class istrstream, an istream that manages a strstreambuf. + class istrstream : public basic_istream<char> + { + public: + explicit istrstream(char*); + explicit istrstream(const char*); + istrstream(char* , streamsize); + istrstream(const char*, streamsize); + virtual ~istrstream(); + + strstreambuf* rdbuf() const; + char* str(); + + private: + strstreambuf _M_buf; + }; + + // Class ostrstream + class ostrstream : public basic_ostream<char> + { + public: + ostrstream(); + ostrstream(char*, int, ios_base::openmode = ios_base::out); + virtual ~ostrstream(); + + strstreambuf* rdbuf() const; + void freeze(bool = true); + char* str(); + int pcount() const; + + private: + strstreambuf _M_buf; + }; + + // Class strstream + class strstream : public basic_iostream<char> + { + public: + typedef char char_type; + typedef char_traits<char>::int_type int_type; + typedef char_traits<char>::pos_type pos_type; + typedef char_traits<char>::off_type off_type; + + strstream(); + strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out); + virtual ~strstream(); + + strstreambuf* rdbuf() const; + void freeze(bool = true); + int pcount() const; + char* str(); + + private: + strstreambuf _M_buf; + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/backward/tempbuf.h b/libstdc++/include/backward/tempbuf.h new file mode 100644 index 0000000..af6e57d --- /dev/null +++ b/libstdc++/include/backward/tempbuf.h @@ -0,0 +1,74 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_TEMPBUF_H +#define _BACKWARD_TEMPBUF_H 1 + +#include "backward_warning.h" +#include "pair.h" +#include "iterator.h" +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <bits/cpp_type_traits.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <ext/memory> + +using std::get_temporary_buffer; +using std::return_temporary_buffer; +using __gnu_cxx::temporary_buffer; + +#endif /* _BACKWARD_TEMPBUF_H */ diff --git a/libstdc++/include/backward/tree.h b/libstdc++/include/backward/tree.h new file mode 100644 index 0000000..88a2f1d --- /dev/null +++ b/libstdc++/include/backward/tree.h @@ -0,0 +1,52 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_TREE +#define _BACKWARD_TREE 1 + +#include "backward_warning.h" +#include <ext/rb_tree> + +using __gnu_cxx::rb_tree; + +#endif diff --git a/libstdc++/include/backward/vector.h b/libstdc++/include/backward/vector.h new file mode 100644 index 0000000..8cd8dd0 --- /dev/null +++ b/libstdc++/include/backward/vector.h @@ -0,0 +1,66 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_VECTOR_H +#define _BACKWARD_VECTOR_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "alloc.h" +#include <vector> + +using std::vector; + +#endif /* _BACKWARD_VECTOR_H */ diff --git a/libstdc++/include/bits/allocator.h b/libstdc++/include/bits/allocator.h new file mode 100644 index 0000000..43939c1 --- /dev/null +++ b/libstdc++/include/bits/allocator.h @@ -0,0 +1,153 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 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. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file allocator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALLOCATOR_H +#define _ALLOCATOR_H 1 + +// Define the base class to std::allocator. +#include <bits/c++allocator.h> + +#include <bits/cpp_type_traits.h> // for __is_empty + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _Tp> + class allocator; + + /// allocator<void> specialization. + template<> + class allocator<void> + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template<typename _Tp1> + struct rebind + { typedef allocator<_Tp1> other; }; + }; + + /** + * @brief The "standard" allocator, as per [20.4]. + * + * Further details: + * http://gcc.gnu.org/onlinedocs/libstdc++/20_util/allocator.html + */ + template<typename _Tp> + class allocator: public __glibcxx_base_allocator<_Tp> + { + 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 allocator<_Tp1> other; }; + + allocator() throw() { } + + allocator(const allocator& __a) throw() + : __glibcxx_base_allocator<_Tp>(__a) { } + + template<typename _Tp1> + allocator(const allocator<_Tp1>&) throw() { } + + ~allocator() throw() { } + + // Inherit everything else. + }; + + template<typename _T1, typename _T2> + inline bool + operator==(const allocator<_T1>&, const allocator<_T2>&) + { return true; } + + template<typename _T1, typename _T2> + inline bool + operator!=(const allocator<_T1>&, const allocator<_T2>&) + { return false; } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class allocator<char>; + extern template class allocator<wchar_t>; +#endif + + // Undefine. +#undef __glibcxx_base_allocator + + // To implement Option 3 of DR 431. + template<typename _Alloc, bool = std::__is_empty<_Alloc>::__value> + struct __alloc_swap + { static void _S_do_it(_Alloc&, _Alloc&) { } }; + + template<typename _Alloc> + struct __alloc_swap<_Alloc, false> + { + static void + _S_do_it(_Alloc& __one, _Alloc& __two) + { + // Precondition: swappable allocators. + if (__one != __two) + swap(__one, __two); + } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/basic_ios.h b/libstdc++/include/bits/basic_ios.h new file mode 100644 index 0000000..d078431 --- /dev/null +++ b/libstdc++/include/bits/basic_ios.h @@ -0,0 +1,468 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 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. + +/** @file basic_ios.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BASIC_IOS_H +#define _BASIC_IOS_H 1 + +#pragma GCC system_header + +#include <bits/streambuf_iterator.h> +#include <bits/localefwd.h> +#include <bits/locale_classes.h> +#include <bits/locale_facets.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // 27.4.5 Template class basic_ios + /** + * @brief Virtual base class for all stream classes. + * + * Most of the member functions called dispatched on stream objects + * (e.g., @c std::cout.foo(bar);) are consolidated in this class. + */ + template<typename _CharT, typename _Traits> + class basic_ios : public ios_base + { + public: + //@{ + /** + * These are standard types. They permit a standardized way of + * referring to names of (or names dependant on) the template + * parameters, which are specific to the implementation. + */ + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + //@} + + //@{ + /** + * @if maint + * These are non-standard types. + * @endif + */ + typedef ctype<_CharT> __ctype_type; + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > + __num_put_type; + typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > + __num_get_type; + //@} + + // Data members: + protected: + basic_ostream<_CharT, _Traits>* _M_tie; + mutable char_type _M_fill; + mutable bool _M_fill_init; + basic_streambuf<_CharT, _Traits>* _M_streambuf; + + // Cached use_facet<ctype>, which is based on the current locale info. + const __ctype_type* _M_ctype; + // For ostream. + const __num_put_type* _M_num_put; + // For istream. + const __num_get_type* _M_num_get; + + public: + //@{ + /** + * @brief The quick-and-easy status check. + * + * This allows you to write constructs such as + * "if (!a_stream) ..." and "while (a_stream) ..." + */ + operator void*() const + { return this->fail() ? 0 : const_cast<basic_ios*>(this); } + + bool + operator!() const + { return this->fail(); } + //@} + + /** + * @brief Returns the error state of the stream buffer. + * @return A bit pattern (well, isn't everything?) + * + * See std::ios_base::iostate for the possible bit values. Most + * users will call one of the interpreting wrappers, e.g., good(). + */ + iostate + rdstate() const + { return _M_streambuf_state; } + + /** + * @brief [Re]sets the error state. + * @param state The new state flag(s) to set. + * + * See std::ios_base::iostate for the possible bit values. Most + * users will not need to pass an argument. + */ + void + clear(iostate __state = goodbit); + + /** + * @brief Sets additional flags in the error state. + * @param state The additional state flag(s) to set. + * + * See std::ios_base::iostate for the possible bit values. + */ + void + setstate(iostate __state) + { this->clear(this->rdstate() | __state); } + + // Flip the internal state on for the proper state bits, then re + // throws the propagated exception if bit also set in + // exceptions(). + void + _M_setstate(iostate __state) + { + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + _M_streambuf_state |= __state; + if (this->exceptions() & __state) + __throw_exception_again; + } + + /** + * @brief Fast error checking. + * @return True if no error flags are set. + * + * A wrapper around rdstate. + */ + bool + good() const + { return this->rdstate() == 0; } + + /** + * @brief Fast error checking. + * @return True if the eofbit is set. + * + * Note that other iostate flags may also be set. + */ + bool + eof() const + { return (this->rdstate() & eofbit) != 0; } + + /** + * @brief Fast error checking. + * @return True if either the badbit or the failbit is set. + * + * Checking the badbit in fail() is historical practice. + * Note that other iostate flags may also be set. + */ + bool + fail() const + { return (this->rdstate() & (badbit | failbit)) != 0; } + + /** + * @brief Fast error checking. + * @return True if the badbit is set. + * + * Note that other iostate flags may also be set. + */ + bool + bad() const + { return (this->rdstate() & badbit) != 0; } + + /** + * @brief Throwing exceptions on errors. + * @return The current exceptions mask. + * + * This changes nothing in the stream. See the one-argument version + * of exceptions(iostate) for the meaning of the return value. + */ + iostate + exceptions() const + { return _M_exception; } + + /** + * @brief Throwing exceptions on errors. + * @param except The new exceptions mask. + * + * By default, error flags are set silently. You can set an + * exceptions mask for each stream; if a bit in the mask becomes set + * in the error flags, then an exception of type + * std::ios_base::failure is thrown. + * + * If the error flage is already set when the exceptions mask is + * added, the exception is immediately thrown. Try running the + * following under GCC 3.1 or later: + * @code + * #include <iostream> + * #include <fstream> + * #include <exception> + * + * int main() + * { + * std::set_terminate (__gnu_cxx::__verbose_terminate_handler); + * + * std::ifstream f ("/etc/motd"); + * + * std::cerr << "Setting badbit\n"; + * f.setstate (std::ios_base::badbit); + * + * std::cerr << "Setting exception mask\n"; + * f.exceptions (std::ios_base::badbit); + * } + * @endcode + */ + void + exceptions(iostate __except) + { + _M_exception = __except; + this->clear(_M_streambuf_state); + } + + // Constructor/destructor: + /** + * @brief Constructor performs initialization. + * + * The parameter is passed by derived streams. + */ + explicit + basic_ios(basic_streambuf<_CharT, _Traits>* __sb) + : ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0), + _M_ctype(0), _M_num_put(0), _M_num_get(0) + { this->init(__sb); } + + /** + * @brief Empty. + * + * The destructor does nothing. More specifically, it does not + * destroy the streambuf held by rdbuf(). + */ + virtual + ~basic_ios() { } + + // Members: + /** + * @brief Fetches the current @e tied stream. + * @return A pointer to the tied stream, or NULL if the stream is + * not tied. + * + * A stream may be @e tied (or synchronized) to a second output + * stream. When this stream performs any I/O, the tied stream is + * first flushed. For example, @c std::cin is tied to @c std::cout. + */ + basic_ostream<_CharT, _Traits>* + tie() const + { return _M_tie; } + + /** + * @brief Ties this stream to an output stream. + * @param tiestr The output stream. + * @return The previously tied output stream, or NULL if the stream + * was not tied. + * + * This sets up a new tie; see tie() for more. + */ + basic_ostream<_CharT, _Traits>* + tie(basic_ostream<_CharT, _Traits>* __tiestr) + { + basic_ostream<_CharT, _Traits>* __old = _M_tie; + _M_tie = __tiestr; + return __old; + } + + /** + * @brief Accessing the underlying buffer. + * @return The current stream buffer. + * + * This does not change the state of the stream. + */ + basic_streambuf<_CharT, _Traits>* + rdbuf() const + { return _M_streambuf; } + + /** + * @brief Changing the underlying buffer. + * @param sb The new stream buffer. + * @return The previous stream buffer. + * + * Associates a new buffer with the current stream, and clears the + * error state. + * + * Due to historical accidents which the LWG refuses to correct, the + * I/O library suffers from a design error: this function is hidden + * in derived classes by overrides of the zero-argument @c rdbuf(), + * which is non-virtual for hysterical raisins. As a result, you + * must use explicit qualifications to access this function via any + * derived class. For example: + * + * @code + * std::fstream foo; // or some other derived type + * std::streambuf* p = .....; + * + * foo.ios::rdbuf(p); // ios == basic_ios<char> + * @endcode + */ + basic_streambuf<_CharT, _Traits>* + rdbuf(basic_streambuf<_CharT, _Traits>* __sb); + + /** + * @brief Copies fields of __rhs into this. + * @param __rhs The source values for the copies. + * @return Reference to this object. + * + * All fields of __rhs are copied into this object except that rdbuf() + * and rdstate() remain unchanged. All values in the pword and iword + * arrays are copied. Before copying, each callback is invoked with + * erase_event. After copying, each (new) callback is invoked with + * copyfmt_event. The final step is to copy exceptions(). + */ + basic_ios& + copyfmt(const basic_ios& __rhs); + + /** + * @brief Retreives the "empty" character. + * @return The current fill character. + * + * It defaults to a space (' ') in the current locale. + */ + char_type + fill() const + { + if (!_M_fill_init) + { + _M_fill = this->widen(' '); + _M_fill_init = true; + } + return _M_fill; + } + + /** + * @brief Sets a new "empty" character. + * @param ch The new character. + * @return The previous fill character. + * + * The fill character is used to fill out space when P+ characters + * have been requested (e.g., via setw), Q characters are actually + * used, and Q<P. It defaults to a space (' ') in the current locale. + */ + char_type + fill(char_type __ch) + { + char_type __old = this->fill(); + _M_fill = __ch; + return __old; + } + + // Locales: + /** + * @brief Moves to a new locale. + * @param loc The new locale. + * @return The previous locale. + * + * Calls @c ios_base::imbue(loc), and if a stream buffer is associated + * with this stream, calls that buffer's @c pubimbue(loc). + * + * Additional l10n notes are at + * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html + */ + locale + imbue(const locale& __loc); + + /** + * @brief Squeezes characters. + * @param c The character to narrow. + * @param dfault The character to narrow. + * @return The narrowed character. + * + * Maps a character of @c char_type to a character of @c char, + * if possible. + * + * Returns the result of + * @code + * std::use_facet<ctype<char_type> >(getloc()).narrow(c,dfault) + * @endcode + * + * Additional l10n notes are at + * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html + */ + char + narrow(char_type __c, char __dfault) const; + + /** + * @brief Widens characters. + * @param c The character to widen. + * @return The widened character. + * + * Maps a character of @c char to a character of @c char_type. + * + * Returns the result of + * @code + * std::use_facet<ctype<char_type> >(getloc()).widen(c) + * @endcode + * + * Additional l10n notes are at + * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html + */ + char_type + widen(char __c) const; + + protected: + // 27.4.5.1 basic_ios constructors + /** + * @brief Empty. + * + * The default constructor does nothing and is not normally + * accessible to users. + */ + basic_ios() + : ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false), + _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0) + { } + + /** + * @brief All setup is performed here. + * + * This is called from the public constructor. It is not virtual and + * cannot be redefined. + */ + void + init(basic_streambuf<_CharT, _Traits>* __sb); + + void + _M_cache_locale(const locale& __loc); + }; + +_GLIBCXX_END_NAMESPACE + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +#include <bits/basic_ios.tcc> +#endif + +#endif /* _BASIC_IOS_H */ diff --git a/libstdc++/include/bits/basic_ios.tcc b/libstdc++/include/bits/basic_ios.tcc new file mode 100644 index 0000000..e8434a5 --- /dev/null +++ b/libstdc++/include/bits/basic_ios.tcc @@ -0,0 +1,202 @@ +// basic_ios member functions -*- C++ -*- + +// Copyright (C) 1999, 2001, 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. + +/** @file basic_ios.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BASIC_IOS_TCC +#define _BASIC_IOS_TCC 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _CharT, typename _Traits> + void + basic_ios<_CharT, _Traits>::clear(iostate __state) + { + if (this->rdbuf()) + _M_streambuf_state = __state; + else + _M_streambuf_state = __state | badbit; + if (this->exceptions() & this->rdstate()) + __throw_ios_failure(__N("basic_ios::clear")); + } + + template<typename _CharT, typename _Traits> + basic_streambuf<_CharT, _Traits>* + basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb) + { + basic_streambuf<_CharT, _Traits>* __old = _M_streambuf; + _M_streambuf = __sb; + this->clear(); + return __old; + } + + template<typename _CharT, typename _Traits> + basic_ios<_CharT, _Traits>& + basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 292. effects of a.copyfmt (a) + if (this != &__rhs) + { + // Per 27.1.1, do not call imbue, yet must trash all caches + // associated with imbue() + + // Alloc any new word array first, so if it fails we have "rollback". + _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? + _M_local_word : new _Words[__rhs._M_word_size]; + + // Bump refs before doing callbacks, for safety. + _Callback_list* __cb = __rhs._M_callbacks; + if (__cb) + __cb->_M_add_reference(); + _M_call_callbacks(erase_event); + if (_M_word != _M_local_word) + { + delete [] _M_word; + _M_word = 0; + } + _M_dispose_callbacks(); + + // NB: Don't want any added during above. + _M_callbacks = __cb; + for (int __i = 0; __i < __rhs._M_word_size; ++__i) + __words[__i] = __rhs._M_word[__i]; + _M_word = __words; + _M_word_size = __rhs._M_word_size; + + this->flags(__rhs.flags()); + this->width(__rhs.width()); + this->precision(__rhs.precision()); + this->tie(__rhs.tie()); + this->fill(__rhs.fill()); + _M_ios_locale = __rhs.getloc(); + _M_cache_locale(_M_ios_locale); + + _M_call_callbacks(copyfmt_event); + + // The next is required to be the last assignment. + this->exceptions(__rhs.exceptions()); + } + return *this; + } + + template<typename _CharT, typename _Traits> + char + basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const + { return __check_facet(_M_ctype).narrow(__c, __dfault); } + + template<typename _CharT, typename _Traits> + _CharT + basic_ios<_CharT, _Traits>::widen(char __c) const + { return __check_facet(_M_ctype).widen(__c); } + + // Locales: + template<typename _CharT, typename _Traits> + locale + basic_ios<_CharT, _Traits>::imbue(const locale& __loc) + { + locale __old(this->getloc()); + ios_base::imbue(__loc); + _M_cache_locale(__loc); + if (this->rdbuf() != 0) + this->rdbuf()->pubimbue(__loc); + return __old; + } + + template<typename _CharT, typename _Traits> + void + basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb) + { + // NB: This may be called more than once on the same object. + ios_base::_M_init(); + + // Cache locale data and specific facets used by iostreams. + _M_cache_locale(_M_ios_locale); + + // NB: The 27.4.4.1 Postconditions Table specifies requirements + // after basic_ios::init() has been called. As part of this, + // fill() must return widen(' ') any time after init() has been + // called, which needs an imbued ctype facet of char_type to + // return without throwing an exception. Unfortunately, + // ctype<char_type> is not necessarily a required facet, so + // streams with char_type != [char, wchar_t] will not have it by + // default. Because of this, the correct value for _M_fill is + // constructed on the first call of fill(). That way, + // unformatted input and output with non-required basic_ios + // instantiations is possible even without imbuing the expected + // ctype<char_type> facet. + _M_fill = _CharT(); + _M_fill_init = false; + + _M_tie = 0; + _M_exception = goodbit; + _M_streambuf = __sb; + _M_streambuf_state = __sb ? goodbit : badbit; + } + + template<typename _CharT, typename _Traits> + void + basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc) + { + if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) + _M_ctype = &use_facet<__ctype_type>(__loc); + else + _M_ctype = 0; + + if (__builtin_expect(has_facet<__num_put_type>(__loc), true)) + _M_num_put = &use_facet<__num_put_type>(__loc); + else + _M_num_put = 0; + + if (__builtin_expect(has_facet<__num_get_type>(__loc), true)) + _M_num_get = &use_facet<__num_get_type>(__loc); + else + _M_num_get = 0; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_ios<char>; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_ios<wchar_t>; +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/basic_string.h b/libstdc++/include/bits/basic_string.h new file mode 100644 index 0000000..e4b7a5b --- /dev/null +++ b/libstdc++/include/bits/basic_string.h @@ -0,0 +1,2457 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, +// 2006, 2007 +// 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. + +/** @file basic_string.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 21 Strings library +// + +#ifndef _BASIC_STRING_H +#define _BASIC_STRING_H 1 + +#pragma GCC system_header + +#include <ext/atomicity.h> +#include <debug/debug.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @class basic_string basic_string.h <string> + * @brief Managing sequences of characters and character-like objects. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and a + * <a href="tables.html#67">sequence</a>. Of the + * <a href="tables.html#68">optional sequence requirements</a>, only + * @c push_back, @c at, and array access are supported. + * + * @doctodo + * + * + * @if maint + * Documentation? What's that? + * Nathan Myers <ncm@cantrip.org>. + * + * A string looks like this: + * + * @code + * [_Rep] + * _M_length + * [basic_string<char_type>] _M_capacity + * _M_dataplus _M_refcount + * _M_p ----------------> unnamed array of char_type + * @endcode + * + * Where the _M_p points to the first character in the string, and + * you cast it to a pointer-to-_Rep and subtract 1 to get a + * pointer to the header. + * + * This approach has the enormous advantage that a string object + * requires only one allocation. All the ugliness is confined + * within a single pair of inline functions, which each compile to + * a single "add" instruction: _Rep::_M_data(), and + * string::_M_rep(); and the allocation function which gets a + * block of raw bytes and with room enough and constructs a _Rep + * object at the front. + * + * The reason you want _M_data pointing to the character array and + * not the _Rep is so that the debugger can see the string + * contents. (Probably we should add a non-inline member to get + * the _Rep for the debugger to use, so users can check the actual + * string length.) + * + * Note that the _Rep object is a POD so that you can have a + * static "empty string" _Rep object already "constructed" before + * static constructors have run. The reference-count encoding is + * chosen so that a 0 indicates one reference, so you never try to + * destroy the empty-string _Rep object. + * + * All but the last paragraph is considered pretty conventional + * for a C++ string implementation. + * @endif + */ + // 21.3 Template class basic_string + template<typename _CharT, typename _Traits, typename _Alloc> + class basic_string + { + typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; + + // Types: + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + typedef typename _CharT_alloc_type::size_type size_type; + typedef typename _CharT_alloc_type::difference_type difference_type; + typedef typename _CharT_alloc_type::reference reference; + typedef typename _CharT_alloc_type::const_reference const_reference; + typedef typename _CharT_alloc_type::pointer pointer; + typedef typename _CharT_alloc_type::const_pointer const_pointer; + typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator; + typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string> + const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + + private: + // _Rep: string representation + // Invariants: + // 1. String really contains _M_length + 1 characters: due to 21.3.4 + // must be kept null-terminated. + // 2. _M_capacity >= _M_length + // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). + // 3. _M_refcount has three states: + // -1: leaked, one reference, no ref-copies allowed, non-const. + // 0: one reference, non-const. + // n>0: n + 1 references, operations require a lock, const. + // 4. All fields==0 is an empty string, given the extra storage + // beyond-the-end for a null terminator; thus, the shared + // empty string representation needs no constructor. + + struct _Rep_base + { + size_type _M_length; + size_type _M_capacity; + _Atomic_word _M_refcount; + }; + + struct _Rep : _Rep_base + { + // Types: + typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc; + + // (Public) Data members: + + // The maximum number of individual char_type elements of an + // individual string is determined by _S_max_size. This is the + // value that will be returned by max_size(). (Whereas npos + // is the maximum number of bytes the allocator can allocate.) + // If one was to divvy up the theoretical largest size string, + // with a terminating character and m _CharT elements, it'd + // look like this: + // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) + // Solving for m: + // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 + // In addition, this implementation quarters this amount. + static const size_type _S_max_size; + static const _CharT _S_terminal; + + // The following storage is init'd to 0 by the linker, resulting + // (carefully) in an empty string with one reference. + static size_type _S_empty_rep_storage[]; + + static _Rep& + _S_empty_rep() + { + // NB: Mild hack to avoid strict-aliasing warnings. Note that + // _S_empty_rep_storage is never modified and the punning should + // be reasonably safe in this case. + void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage); + return *reinterpret_cast<_Rep*>(__p); + } + + bool + _M_is_leaked() const + { return this->_M_refcount < 0; } + + bool + _M_is_shared() const + { return this->_M_refcount > 0; } + + void + _M_set_leaked() + { this->_M_refcount = -1; } + + void + _M_set_sharable() + { this->_M_refcount = 0; } + + void + _M_set_length_and_sharable(size_type __n) + { + this->_M_set_sharable(); // One reference. + this->_M_length = __n; + traits_type::assign(this->_M_refdata()[__n], _S_terminal); + // grrr. (per 21.3.4) + // You cannot leave those LWG people alone for a second. + } + + _CharT* + _M_refdata() throw() + { return reinterpret_cast<_CharT*>(this + 1); } + + _CharT* + _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) + { + return (!_M_is_leaked() && __alloc1 == __alloc2) + ? _M_refcopy() : _M_clone(__alloc1); + } + + // Create & Destroy + static _Rep* + _S_create(size_type, size_type, const _Alloc&); + + void + _M_dispose(const _Alloc& __a) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__builtin_expect(this != &_S_empty_rep(), false)) +#endif + if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, + -1) <= 0) + _M_destroy(__a); + } // XXX MT + + void + _M_destroy(const _Alloc&) throw(); + + _CharT* + _M_refcopy() throw() + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__builtin_expect(this != &_S_empty_rep(), false)) +#endif + __gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1); + return _M_refdata(); + } // XXX MT + + _CharT* + _M_clone(const _Alloc&, size_type __res = 0); + }; + + // Use empty-base optimization: http://www.cantrip.org/emptyopt.html + struct _Alloc_hider : _Alloc + { + _Alloc_hider(_CharT* __dat, const _Alloc& __a) + : _Alloc(__a), _M_p(__dat) { } + + _CharT* _M_p; // The actual data. + }; + + public: + // Data Members (public): + // NB: This is an unsigned type, and thus represents the maximum + // size that the allocator can hold. + /// Value returned by various member functions when they fail. + static const size_type npos = static_cast<size_type>(-1); + + private: + // Data Members (private): + mutable _Alloc_hider _M_dataplus; + + _CharT* + _M_data() const + { return _M_dataplus._M_p; } + + _CharT* + _M_data(_CharT* __p) + { return (_M_dataplus._M_p = __p); } + + _Rep* + _M_rep() const + { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } + + // For the internal use we have functions similar to `begin'/`end' + // but they do not call _M_leak. + iterator + _M_ibegin() const + { return iterator(_M_data()); } + + iterator + _M_iend() const + { return iterator(_M_data() + this->size()); } + + void + _M_leak() // for use in begin() & non-const op[] + { + if (!_M_rep()->_M_is_leaked()) + _M_leak_hard(); + } + + size_type + _M_check(size_type __pos, const char* __s) const + { + if (__pos > this->size()) + __throw_out_of_range(__N(__s)); + return __pos; + } + + void + _M_check_length(size_type __n1, size_type __n2, const char* __s) const + { + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N(__s)); + } + + // NB: _M_limit doesn't check for a bad __pos value. + size_type + _M_limit(size_type __pos, size_type __off) const + { + const bool __testoff = __off < this->size() - __pos; + return __testoff ? __off : this->size() - __pos; + } + + // True if _Rep and source do not overlap. + bool + _M_disjunct(const _CharT* __s) const + { + return (less<const _CharT*>()(__s, _M_data()) + || less<const _CharT*>()(_M_data() + this->size(), __s)); + } + + // When __n = 1 way faster than the general multichar + // traits_type::copy/move/assign. + static void + _M_copy(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::copy(__d, __s, __n); + } + + static void + _M_move(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::move(__d, __s, __n); + } + + static void + _M_assign(_CharT* __d, size_type __n, _CharT __c) + { + if (__n == 1) + traits_type::assign(*__d, __c); + else + traits_type::assign(__d, __n, __c); + } + + // _S_copy_chars is a separate template to permit specialization + // to optimize for the common case of pointers as iterators. + template<class _Iterator> + static void + _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + { + for (; __k1 != __k2; ++__k1, ++__p) + traits_type::assign(*__p, *__k1); // These types are off. + } + + static void + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) + { _M_copy(__p, __k1, __k2 - __k1); } + + static void + _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + { _M_copy(__p, __k1, __k2 - __k1); } + + void + _M_mutate(size_type __pos, size_type __len1, size_type __len2); + + void + _M_leak_hard(); + + static _Rep& + _S_empty_rep() + { return _Rep::_S_empty_rep(); } + + public: + // Construct/copy/destroy: + // NB: We overload ctors in some cases instead of using default + // arguments, per 17.4.4.4 para. 2 item 2. + + /** + * @brief Default constructor creates an empty string. + */ + inline + basic_string(); + + /** + * @brief Construct an empty string using allocator @a a. + */ + explicit + basic_string(const _Alloc& __a); + + // NB: per LWG issue 42, semantics different from IS: + /** + * @brief Construct string with copy of value of @a str. + * @param str Source string. + */ + basic_string(const basic_string& __str); + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy (default remainder). + */ + basic_string(const basic_string& __str, size_type __pos, + size_type __n = npos); + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy. + * @param a Allocator to use. + */ + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a); + + /** + * @brief Construct string initialized by a character array. + * @param s Source character array. + * @param n Number of characters to copy. + * @param a Allocator to use (default is default allocator). + * + * NB: @a s must have at least @a n characters, '\0' has no special + * meaning. + */ + basic_string(const _CharT* __s, size_type __n, + const _Alloc& __a = _Alloc()); + /** + * @brief Construct string as copy of a C string. + * @param s Source C string. + * @param a Allocator to use (default is default allocator). + */ + basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()); + /** + * @brief Construct string as multiple characters. + * @param n Number of characters. + * @param c Character to use. + * @param a Allocator to use (default is default allocator). + */ + basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()); + + /** + * @brief Construct string as copy of a range. + * @param beg Start of range. + * @param end End of range. + * @param a Allocator to use (default is default allocator). + */ + template<class _InputIterator> + basic_string(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a = _Alloc()); + + /** + * @brief Destroy the string instance. + */ + ~basic_string() + { _M_rep()->_M_dispose(this->get_allocator()); } + + /** + * @brief Assign the value of @a str to this string. + * @param str Source string. + */ + basic_string& + operator=(const basic_string& __str) + { return this->assign(__str); } + + /** + * @brief Copy contents of @a s into this string. + * @param s Source null-terminated string. + */ + basic_string& + operator=(const _CharT* __s) + { return this->assign(__s); } + + /** + * @brief Set value to string of length 1. + * @param c Source character. + * + * Assigning to a character makes this string length 1 and + * (*this)[0] == @a c. + */ + basic_string& + operator=(_CharT __c) + { + this->assign(1, __c); + return *this; + } + + // Iterators: + /** + * Returns a read/write iterator that points to the first character in + * the %string. Unshares the string. + */ + iterator + begin() + { + _M_leak(); + return iterator(_M_data()); + } + + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ + const_iterator + begin() const + { return const_iterator(_M_data()); } + + /** + * Returns a read/write iterator that points one past the last + * character in the %string. Unshares the string. + */ + iterator + end() + { + _M_leak(); + return iterator(_M_data() + this->size()); + } + + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ + const_iterator + end() const + { return const_iterator(_M_data() + this->size()); } + + /** + * Returns a read/write reverse iterator that points to the last + * character in the %string. Iteration is done in reverse element + * order. Unshares the string. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->end()); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first character in the %string. Iteration is done in reverse + * element order. Unshares the string. + */ + reverse_iterator + rend() + { return reverse_iterator(this->begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->begin()); } + + public: + // Capacity: + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + size() const + { return _M_rep()->_M_length; } + + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + length() const + { return _M_rep()->_M_length; } + + /// Returns the size() of the largest possible %string. + size_type + max_size() const + { return _Rep::_S_max_size; } + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * @param c Character to fill any new elements. + * + * This function will %resize the %string to the specified + * number of characters. If the number is smaller than the + * %string's current size the %string is truncated, otherwise + * the %string is extended and new elements are set to @a c. + */ + void + resize(size_type __n, _CharT __c); + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * + * This function will resize the %string to the specified length. If + * the new size is smaller than the %string's current size the %string + * is truncated, otherwise the %string is extended and new characters + * are default-constructed. For basic types such as char, this means + * setting them to 0. + */ + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + + /** + * Returns the total number of characters that the %string can hold + * before needing to allocate more memory. + */ + size_type + capacity() const + { return _M_rep()->_M_capacity; } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * characters. + * @param res_arg Number of characters required. + * @throw std::length_error If @a res_arg exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %string to hold the specified number of characters. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the string length that will be + * required, the user can reserve the memory in %advance, and thus + * prevent a possible reallocation of memory and copying of %string + * data. + */ + void + reserve(size_type __res_arg = 0); + + /** + * Erases the string, making it empty. + */ + void + clear() + { _M_mutate(0, this->size(), 0); } + + /** + * Returns true if the %string is empty. Equivalent to *this == "". + */ + bool + empty() const + { return this->size() == 0; } + + // Element access: + /** + * @brief Subscript access to the data contained in the %string. + * @param pos The index of the character to access. + * @return Read-only (constant) reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[] (size_type __pos) const + { + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + return _M_data()[__pos]; + } + + /** + * @brief Subscript access to the data contained in the %string. + * @param pos The index of the character to access. + * @return Read/write reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) Unshares the string. + */ + reference + operator[](size_type __pos) + { + // allow pos == size() as v3 extension: + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + // but be strict in pedantic mode: + _GLIBCXX_DEBUG_PEDASSERT(__pos < size()); + _M_leak(); + return _M_data()[__pos]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read-only (const) reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("basic_string::at")); + return _M_data()[__n]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read/write reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. Success results in + * unsharing the string. + */ + reference + at(size_type __n) + { + if (__n >= size()) + __throw_out_of_range(__N("basic_string::at")); + _M_leak(); + return _M_data()[__n]; + } + + // Modifiers: + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const basic_string& __str) + { return this->append(__str); } + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const _CharT* __s) + { return this->append(__s); } + + /** + * @brief Append a character. + * @param c The character to append. + * @return Reference to this string. + */ + basic_string& + operator+=(_CharT __c) + { + this->push_back(__c); + return *this; + } + + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + basic_string& + append(const basic_string& __str); + + /** + * @brief Append a substring. + * @param str The string to append. + * @param pos Index of the first character of str to append. + * @param n The number of characters to append. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function appends @a n characters from @a str starting at @a pos + * to this string. If @a n is is larger than the number of available + * characters in @a str, the remainder of @a str is appended. + */ + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n); + + /** + * @brief Append a C substring. + * @param s The C string to append. + * @param n The number of characters to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s, size_type __n); + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->append(__s, traits_type::length(__s)); + } + + /** + * @brief Append multiple characters. + * @param n The number of characters to append. + * @param c The character to use. + * @return Reference to this string. + * + * Appends n copies of c to this string. + */ + basic_string& + append(size_type __n, _CharT __c); + + /** + * @brief Append a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Appends characters in the range [first,last) to this string. + */ + template<class _InputIterator> + basic_string& + append(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_iend(), _M_iend(), __first, __last); } + + /** + * @brief Append a single character. + * @param c Character to append. + */ + void + push_back(_CharT __c) + { + const size_type __len = 1 + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + traits_type::assign(_M_data()[this->size()], __c); + _M_rep()->_M_set_length_and_sharable(__len); + } + + /** + * @brief Set value to contents of another string. + * @param str Source string to use. + * @return Reference to this string. + */ + basic_string& + assign(const basic_string& __str); + + /** + * @brief Set value to a substring of a string. + * @param str The string to use. + * @param pos Index of the first character of str. + * @param n Number of characters to use. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function sets this string to the substring of @a str consisting + * of @a n characters at @a pos. If @a n is is larger than the number + * of available characters in @a str, the remainder of @a str is used. + */ + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { return this->assign(__str._M_data() + + __str._M_check(__pos, "basic_string::assign"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Set value to a C substring. + * @param s The C string to use. + * @param n Number of characters to use. + * @return Reference to this string. + * + * This function sets the value of this string to the first @a n + * characters of @a s. If @a n is is larger than the number of + * available characters in @a s, the remainder of @a s is used. + */ + basic_string& + assign(const _CharT* __s, size_type __n); + + /** + * @brief Set value to contents of a C string. + * @param s The C string to use. + * @return Reference to this string. + * + * This function sets the value of this string to the value of @a s. + * The data is copied, so there is no dependence on @a s once the + * function returns. + */ + basic_string& + assign(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->assign(__s, traits_type::length(__s)); + } + + /** + * @brief Set value to multiple characters. + * @param n Length of the resulting string. + * @param c The character to use. + * @return Reference to this string. + * + * This function sets the value of this string to @a n copies of + * character @a c. + */ + basic_string& + assign(size_type __n, _CharT __c) + { return _M_replace_aux(size_type(0), this->size(), __n, __c); } + + /** + * @brief Set value to a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Sets value of string to characters in the range [first,last). + */ + template<class _InputIterator> + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } + + /** + * @brief Insert multiple characters. + * @param p Iterator referencing location in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a n copies of character @a c starting at the position + * referenced by iterator @a p. If adding characters causes the length + * to exceed max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + void + insert(iterator __p, size_type __n, _CharT __c) + { this->replace(__p, __p, __n, __c); } + + /** + * @brief Insert a range of characters. + * @param p Iterator referencing location in string to insert at. + * @param beg Start of range. + * @param end End of range. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [beg,end). If adding characters causes + * the length to exceed max_size(), length_error is thrown. The value + * of the string doesn't change if an error is thrown. + */ + template<class _InputIterator> + void + insert(iterator __p, _InputIterator __beg, _InputIterator __end) + { this->replace(__p, __p, __beg, __end); } + + /** + * @brief Insert value of a string. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts value of @a str starting at @a pos1. If adding characters + * causes the length to exceed max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str) + { return this->insert(__pos1, __str, size_type(0), __str.size()); } + + /** + * @brief Insert a substring. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @param pos2 Start of characters in str to insert. + * @param n Number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos1 > size() or + * @a pos2 > @a str.size(). + * + * Starting at @a pos1, insert @a n character of @a str beginning with + * @a pos2. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a pos1 is beyond the end of + * this string or @a pos2 is beyond the end of @a str, out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { return this->insert(__pos1, __str._M_data() + + __str._M_check(__pos2, "basic_string::insert"), + __str._M_limit(__pos2, __n)); } + + /** + * @brief Insert a C substring. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @param n The number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n); + + /** + * @brief Insert a C string. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->insert(__pos, __s, traits_type::length(__s)); + } + + /** + * @brief Insert multiple characters. + * @param pos Index in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts @a n copies of character @a c starting at index @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos > length(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), + size_type(0), __n, __c); } + + /** + * @brief Insert one character. + * @param p Iterator referencing position in string to insert at. + * @param c The character to insert. + * @return Iterator referencing newly inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts character @a c at position referenced by @a p. If adding + * character causes the length to exceed max_size(), length_error is + * thrown. If @a p is beyond end of string, out_of_range is thrown. + * The value of the string doesn't change if an error is thrown. + */ + iterator + insert(iterator __p, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); + const size_type __pos = __p - _M_ibegin(); + _M_replace_aux(__pos, size_type(0), size_type(1), __c); + _M_rep()->_M_set_leaked(); + return iterator(_M_data() + __pos); + } + + /** + * @brief Remove characters. + * @param pos Index of first character to remove (default 0). + * @param n Number of characters to remove (default remainder). + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Removes @a n characters from this string starting at @a pos. The + * length of the string is reduced by @a n. If there are < @a n + * characters to remove, the remainder of the string is truncated. If + * @a p is beyond end of string, out_of_range is thrown. The value of + * the string doesn't change if an error is thrown. + */ + basic_string& + erase(size_type __pos = 0, size_type __n = npos) + { + _M_mutate(_M_check(__pos, "basic_string::erase"), + _M_limit(__pos, __n), size_type(0)); + return *this; + } + + /** + * @brief Remove one character. + * @param position Iterator referencing the character to remove. + * @return iterator referencing same location after removal. + * + * Removes the character at @a position from this string. The value + * of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __position) + { + _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() + && __position < _M_iend()); + const size_type __pos = __position - _M_ibegin(); + _M_mutate(__pos, size_type(1), size_type(0)); + _M_rep()->_M_set_leaked(); + return iterator(_M_data() + __pos); + } + + /** + * @brief Remove a range of characters. + * @param first Iterator referencing the first character to remove. + * @param last Iterator referencing the end of the range. + * @return Iterator referencing location of first after removal. + * + * Removes the characters in the range [first,last) from this string. + * The value of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __first, iterator __last) + { + _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last + && __last <= _M_iend()); + const size_type __pos = __first - _M_ibegin(); + _M_mutate(__pos, __last - __first, size_type(0)); + _M_rep()->_M_set_leaked(); + return iterator(_M_data() + __pos); + } + + /** + * @brief Replace characters with value from another string. + * @param pos Index of first character to replace. + * @param n Number of characters to be replaced. + * @param str String to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos+n) from this string. + * In place, the value of @a str is inserted. If @a pos is beyond end + * of string, out_of_range is thrown. If the length of the result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n, const basic_string& __str) + { return this->replace(__pos, __n, __str._M_data(), __str.size()); } + + /** + * @brief Replace characters with value from another string. + * @param pos1 Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str String to insert. + * @param pos2 Index of first character of str to use. + * @param n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size() or @a pos2 > + * str.size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos1,pos1 + n) from this + * string. In place, the value of @a str is inserted. If @a pos is + * beyond end of string, out_of_range is thrown. If the length of the + * result exceeds max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { return this->replace(__pos1, __n1, __str._M_data() + + __str._M_check(__pos2, "basic_string::replace"), + __str._M_limit(__pos2, __n2)); } + + /** + * @brief Replace characters with value of a C substring. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param s C string to insert. + * @param n2 Number of characters from @a s to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n2 characters of @a s are inserted, or all + * of @a s if @a n2 is too large. If @a pos is beyond end of string, + * out_of_range is thrown. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2); + + /** + * @brief Replace characters with value of a C string. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param s C string to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n characters of @a s are inserted. If @a + * pos is beyond end of string, out_of_range is thrown. If the length + * of result exceeds max_size(), length_error is thrown. The value of + * the string doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } + + /** + * @brief Replace characters with multiple characters. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param n2 Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, @a n2 copies of @a c are inserted. If @a pos is beyond + * end of string, out_of_range is thrown. If the length of result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), + _M_limit(__pos, __n1), __n2, __c); } + + /** + * @brief Replace range of characters with string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param str String value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the value of + * @a str is inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } + + /** + * @brief Replace range of characters with C substring. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @param n Number of characters from s to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the first @a + * n characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); + } + + /** + * @brief Replace range of characters with C string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the + * characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__i1, __i2, __s, traits_type::length(__s)); + } + + /** + * @brief Replace range of characters with multiple characters + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param n Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, @a n copies + * of @a c are inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); + } + + /** + * @brief Replace range of characters with range. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param k1 Iterator referencing start of range to insert. + * @param k2 Iterator referencing end of range to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, characters + * in the range [k1,k2) are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + template<class _InputIterator> + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); + } + + // Specializations for the common case of pointer and iterator: + // useful to avoid the overhead of temporary buffering in _M_replace. + basic_string& + replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, + const _CharT* __k1, const _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, + const_iterator __k1, const_iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + private: + template<class _Integer> + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n, + _Integer __val, __true_type) + { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } + + template<class _InputIterator> + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type); + + basic_string& + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c); + + basic_string& + _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, + size_type __n2); + + // _S_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIter is an integral type + template<class _InIterator> + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, __false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + return _S_construct(__beg, __end, __a, _Tag()); + } + + template<class _InIterator> + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, __true_type) + { return _S_construct(static_cast<size_type>(__beg), + static_cast<value_type>(__end), __a); } + + template<class _InIterator> + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + return _S_construct_aux(__beg, __end, __a, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template<class _InIterator> + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template<class _FwdIterator> + static _CharT* + _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, + forward_iterator_tag); + + static _CharT* + _S_construct(size_type __req, _CharT __c, const _Alloc& __a); + + public: + + /** + * @brief Copy substring into C string. + * @param s C string to copy value into. + * @param n Number of characters to copy. + * @param pos Index of first character to copy. + * @return Number of characters actually copied + * @throw std::out_of_range If pos > size(). + * + * Copies up to @a n characters starting at @a pos into the C string @a + * s. If @a pos is greater than size(), out_of_range is thrown. + */ + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + + /** + * @brief Swap contents with another string. + * @param s String to swap with. + * + * Exchanges the contents of this string with that of @a s in constant + * time. + */ + void + swap(basic_string& __s); + + // String operations: + /** + * @brief Return const pointer to null-terminated contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + c_str() const + { return _M_data(); } + + /** + * @brief Return const pointer to contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + data() const + { return _M_data(); } + + /** + * @brief Return copy of allocator used to construct this string. + */ + allocator_type + get_allocator() const + { return _M_dataplus; } + + /** + * @brief Find position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search from. + * @param n Number of characters from @a s to search for. + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the first @a n characters + * in @a s within this string. If found, returns the index where it + * begins. If not found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a string. + * @param str String to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const basic_string& __str, size_type __pos = 0) const + { return this->find(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a C string. + * @param s C string to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a string. + * @param str String to locate. + * @param pos Index of character to search back from (default end). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const basic_string& __str, size_type __pos = npos) const + { return this->rfind(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search back from. + * @param n Number of characters from s to search for. + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the first @a n + * characters in @a s within this string. If found, returns the index + * where it begins. If not found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a C string. + * @param s C string to locate. + * @param pos Index of character to start search at (default end). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->rfind(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + rfind(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Find position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + { return this->find_first_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character of C substring. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to search for. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a character of C string. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for the character @a c within + * this string. If found, returns the index where it was found. If + * not found, returns npos. + * + * Note: equivalent to find(c, pos). + */ + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return this->find(__c, __pos); } + + /** + * @brief Find last position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const basic_string& __str, size_type __pos = npos) const + { return this->find_last_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character of C substring. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @param n Number of characters from s to search for. + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a character of C string. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default 0). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + * + * Note: equivalent to rfind(c, pos). + */ + size_type + find_last_of(_CharT __c, size_type __pos = npos) const + { return this->rfind(__c, __pos); } + + /** + * @brief Find position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a str within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + { return this->find_first_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in the first @a n characters of @a s within this string. If found, + * returns the index where it was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a s within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character other than @a c + * within this string. If found, returns the index where it was found. + * If not found, returns npos. + */ + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a str within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const basic_string& __str, size_type __pos = npos) const + { return this->find_last_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in the first @a n characters of @a s within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character other than + * @a c within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Get a substring. + * @param pos Index of first character (default 0). + * @param n Number of characters in substring (default remainder). + * @return The new string. + * @throw std::out_of_range If pos > size(). + * + * Construct and return a new string using the @a n characters starting + * at @a pos. If the string is too short, use the remainder of the + * characters. If @a pos is beyond the end of the string, out_of_range + * is thrown. + */ + basic_string + substr(size_type __pos = 0, size_type __n = npos) const + { return basic_string(*this, + _M_check(__pos, "basic_string::substr"), __n); } + + /** + * @brief Compare to a string. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a str, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a str. Determines the effective length rlen of the strings to + * compare as the smallest of size() and str.size(). The function + * then compares the two strings by calling traits::compare(data(), + * str.data(),rlen). If the result of the comparison is nonzero returns + * it, otherwise the shorter one is ordered first. + */ + int + compare(const basic_string& __str) const + { + const size_type __size = this->size(); + const size_type __osize = __str.size(); + const size_type __len = std::min(__size, __osize); + + int __r = traits_type::compare(_M_data(), __str.data(), __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + /** + * @brief Compare substring to a string. + * @param pos Index of first character of substring. + * @param n Number of characters in substring. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a str, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a str. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and @a str.size(). The function then compares the two + * strings by calling traits::compare(substring.data(),str.data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos, size_type __n, const basic_string& __str) const; + + /** + * @brief Compare substring to a substring. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param str String to compare against. + * @param pos2 Index of first character of substring of str. + * @param n2 Number of characters in substring of str. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form the substring of @a str from the @a n2 characters + * starting at @a pos2. Returns an integer < 0 if this substring is + * ordered before the substring of @a str, 0 if their values are + * equivalent, or > 0 if this substring is ordered after the substring + * of @a str. Determines the effective length rlen of the strings + * to compare as the smallest of the lengths of the substrings. The + * function then compares the two strings by calling + * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const; + + /** + * @brief Compare to a C string. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a s, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a s. Determines the effective length rlen of the strings to + * compare as the smallest of size() and the length of a string + * constructed from @a s. The function then compares the two strings + * by calling traits::compare(data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(const _CharT* __s) const; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5 String::compare specification questionable + /** + * @brief Compare substring to a C string. + * @param pos Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a s, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a s. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and the length of a string constructed from @a s. The + * function then compares the two string by calling + * traits::compare(substring.data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s) const; + + /** + * @brief Compare substring against a character array. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s character array to compare against. + * @param n2 Number of characters of s. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form a string from the first @a n2 characters of @a s. + * Returns an integer < 0 if this substring is ordered before the string + * from @a s, 0 if their values are equivalent, or > 0 if this substring + * is ordered after the string from @a s. Determines the effective + * length rlen of the strings to compare as the smallest of the length + * of the substring and @a n2. The function then compares the two + * strings by calling traits::compare(substring.data(),s,rlen). If the + * result of the comparison is nonzero returns it, otherwise the shorter + * one is ordered first. + * + * NB: s must have at least n2 characters, '\0' has no special + * meaning. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const; + }; + + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_string<_CharT, _Traits, _Alloc>:: + basic_string() +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { } +#else + : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { } +#endif + + // operator+ + /** + * @brief Concatenate two strings. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + /** + * @brief Concatenate C string and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + /** + * @brief Concatenate character and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc> + operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + /** + * @brief Concatenate string and C string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + /** + * @brief Concatenate string and character. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str(__lhs); + __str.append(__size_type(1), __rhs); + return __str; + } + + // operator == + /** + * @brief Test equivalence of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) == 0; } + + /** + * @brief Test equivalence of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) == 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) == 0; } + + /** + * @brief Test equivalence of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) == 0; } + + // operator != + /** + * @brief Test difference of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) != 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) != 0; } + + // operator < + /** + * @brief Test if string precedes string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if string precedes C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if C string precedes string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) > 0; } + + // operator > + /** + * @brief Test if string follows string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if string follows C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if C string follows string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) < 0; } + + // operator <= + /** + * @brief Test if string doesn't follow string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if string doesn't follow C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if C string doesn't follow string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) >= 0; } + + // operator >= + /** + * @brief Test if string doesn't precede string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if string doesn't precede C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if C string doesn't precede string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) <= 0; } + + /** + * @brief Swap contents of two strings. + * @param lhs First string. + * @param rhs Second string. + * + * Exchanges the contents of @a lhs and @a rhs in constant time. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline void + swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, + basic_string<_CharT, _Traits, _Alloc>& __rhs) + { __lhs.swap(__rhs); } + + /** + * @brief Read stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until whitespace is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str); + + template<> + basic_istream<char>& + operator>>(basic_istream<char>& __is, basic_string<char>& __str); + + /** + * @brief Write string to a stream. + * @param os Output stream. + * @param str String to write out. + * @return Reference to the output stream. + * + * Output characters of @a str into os following the same rules as for + * writing a C string. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT, _Traits, _Alloc>& __str) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 586. string inserter not a formatted function + return __ostream_insert(__os, __str.data(), __str.size()); + } + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @param delim Character marking end of line. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until @a delim is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. If @a + * delim was encountered, it is extracted but not stored into @a str. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim); + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from is into @a str until '\n' is found, the end of + * the stream is encountered, or str.max_size() is reached. If is.width() + * is non-zero, that is the limit on the number of characters stored into + * @a str. Any previous contents of @a str are erased. If end of line was + * encountered, it is extracted but not stored into @a str. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str) + { return getline(__is, __str, __is.widen('\n')); } + + template<> + basic_istream<char>& + getline(basic_istream<char>& __in, basic_string<char>& __str, + char __delim); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + basic_istream<wchar_t>& + getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str, + wchar_t __delim); +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _BASIC_STRING_H */ diff --git a/libstdc++/include/bits/basic_string.tcc b/libstdc++/include/bits/basic_string.tcc new file mode 100644 index 0000000..c2798ef --- /dev/null +++ b/libstdc++/include/bits/basic_string.tcc @@ -0,0 +1,1012 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, +// 2006, 2007 +// 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. + +/** @file basic_string.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 21 Strings library +// + +// Written by Jason Merrill based upon the specification by Takanori Adachi +// in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. + +#ifndef _BASIC_STRING_TCC +#define _BASIC_STRING_TCC 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _Type> + inline bool + __is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template<typename _Type> + inline bool + __is_null_pointer(_Type) + { return false; } + + template<typename _CharT, typename _Traits, typename _Alloc> + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; + + template<typename _CharT, typename _Traits, typename _Alloc> + const _CharT + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_terminal = _CharT(); + + template<typename _CharT, typename _Traits, typename _Alloc> + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::npos; + + // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) + // at static init time (before static ctors are run). + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ + (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / + sizeof(size_type)]; + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + input_iterator_tag) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); +#endif + // Avoid reallocation for common case. + _CharT __buf[128]; + size_type __len = 0; + while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) + { + __buf[__len++] = *__beg; + ++__beg; + } + _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); + _M_copy(__r->_M_refdata(), __buf, __len); + try + { + while (__beg != __end) + { + if (__len == __r->_M_capacity) + { + // Allocate more space. + _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); + _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len); + __r->_M_destroy(__a); + __r = __another; + } + __r->_M_refdata()[__len++] = *__beg; + ++__beg; + } + } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_set_length_and_sharable(__len); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template <typename _InIterator> + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + forward_iterator_tag) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); +#endif + // NB: Not required, but considered best practice. + if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0)) + __throw_logic_error(__N("basic_string::_S_construct NULL not valid")); + + const size_type __dnew = static_cast<size_type>(std::distance(__beg, + __end)); + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); + try + { _S_copy_chars(__r->_M_refdata(), __beg, __end); } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_set_length_and_sharable(__dnew); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(size_type __n, _CharT __c, const _Alloc& __a) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__n == 0 && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); +#endif + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); + if (__n) + _M_assign(__r->_M_refdata(), __n, __c); + + __r->_M_set_length_and_sharable(__n); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str) + : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), + __str.get_allocator()), + __str.get_allocator()) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _Alloc& __a) + : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, size_type __n) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, _Alloc()), _Alloc()) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, __a), __a) + { } + + // TBD: DPG annotate + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) + { } + + // TBD: DPG annotate + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : + __s + npos, __a), __a) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(size_type __n, _CharT __c, const _Alloc& __a) + : _M_dataplus(_S_construct(__n, __c, __a), __a) + { } + + // TBD: DPG annotate + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InputIterator> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) + : _M_dataplus(_S_construct(__beg, __end, __a), __a) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + assign(const basic_string& __str) + { + if (_M_rep() != __str._M_rep()) + { + // XXX MT + const allocator_type __a = this->get_allocator(); + _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + assign(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check_length(this->size(), __n, "basic_string::assign"); + if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) + return _M_replace_safe(size_type(0), this->size(), __s, __n); + else + { + // Work in-place. + const size_type __pos = __s - _M_data(); + if (__pos >= __n) + _M_copy(_M_data(), __s, __n); + else if (__pos) + _M_move(_M_data(), __s, __n); + _M_rep()->_M_set_length_and_sharable(__n); + return *this; + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(size_type __n, _CharT __c) + { + if (__n) + { + _M_check_length(size_type(0), __n, "basic_string::append"); + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_assign(_M_data() + this->size(), __n, __c); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + if (__n) + { + _M_check_length(size_type(0), __n, "basic_string::append"); + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + { + if (_M_disjunct(__s)) + this->reserve(__len); + else + { + const size_type __off = __s - _M_data(); + this->reserve(__len); + __s = _M_data() + __off; + } + } + _M_copy(_M_data() + this->size(), __s, __n); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str) + { + const size_type __size = __str.size(); + if (__size) + { + const size_type __len = __size + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_copy(_M_data() + this->size(), __str._M_data(), __size); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str, size_type __pos, size_type __n) + { + __str._M_check(__pos, "basic_string::append"); + __n = __str._M_limit(__pos, __n); + if (__n) + { + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + insert(size_type __pos, const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check(__pos, "basic_string::insert"); + _M_check_length(size_type(0), __n, "basic_string::insert"); + if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) + return _M_replace_safe(__pos, size_type(0), __s, __n); + else + { + // Work in-place. + const size_type __off = __s - _M_data(); + _M_mutate(__pos, 0, __n); + __s = _M_data() + __off; + _CharT* __p = _M_data() + __pos; + if (__s + __n <= __p) + _M_copy(__p, __s, __n); + else if (__s >= __p) + _M_copy(__p, __s + __n, __n); + else + { + const size_type __nleft = __p - __s; + _M_copy(__p, __s, __nleft); + _M_copy(__p + __nleft, __p + __n, __n - __nleft); + } + return *this; + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "basic_string::replace"); + __n1 = _M_limit(__pos, __n1); + _M_check_length(__n1, __n2, "basic_string::replace"); + bool __left; + if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) + return _M_replace_safe(__pos, __n1, __s, __n2); + else if ((__left = __s + __n2 <= _M_data() + __pos) + || _M_data() + __pos + __n1 <= __s) + { + // Work in-place: non-overlapping case. + size_type __off = __s - _M_data(); + __left ? __off : (__off += __n2 - __n1); + _M_mutate(__pos, __n1, __n2); + _M_copy(_M_data() + __pos, _M_data() + __off, __n2); + return *this; + } + else + { + // Todo: overlapping case. + const basic_string __tmp(__s, __n2); + return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_destroy(const _Alloc& __a) throw () + { + const size_type __size = sizeof(_Rep_base) + + (this->_M_capacity + 1) * sizeof(_CharT); + _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_leak_hard() + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (_M_rep() == &_S_empty_rep()) + return; +#endif + if (_M_rep()->_M_is_shared()) + _M_mutate(0, 0, 0); + _M_rep()->_M_set_leaked(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, size_type __len2) + { + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __len2 - __len1; + const size_type __how_much = __old_size - __pos - __len1; + + if (__new_size > this->capacity() || _M_rep()->_M_is_shared()) + { + // Must reallocate. + const allocator_type __a = get_allocator(); + _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); + + if (__pos) + _M_copy(__r->_M_refdata(), _M_data(), __pos); + if (__how_much) + _M_copy(__r->_M_refdata() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_rep()->_M_dispose(__a); + _M_data(__r->_M_refdata()); + } + else if (__how_much && __len1 != __len2) + { + // Work in-place. + _M_move(_M_data() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + } + _M_rep()->_M_set_length_and_sharable(__new_size); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + reserve(size_type __res) + { + if (__res != this->capacity() || _M_rep()->_M_is_shared()) + { + // Make sure we don't shrink below the current size + if (__res < this->size()) + __res = this->size(); + const allocator_type __a = get_allocator(); + _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + swap(basic_string& __s) + { + if (_M_rep()->_M_is_leaked()) + _M_rep()->_M_set_sharable(); + if (__s._M_rep()->_M_is_leaked()) + __s._M_rep()->_M_set_sharable(); + if (this->get_allocator() == __s.get_allocator()) + { + _CharT* __tmp = _M_data(); + _M_data(__s._M_data()); + __s._M_data(__tmp); + } + // The code below can usually be optimized away. + else + { + const basic_string __tmp1(_M_ibegin(), _M_iend(), + __s.get_allocator()); + const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), + this->get_allocator()); + *this = __tmp2; + __s = __tmp1; + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::_Rep* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _S_create(size_type __capacity, size_type __old_capacity, + const _Alloc& __alloc) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + if (__capacity > _S_max_size) + __throw_length_error(__N("basic_string::_S_create")); + + // The standard places no restriction on allocating more memory + // than is strictly needed within this layer at the moment or as + // requested by an explicit application call to reserve(). + + // Many malloc implementations perform quite poorly when an + // application attempts to allocate memory in a stepwise fashion + // growing each allocation size by only 1 char. Additionally, + // it makes little sense to allocate less linear memory than the + // natural blocking size of the malloc implementation. + // Unfortunately, we would need a somewhat low-level calculation + // with tuned parameters to get this perfect for any particular + // malloc implementation. Fortunately, generalizations about + // common features seen among implementations seems to suffice. + + // __pagesize need not match the actual VM page size for good + // results in practice, thus we pick a common value on the low + // side. __malloc_header_size is an estimate of the amount of + // overhead per memory allocation (in practice seen N * sizeof + // (void*) where N is 0, 2 or 4). According to folklore, + // picking this value on the high side is better than + // low-balling it (especially when this algorithm is used with + // malloc implementations that allocate memory blocks rounded up + // to a size which is a power of 2). + const size_type __pagesize = 4096; + const size_type __malloc_header_size = 4 * sizeof(void*); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + // It's active for allocations requiring an amount of memory above + // system pagesize. This is consistent with the requirements of the + // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) + __capacity = 2 * __old_capacity; + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element, plus enough for the _Rep data structure. + // Whew. Seemingly so needy, yet so elemental. + size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + + const size_type __adj_size = __size + __malloc_header_size; + if (__adj_size > __pagesize && __capacity > __old_capacity) + { + const size_type __extra = __pagesize - __adj_size % __pagesize; + __capacity += __extra / sizeof(_CharT); + // Never allocate a string bigger than _S_max_size. + if (__capacity > _S_max_size) + __capacity = _S_max_size; + __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + } + + // NB: Might throw, but no worries about a leak, mate: _Rep() + // does not throw. + void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); + _Rep *__p = new (__place) _Rep; + __p->_M_capacity = __capacity; + // ABI compatibility - 3.4.x set in _S_create both + // _M_refcount and _M_length. All callers of _S_create + // in basic_string.tcc then set just _M_length. + // In 4.0.x and later both _M_refcount and _M_length + // are initialized in the callers, unfortunately we can + // have 3.4.x compiled code with _S_create callers inlined + // calling 4.0.x+ _S_create. + __p->_M_set_sharable(); + return __p; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_clone(const _Alloc& __alloc, size_type __res) + { + // Requested capacity of the clone. + const size_type __requested_cap = this->_M_length + __res; + _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, + __alloc); + if (this->_M_length) + _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length); + + __r->_M_set_length_and_sharable(this->_M_length); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + resize(size_type __n, _CharT __c) + { + const size_type __size = this->size(); + _M_check_length(__size, __n, "basic_string::resize"); + if (__size < __n) + this->append(__n - __size, __c); + else if (__n < __size) + this->erase(__n); + // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InputIterator> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type) + { + const basic_string __s(__k1, __k2); + const size_type __n1 = __i2 - __i1; + _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch"); + return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), + __s.size()); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c) + { + _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); + _M_mutate(__pos1, __n1, __n2); + if (__n2) + _M_assign(_M_data() + __pos1, __n2, __c); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, + size_type __n2) + { + _M_mutate(__pos1, __n1, __n2); + if (__n2) + _M_copy(_M_data() + __pos1, __s, __n2); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + __glibcxx_requires_string(__lhs); + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + const __size_type __len = _Traits::length(__lhs); + __string_type __str; + __str.reserve(__len + __rhs.size()); + __str.append(__lhs, __len); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc> + operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str; + const __size_type __len = __rhs.size(); + __str.reserve(__len + 1); + __str.append(__size_type(1), __lhs); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "basic_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + _M_copy(__s, _M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + const _CharT* __data = _M_data(); + + if (__n == 0) + return __pos <= __size ? __pos : npos; + + if (__n <= __size) + { + for (; __pos <= __size - __n; ++__pos) + if (traits_type::eq(__data[__pos], __s[0]) + && traits_type::compare(__data + __pos + 1, + __s + 1, __n - 1) == 0) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(_CharT __c, size_type __pos) const + { + size_type __ret = npos; + const size_type __size = this->size(); + if (__pos < __size) + { + const _CharT* __data = _M_data(); + const size_type __n = __size - __pos; + const _CharT* __p = traits_type::find(__data + __pos, __n, __c); + if (__p) + __ret = __p - __data; + } + return __ret; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + if (__n <= __size) + { + __pos = std::min(size_type(__size - __n), __pos); + const _CharT* __data = _M_data(); + do + { + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(_M_data()[__size], __c)) + return __size; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __n && __pos < this->size(); ++__pos) + { + const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); + if (__p) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (traits_type::find(__s, __n, _M_data()[__size])) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __pos < this->size(); ++__pos) + if (!traits_type::find(__s, __n, _M_data()[__pos])) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_not_of(_CharT __c, size_type __pos) const + { + for (; __pos < this->size(); ++__pos) + if (!traits_type::eq(_M_data()[__pos], __c)) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::find(__s, __n, _M_data()[__size])) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_not_of(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(_M_data()[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n, const basic_string& __str) const + { + _M_check(__pos, "basic_string::compare"); + __n = _M_limit(__pos, __n); + const size_type __osize = __str.size(); + const size_type __len = std::min(__n, __osize); + int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); + if (!__r) + __r = __n - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { + _M_check(__pos1, "basic_string::compare"); + __str._M_check(__pos2, "basic_string::compare"); + __n1 = _M_limit(__pos1, __n1); + __n2 = __str._M_limit(__pos2, __n2); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(_M_data() + __pos1, + __str.data() + __pos2, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(const _CharT* __s) const + { + __glibcxx_requires_string(__s); + const size_type __size = this->size(); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__size, __osize); + int __r = traits_type::compare(_M_data(), __s, __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + int + basic_string <_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n1, const _CharT* __s) const + { + __glibcxx_requires_string(__s); + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__n1, __osize); + int __r = traits_type::compare(_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + int + basic_string <_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const + { + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_string<char>; + extern template + basic_istream<char>& + operator>>(basic_istream<char>&, string&); + extern template + basic_ostream<char>& + operator<<(basic_ostream<char>&, const string&); + extern template + basic_istream<char>& + getline(basic_istream<char>&, string&, char); + extern template + basic_istream<char>& + getline(basic_istream<char>&, string&); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_string<wchar_t>; + extern template + basic_istream<wchar_t>& + operator>>(basic_istream<wchar_t>&, wstring&); + extern template + basic_ostream<wchar_t>& + operator<<(basic_ostream<wchar_t>&, const wstring&); + extern template + basic_istream<wchar_t>& + getline(basic_istream<wchar_t>&, wstring&, wchar_t); + extern template + basic_istream<wchar_t>& + getline(basic_istream<wchar_t>&, wstring&); +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/boost_concept_check.h b/libstdc++/include/bits/boost_concept_check.h new file mode 100644 index 0000000..3d8fe75 --- /dev/null +++ b/libstdc++/include/bits/boost_concept_check.h @@ -0,0 +1,933 @@ +// -*- C++ -*- + +// 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. + +// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// + +/** @file boost_concept_check.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// GCC Note: based on version 1.12.0 of the Boost library. + +#ifndef _BOOST_CONCEPT_CHECK_H +#define _BOOST_CONCEPT_CHECK_H 1 + +#pragma GCC system_header + +#include <cstddef> // for ptrdiff_t, used next +#include <bits/stl_iterator_base_types.h> // for traits and tags +#include <utility> // for pair<> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +#define _IsUnused __attribute__ ((__unused__)) + +// When the C-C code is in use, we would like this function to do as little +// as possible at runtime, use as few resources as possible, and hopefully +// be elided out of existence... hmmm. +template <class _Concept> +inline void __function_requires() +{ + void (_Concept::*__x)() _IsUnused = &_Concept::__constraints; +} + +// No definition: if this is referenced, there's a problem with +// the instantiating type not being one of the required integer types. +// Unfortunately, this results in a link-time error, not a compile-time error. +void __error_type_must_be_an_integer_type(); +void __error_type_must_be_an_unsigned_integer_type(); +void __error_type_must_be_a_signed_integer_type(); + +// ??? Should the "concept_checking*" structs begin with more than _ ? +#define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \ + typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \ + template <_func##_type_var##_concept _Tp1> \ + struct _concept_checking##_type_var##_concept { }; \ + typedef _concept_checking##_type_var##_concept< \ + &_ns::_concept <_type_var>::__constraints> \ + _concept_checking_typedef##_type_var##_concept + +#define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \ + typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \ + template <_func##_type_var1##_type_var2##_concept _Tp1> \ + struct _concept_checking##_type_var1##_type_var2##_concept { }; \ + typedef _concept_checking##_type_var1##_type_var2##_concept< \ + &_ns::_concept <_type_var1,_type_var2>::__constraints> \ + _concept_checking_typedef##_type_var1##_type_var2##_concept + +#define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \ + typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \ + template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \ + struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \ + typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \ + &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \ + _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept + +#define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \ + typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \ + template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \ + struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \ + typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \ + &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \ + _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept + + +template <class _Tp1, class _Tp2> +struct _Aux_require_same { }; + +template <class _Tp> +struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; + + template <class _Tp1, class _Tp2> + struct _SameTypeConcept + { + void __constraints() { + typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required; + } + }; + + template <class _Tp> + struct _IntegerConcept { + void __constraints() { + __error_type_must_be_an_integer_type(); + } + }; + template <> struct _IntegerConcept<short> { void __constraints() {} }; + template <> struct _IntegerConcept<unsigned short> { void __constraints(){} }; + template <> struct _IntegerConcept<int> { void __constraints() {} }; + template <> struct _IntegerConcept<unsigned int> { void __constraints() {} }; + template <> struct _IntegerConcept<long> { void __constraints() {} }; + template <> struct _IntegerConcept<unsigned long> { void __constraints() {} }; + template <> struct _IntegerConcept<long long> { void __constraints() {} }; + template <> struct _IntegerConcept<unsigned long long> + { void __constraints() {} }; + + template <class _Tp> + struct _SignedIntegerConcept { + void __constraints() { + __error_type_must_be_a_signed_integer_type(); + } + }; + template <> struct _SignedIntegerConcept<short> { void __constraints() {} }; + template <> struct _SignedIntegerConcept<int> { void __constraints() {} }; + template <> struct _SignedIntegerConcept<long> { void __constraints() {} }; + template <> struct _SignedIntegerConcept<long long> { void __constraints(){}}; + + template <class _Tp> + struct _UnsignedIntegerConcept { + void __constraints() { + __error_type_must_be_an_unsigned_integer_type(); + } + }; + template <> struct _UnsignedIntegerConcept<unsigned short> + { void __constraints() {} }; + template <> struct _UnsignedIntegerConcept<unsigned int> + { void __constraints() {} }; + template <> struct _UnsignedIntegerConcept<unsigned long> + { void __constraints() {} }; + template <> struct _UnsignedIntegerConcept<unsigned long long> + { void __constraints() {} }; + + //=========================================================================== + // Basic Concepts + + template <class _Tp> + struct _DefaultConstructibleConcept + { + void __constraints() { + _Tp __a _IsUnused; // require default constructor + } + }; + + template <class _Tp> + struct _AssignableConcept + { + void __constraints() { + __a = __a; // require assignment operator + __const_constraints(__a); + } + void __const_constraints(const _Tp& __b) { + __a = __b; // const required for argument to assignment + } + _Tp __a; + // possibly should be "Tp* a;" and then dereference "a" in constraint + // functions? present way would require a default ctor, i think... + }; + + template <class _Tp> + struct _CopyConstructibleConcept + { + void __constraints() { + _Tp __a(__b); // require copy constructor + _Tp* __ptr _IsUnused = &__a; // require address of operator + __const_constraints(__a); + } + void __const_constraints(const _Tp& __a) { + _Tp __c _IsUnused(__a); // require const copy constructor + const _Tp* __ptr _IsUnused = &__a; // require const address of operator + } + _Tp __b; + }; + + // The SGI STL version of Assignable requires copy constructor and operator= + template <class _Tp> + struct _SGIAssignableConcept + { + void __constraints() { + _Tp __b _IsUnused(__a); + __a = __a; // require assignment operator + __const_constraints(__a); + } + void __const_constraints(const _Tp& __b) { + _Tp __c _IsUnused(__b); + __a = __b; // const required for argument to assignment + } + _Tp __a; + }; + + template <class _From, class _To> + struct _ConvertibleConcept + { + void __constraints() { + _To __y _IsUnused = __x; + } + _From __x; + }; + + // The C++ standard requirements for many concepts talk about return + // types that must be "convertible to bool". The problem with this + // requirement is that it leaves the door open for evil proxies that + // define things like operator|| with strange return types. Two + // possible solutions are: + // 1) require the return type to be exactly bool + // 2) stay with convertible to bool, and also + // specify stuff about all the logical operators. + // For now we just test for convertible to bool. + template <class _Tp> + void __aux_require_boolean_expr(const _Tp& __t) { + bool __x _IsUnused = __t; + } + +// FIXME + template <class _Tp> + struct _EqualityComparableConcept + { + void __constraints() { + __aux_require_boolean_expr(__a == __b); + } + _Tp __a, __b; + }; + + template <class _Tp> + struct _LessThanComparableConcept + { + void __constraints() { + __aux_require_boolean_expr(__a < __b); + } + _Tp __a, __b; + }; + + // This is equivalent to SGI STL's LessThanComparable. + template <class _Tp> + struct _ComparableConcept + { + void __constraints() { + __aux_require_boolean_expr(__a < __b); + __aux_require_boolean_expr(__a > __b); + __aux_require_boolean_expr(__a <= __b); + __aux_require_boolean_expr(__a >= __b); + } + _Tp __a, __b; + }; + +#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \ + template <class _First, class _Second> \ + struct _NAME { \ + void __constraints() { (void)__constraints_(); } \ + bool __constraints_() { \ + return __a _OP __b; \ + } \ + _First __a; \ + _Second __b; \ + } + +#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ + template <class _Ret, class _First, class _Second> \ + struct _NAME { \ + void __constraints() { (void)__constraints_(); } \ + _Ret __constraints_() { \ + return __a _OP __b; \ + } \ + _First __a; \ + _Second __b; \ + } + + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept); + + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept); + +#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT +#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT + + //=========================================================================== + // Function Object Concepts + + template <class _Func, class _Return> + struct _GeneratorConcept + { + void __constraints() { + const _Return& __r _IsUnused = __f();// require operator() member function + } + _Func __f; + }; + + + template <class _Func> + struct _GeneratorConcept<_Func,void> + { + void __constraints() { + __f(); // require operator() member function + } + _Func __f; + }; + + template <class _Func, class _Return, class _Arg> + struct _UnaryFunctionConcept + { + void __constraints() { + __r = __f(__arg); // require operator() + } + _Func __f; + _Arg __arg; + _Return __r; + }; + + template <class _Func, class _Arg> + struct _UnaryFunctionConcept<_Func, void, _Arg> { + void __constraints() { + __f(__arg); // require operator() + } + _Func __f; + _Arg __arg; + }; + + template <class _Func, class _Return, class _First, class _Second> + struct _BinaryFunctionConcept + { + void __constraints() { + __r = __f(__first, __second); // require operator() + } + _Func __f; + _First __first; + _Second __second; + _Return __r; + }; + + template <class _Func, class _First, class _Second> + struct _BinaryFunctionConcept<_Func, void, _First, _Second> + { + void __constraints() { + __f(__first, __second); // require operator() + } + _Func __f; + _First __first; + _Second __second; + }; + + template <class _Func, class _Arg> + struct _UnaryPredicateConcept + { + void __constraints() { + __aux_require_boolean_expr(__f(__arg)); // require op() returning bool + } + _Func __f; + _Arg __arg; + }; + + template <class _Func, class _First, class _Second> + struct _BinaryPredicateConcept + { + void __constraints() { + __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool + } + _Func __f; + _First __a; + _Second __b; + }; + + // use this when functor is used inside a container class like std::set + template <class _Func, class _First, class _Second> + struct _Const_BinaryPredicateConcept { + void __constraints() { + __const_constraints(__f); + } + void __const_constraints(const _Func& __fun) { + __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >(); + // operator() must be a const member function + __aux_require_boolean_expr(__fun(__a, __b)); + } + _Func __f; + _First __a; + _Second __b; + }; + + //=========================================================================== + // Iterator Concepts + + template <class _Tp> + struct _TrivialIteratorConcept + { + void __constraints() { +// __function_requires< _DefaultConstructibleConcept<_Tp> >(); + __function_requires< _AssignableConcept<_Tp> >(); + __function_requires< _EqualityComparableConcept<_Tp> >(); +// typedef typename std::iterator_traits<_Tp>::value_type _V; + (void)*__i; // require dereference operator + } + _Tp __i; + }; + + template <class _Tp> + struct _Mutable_TrivialIteratorConcept + { + void __constraints() { + __function_requires< _TrivialIteratorConcept<_Tp> >(); + *__i = *__j; // require dereference and assignment + } + _Tp __i, __j; + }; + + template <class _Tp> + struct _InputIteratorConcept + { + void __constraints() { + __function_requires< _TrivialIteratorConcept<_Tp> >(); + // require iterator_traits typedef's + typedef typename std::iterator_traits<_Tp>::difference_type _Diff; +// __function_requires< _SignedIntegerConcept<_Diff> >(); + typedef typename std::iterator_traits<_Tp>::reference _Ref; + typedef typename std::iterator_traits<_Tp>::pointer _Pt; + typedef typename std::iterator_traits<_Tp>::iterator_category _Cat; + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::input_iterator_tag> >(); + ++__i; // require preincrement operator + __i++; // require postincrement operator + } + _Tp __i; + }; + + template <class _Tp, class _ValueT> + struct _OutputIteratorConcept + { + void __constraints() { + __function_requires< _AssignableConcept<_Tp> >(); + ++__i; // require preincrement operator + __i++; // require postincrement operator + *__i++ = __t; // require postincrement and assignment + } + _Tp __i; + _ValueT __t; + }; + + template <class _Tp> + struct _ForwardIteratorConcept + { + void __constraints() { + __function_requires< _InputIteratorConcept<_Tp> >(); + __function_requires< _DefaultConstructibleConcept<_Tp> >(); + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::forward_iterator_tag> >(); + typedef typename std::iterator_traits<_Tp>::reference _Ref; + _Ref __r _IsUnused = *__i; + } + _Tp __i; + }; + + template <class _Tp> + struct _Mutable_ForwardIteratorConcept + { + void __constraints() { + __function_requires< _ForwardIteratorConcept<_Tp> >(); + *__i++ = *__i; // require postincrement and assignment + } + _Tp __i; + }; + + template <class _Tp> + struct _BidirectionalIteratorConcept + { + void __constraints() { + __function_requires< _ForwardIteratorConcept<_Tp> >(); + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::bidirectional_iterator_tag> >(); + --__i; // require predecrement operator + __i--; // require postdecrement operator + } + _Tp __i; + }; + + template <class _Tp> + struct _Mutable_BidirectionalIteratorConcept + { + void __constraints() { + __function_requires< _BidirectionalIteratorConcept<_Tp> >(); + __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >(); + *__i-- = *__i; // require postdecrement and assignment + } + _Tp __i; + }; + + + template <class _Tp> + struct _RandomAccessIteratorConcept + { + void __constraints() { + __function_requires< _BidirectionalIteratorConcept<_Tp> >(); + __function_requires< _ComparableConcept<_Tp> >(); + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::random_access_iterator_tag> >(); + // ??? We don't use _Ref, are we just checking for "referenceability"? + typedef typename std::iterator_traits<_Tp>::reference _Ref; + + __i += __n; // require assignment addition operator + __i = __i + __n; __i = __n + __i; // require addition with difference type + __i -= __n; // require assignment subtraction op + __i = __i - __n; // require subtraction with + // difference type + __n = __i - __j; // require difference operator + (void)__i[__n]; // require element access operator + } + _Tp __a, __b; + _Tp __i, __j; + typename std::iterator_traits<_Tp>::difference_type __n; + }; + + template <class _Tp> + struct _Mutable_RandomAccessIteratorConcept + { + void __constraints() { + __function_requires< _RandomAccessIteratorConcept<_Tp> >(); + __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >(); + __i[__n] = *__i; // require element access and assignment + } + _Tp __i; + typename std::iterator_traits<_Tp>::difference_type __n; + }; + + //=========================================================================== + // Container Concepts + + template <class _Container> + struct _ContainerConcept + { + typedef typename _Container::value_type _Value_type; + typedef typename _Container::difference_type _Difference_type; + typedef typename _Container::size_type _Size_type; + typedef typename _Container::const_reference _Const_reference; + typedef typename _Container::const_pointer _Const_pointer; + typedef typename _Container::const_iterator _Const_iterator; + + void __constraints() { + __function_requires< _InputIteratorConcept<_Const_iterator> >(); + __function_requires< _AssignableConcept<_Container> >(); + const _Container __c; + __i = __c.begin(); + __i = __c.end(); + __n = __c.size(); + __n = __c.max_size(); + __b = __c.empty(); + } + bool __b; + _Const_iterator __i; + _Size_type __n; + }; + + template <class _Container> + struct _Mutable_ContainerConcept + { + typedef typename _Container::value_type _Value_type; + typedef typename _Container::reference _Reference; + typedef typename _Container::iterator _Iterator; + typedef typename _Container::pointer _Pointer; + + void __constraints() { + __function_requires< _ContainerConcept<_Container> >(); + __function_requires< _AssignableConcept<_Value_type> >(); + __function_requires< _InputIteratorConcept<_Iterator> >(); + + __i = __c.begin(); + __i = __c.end(); + __c.swap(__c2); + } + _Iterator __i; + _Container __c, __c2; + }; + + template <class _ForwardContainer> + struct _ForwardContainerConcept + { + void __constraints() { + __function_requires< _ContainerConcept<_ForwardContainer> >(); + typedef typename _ForwardContainer::const_iterator _Const_iterator; + __function_requires< _ForwardIteratorConcept<_Const_iterator> >(); + } + }; + + template <class _ForwardContainer> + struct _Mutable_ForwardContainerConcept + { + void __constraints() { + __function_requires< _ForwardContainerConcept<_ForwardContainer> >(); + __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >(); + typedef typename _ForwardContainer::iterator _Iterator; + __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >(); + } + }; + + template <class _ReversibleContainer> + struct _ReversibleContainerConcept + { + typedef typename _ReversibleContainer::const_iterator _Const_iterator; + typedef typename _ReversibleContainer::const_reverse_iterator + _Const_reverse_iterator; + + void __constraints() { + __function_requires< _ForwardContainerConcept<_ReversibleContainer> >(); + __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >(); + __function_requires< + _BidirectionalIteratorConcept<_Const_reverse_iterator> >(); + + const _ReversibleContainer __c; + _Const_reverse_iterator __i = __c.rbegin(); + __i = __c.rend(); + } + }; + + template <class _ReversibleContainer> + struct _Mutable_ReversibleContainerConcept + { + typedef typename _ReversibleContainer::iterator _Iterator; + typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator; + + void __constraints() { + __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >(); + __function_requires< + _Mutable_ForwardContainerConcept<_ReversibleContainer> >(); + __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >(); + __function_requires< + _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >(); + + _Reverse_iterator __i = __c.rbegin(); + __i = __c.rend(); + } + _ReversibleContainer __c; + }; + + template <class _RandomAccessContainer> + struct _RandomAccessContainerConcept + { + typedef typename _RandomAccessContainer::size_type _Size_type; + typedef typename _RandomAccessContainer::const_reference _Const_reference; + typedef typename _RandomAccessContainer::const_iterator _Const_iterator; + typedef typename _RandomAccessContainer::const_reverse_iterator + _Const_reverse_iterator; + + void __constraints() { + __function_requires< + _ReversibleContainerConcept<_RandomAccessContainer> >(); + __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >(); + __function_requires< + _RandomAccessIteratorConcept<_Const_reverse_iterator> >(); + + const _RandomAccessContainer __c; + _Const_reference __r _IsUnused = __c[__n]; + } + _Size_type __n; + }; + + template <class _RandomAccessContainer> + struct _Mutable_RandomAccessContainerConcept + { + typedef typename _RandomAccessContainer::size_type _Size_type; + typedef typename _RandomAccessContainer::reference _Reference; + typedef typename _RandomAccessContainer::iterator _Iterator; + typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator; + + void __constraints() { + __function_requires< + _RandomAccessContainerConcept<_RandomAccessContainer> >(); + __function_requires< + _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >(); + __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >(); + __function_requires< + _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >(); + + _Reference __r _IsUnused = __c[__i]; + } + _Size_type __i; + _RandomAccessContainer __c; + }; + + // A Sequence is inherently mutable + template <class _Sequence> + struct _SequenceConcept + { + typedef typename _Sequence::reference _Reference; + typedef typename _Sequence::const_reference _Const_reference; + + void __constraints() { + // Matt Austern's book puts DefaultConstructible here, the C++ + // standard places it in Container + // function_requires< DefaultConstructible<Sequence> >(); + __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >(); + __function_requires< _DefaultConstructibleConcept<_Sequence> >(); + + _Sequence + __c _IsUnused(__n, __t), + __c2 _IsUnused(__first, __last); + + __c.insert(__p, __t); + __c.insert(__p, __n, __t); + __c.insert(__p, __first, __last); + + __c.erase(__p); + __c.erase(__p, __q); + + _Reference __r _IsUnused = __c.front(); + + __const_constraints(__c); + } + void __const_constraints(const _Sequence& __c) { + _Const_reference __r _IsUnused = __c.front(); + } + typename _Sequence::value_type __t; + typename _Sequence::size_type __n; + typename _Sequence::value_type *__first, *__last; + typename _Sequence::iterator __p, __q; + }; + + template <class _FrontInsertionSequence> + struct _FrontInsertionSequenceConcept + { + void __constraints() { + __function_requires< _SequenceConcept<_FrontInsertionSequence> >(); + + __c.push_front(__t); + __c.pop_front(); + } + _FrontInsertionSequence __c; + typename _FrontInsertionSequence::value_type __t; + }; + + template <class _BackInsertionSequence> + struct _BackInsertionSequenceConcept + { + typedef typename _BackInsertionSequence::reference _Reference; + typedef typename _BackInsertionSequence::const_reference _Const_reference; + + void __constraints() { + __function_requires< _SequenceConcept<_BackInsertionSequence> >(); + + __c.push_back(__t); + __c.pop_back(); + _Reference __r _IsUnused = __c.back(); + } + void __const_constraints(const _BackInsertionSequence& __c) { + _Const_reference __r _IsUnused = __c.back(); + }; + _BackInsertionSequence __c; + typename _BackInsertionSequence::value_type __t; + }; + + template <class _AssociativeContainer> + struct _AssociativeContainerConcept + { + void __constraints() { + __function_requires< _ForwardContainerConcept<_AssociativeContainer> >(); + __function_requires< + _DefaultConstructibleConcept<_AssociativeContainer> >(); + + __i = __c.find(__k); + __r = __c.equal_range(__k); + __c.erase(__k); + __c.erase(__i); + __c.erase(__r.first, __r.second); + __const_constraints(__c); + } + void __const_constraints(const _AssociativeContainer& __c) { + __ci = __c.find(__k); + __n = __c.count(__k); + __cr = __c.equal_range(__k); + } + typedef typename _AssociativeContainer::iterator _Iterator; + typedef typename _AssociativeContainer::const_iterator _Const_iterator; + + _AssociativeContainer __c; + _Iterator __i; + std::pair<_Iterator,_Iterator> __r; + _Const_iterator __ci; + std::pair<_Const_iterator,_Const_iterator> __cr; + typename _AssociativeContainer::key_type __k; + typename _AssociativeContainer::size_type __n; + }; + + template <class _UniqueAssociativeContainer> + struct _UniqueAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_UniqueAssociativeContainer> >(); + + _UniqueAssociativeContainer __c(__first, __last); + + __pos_flag = __c.insert(__t); + __c.insert(__first, __last); + } + std::pair<typename _UniqueAssociativeContainer::iterator, bool> __pos_flag; + typename _UniqueAssociativeContainer::value_type __t; + typename _UniqueAssociativeContainer::value_type *__first, *__last; + }; + + template <class _MultipleAssociativeContainer> + struct _MultipleAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_MultipleAssociativeContainer> >(); + + _MultipleAssociativeContainer __c(__first, __last); + + __pos = __c.insert(__t); + __c.insert(__first, __last); + + } + typename _MultipleAssociativeContainer::iterator __pos; + typename _MultipleAssociativeContainer::value_type __t; + typename _MultipleAssociativeContainer::value_type *__first, *__last; + }; + + template <class _SimpleAssociativeContainer> + struct _SimpleAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_SimpleAssociativeContainer> >(); + typedef typename _SimpleAssociativeContainer::key_type _Key_type; + typedef typename _SimpleAssociativeContainer::value_type _Value_type; + typedef typename _Aux_require_same<_Key_type, _Value_type>::_Type + _Required; + } + }; + + template <class _SimpleAssociativeContainer> + struct _PairAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_SimpleAssociativeContainer> >(); + typedef typename _SimpleAssociativeContainer::key_type _Key_type; + typedef typename _SimpleAssociativeContainer::value_type _Value_type; + typedef typename _SimpleAssociativeContainer::mapped_type _Mapped_type; + typedef std::pair<const _Key_type, _Mapped_type> _Required_value_type; + typedef typename _Aux_require_same<_Value_type, + _Required_value_type>::_Type _Required; + } + }; + + template <class _SortedAssociativeContainer> + struct _SortedAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_SortedAssociativeContainer> >(); + __function_requires< + _ReversibleContainerConcept<_SortedAssociativeContainer> >(); + + _SortedAssociativeContainer + __c _IsUnused(__kc), + __c2 _IsUnused(__first, __last), + __c3 _IsUnused(__first, __last, __kc); + + __p = __c.upper_bound(__k); + __p = __c.lower_bound(__k); + __r = __c.equal_range(__k); + + __c.insert(__p, __t); + } + void __const_constraints(const _SortedAssociativeContainer& __c) { + __kc = __c.key_comp(); + __vc = __c.value_comp(); + + __cp = __c.upper_bound(__k); + __cp = __c.lower_bound(__k); + __cr = __c.equal_range(__k); + } + typename _SortedAssociativeContainer::key_compare __kc; + typename _SortedAssociativeContainer::value_compare __vc; + typename _SortedAssociativeContainer::value_type __t; + typename _SortedAssociativeContainer::key_type __k; + typedef typename _SortedAssociativeContainer::iterator _Iterator; + typedef typename _SortedAssociativeContainer::const_iterator + _Const_iterator; + + _Iterator __p; + _Const_iterator __cp; + std::pair<_Iterator,_Iterator> __r; + std::pair<_Const_iterator,_Const_iterator> __cr; + typename _SortedAssociativeContainer::value_type *__first, *__last; + }; + + // HashedAssociativeContainer + +_GLIBCXX_END_NAMESPACE + +#undef _IsUnused + +#endif // _GLIBCXX_BOOST_CONCEPT_CHECK + + diff --git a/libstdc++/include/bits/c++config b/libstdc++/include/bits/c++config new file mode 100644 index 0000000..cf20c1b --- /dev/null +++ b/libstdc++/include/bits/c++config @@ -0,0 +1,206 @@ +// Predefined symbols and macros -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, +// 2006, 2007 +// 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. + +/** @file c++config.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CXXCONFIG +#define _CXXCONFIG 1 + +// Pick up any OS-specific definitions. +#include <bits/os_defines.h> + +// Pick up any CPU-specific definitions. +#include <bits/cpu_defines.h> + +// The current version of the C++ library in compressed ISO date format. +#define __GLIBCXX__ + +// Macros for visibility. +#define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY + +#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY +#define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) +#else +#define _GLIBCXX_VISIBILITY(V) +#endif + +// Macros for controlling various namespace association schemes and modes. +#ifdef _GLIBCXX_DEBUG +# define _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG 1 +#endif + +#define _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION + +// Macros for namespace scope. +// _GLIBCXX_BEGIN_NAMESPACE +// _GLIBCXX_END_NAMESPACE +// _GLIBCXX_BEGIN_NESTED_NAMESPACE +// _GLIBCXX_END_NESTED_NAMESPACE +#if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION +# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) namespace X { namespace Y _GLIBCXX_VISIBILITY(default) { +# define _GLIBCXX_END_NESTED_NAMESPACE } } +# define _GLIBCXX_BEGIN_NAMESPACE(X) _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, _6) +# define _GLIBCXX_END_NAMESPACE _GLIBCXX_END_NESTED_NAMESPACE +#else +# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY(default) { +# define _GLIBCXX_END_NAMESPACE } +# if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG +# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) namespace X { namespace Y _GLIBCXX_VISIBILITY(default) { +# define _GLIBCXX_END_NESTED_NAMESPACE } } +# else +# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) _GLIBCXX_BEGIN_NAMESPACE(X) +# define _GLIBCXX_END_NESTED_NAMESPACE _GLIBCXX_END_NAMESPACE +# endif +#endif + +// Namespace associations for versioning mode. +#if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION +namespace std +{ + namespace _6 { } + using namespace _6 __attribute__ ((strong)); +} + +// In addition, other supported namespace configurations. +namespace __gnu_cxx +{ + namespace _6 { } + using namespace _6 __attribute__ ((strong)); +} + +namespace std +{ + namespace tr1 + { + namespace _6 { } + using namespace _6 __attribute__ ((strong)); + } +} +#endif + +// Namespace associations for debug mode. +#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG +namespace std +{ + namespace __norm { } + namespace __debug { } + using namespace __debug __attribute__ ((strong)); +} + +namespace __gnu_cxx +{ + namespace __norm { } + namespace __debug { } + using namespace __debug __attribute__ ((strong)); +} + +# define _GLIBCXX_STD __norm +# define _GLIBCXX_EXT __norm +# define _GLIBCXX_EXTERN_TEMPLATE 0 +# if __NO_INLINE__ && !__GXX_WEAK__ +# warning debug mode without inlining may fail due to lack of weak symbols +# endif +#else +#if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION +# define _GLIBCXX_STD _6 +# define _GLIBCXX_EXT _6 +#else +# define _GLIBCXX_STD std +# define _GLIBCXX_EXT __gnu_cxx +#endif +#endif + +/* Define if compatibility should be provided for -mlong-double-64. */ +#undef _GLIBCXX_LONG_DOUBLE_COMPAT + +// XXX GLIBCXX_ABI Deprecated +// Namespace associations for long double 128 mode. +_GLIBCXX_BEGIN_NAMESPACE(std) +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +# define _GLIBCXX_LDBL_NAMESPACE __gnu_cxx_ldbl128:: +# define _GLIBCXX_BEGIN_LDBL_NAMESPACE namespace __gnu_cxx_ldbl128 { +# define _GLIBCXX_END_LDBL_NAMESPACE } + namespace __gnu_cxx_ldbl128 { } + using namespace __gnu_cxx_ldbl128 __attribute__((__strong__)); +#else +# define _GLIBCXX_LDBL_NAMESPACE +# define _GLIBCXX_BEGIN_LDBL_NAMESPACE +# define _GLIBCXX_END_LDBL_NAMESPACE +#endif +_GLIBCXX_END_NAMESPACE + + +// Allow use of "export template." This is currently not a feature +// that g++ supports. +// #define _GLIBCXX_EXPORT_TEMPLATE 1 + +// Allow use of the GNU syntax extension, "extern template." This +// extension is fully documented in the g++ manual, but in a nutshell, +// it inhibits all implicit instantiations and is used throughout the +// library to avoid multiple weak definitions for required types that +// are already explicitly instantiated in the library binary. This +// substantially reduces the binary size of resulting executables. +#ifndef _GLIBCXX_EXTERN_TEMPLATE +# define _GLIBCXX_EXTERN_TEMPLATE 1 +#endif + + +// Certain function definitions that are meant to be overridable from +// user code are decorated with this macro. For some targets, this +// macro causes these definitions to be weak. +#ifndef _GLIBCXX_WEAK_DEFINITION +# define _GLIBCXX_WEAK_DEFINITION +#endif + +// The remainder of the prewritten config is automatic; all the +// user hooks are listed above. + +// Create a boolean flag to be used to determine if --fast-math is set. +#ifdef __FAST_MATH__ +# define _GLIBCXX_FAST_MATH 1 +#else +# define _GLIBCXX_FAST_MATH 0 +#endif + +// This marks string literals in header files to be extracted for eventual +// translation. It is primarily used for messages in thrown exceptions; see +// src/functexcept.cc. We use __N because the more traditional _N is used +// for something else under certain OSes (see BADNAMES). +#define __N(msgid) (msgid) + +// For example, <windows.h> is known to #define min and max as macros... +#undef min +#undef max + +// End of prewritten config; the discovered settings follow. diff --git a/libstdc++/include/bits/char_traits.h b/libstdc++/include/bits/char_traits.h new file mode 100644 index 0000000..58cddf6 --- /dev/null +++ b/libstdc++/include/bits/char_traits.h @@ -0,0 +1,367 @@ +// Character Traits for use by standard string and iostream -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file char_traits.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 21 Strings library +// + +#ifndef _CHAR_TRAITS_H +#define _CHAR_TRAITS_H 1 + +#pragma GCC system_header + +#include <cstring> // For memmove, memset, memchr +#include <bits/stl_algobase.h>// For copy, lexicographical_compare, fill_n +#include <bits/postypes.h> // For streampos + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /** + * @brief Mapping from character type to associated types. + * + * @note This is an implementation class for the generic version + * of char_traits. It defines int_type, off_type, pos_type, and + * state_type. By default these are unsigned long, streamoff, + * streampos, and mbstate_t. Users who need a different set of + * types, but who don't need to change the definitions of any function + * defined in char_traits, can specialize __gnu_cxx::_Char_types + * while leaving __gnu_cxx::char_traits alone. */ + template <class _CharT> + struct _Char_types + { + typedef unsigned long int_type; + typedef std::streampos pos_type; + typedef std::streamoff off_type; + typedef std::mbstate_t state_type; + }; + + + /** + * @brief Base class used to implement std::char_traits. + * + * @note For any given actual character type, this definition is + * probably wrong. (Most of the member functions are likely to be + * right, but the int_type and state_type typedefs, and the eof() + * member function, are likely to be wrong.) The reason this class + * exists is so users can specialize it. Classes in namespace std + * may not be specialized for fundamentl types, but classes in + * namespace __gnu_cxx may be. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 + * for advice on how to make use of this class for "unusual" character + * types. Also, check out include/ext/pod_char_traits.h. + */ + template<typename _CharT> + struct char_traits + { + typedef _CharT char_type; + typedef typename _Char_types<_CharT>::int_type int_type; + typedef typename _Char_types<_CharT>::pos_type pos_type; + typedef typename _Char_types<_CharT>::off_type off_type; + typedef typename _Char_types<_CharT>::state_type state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, std::size_t __n); + + static std::size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, std::size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, std::size_t __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, std::size_t __n); + + static char_type* + assign(char_type* __s, std::size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c) + { return static_cast<char_type>(__c); } + + static int_type + to_int_type(const char_type& __c) + { return static_cast<int_type>(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() + { return static_cast<int_type>(EOF); } + + static int_type + not_eof(const int_type& __c) + { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } + }; + + template<typename _CharT> + int + char_traits<_CharT>:: + compare(const char_type* __s1, const char_type* __s2, std::size_t __n) + { + for (std::size_t __i = 0; __i < __n; ++__i) + if (lt(__s1[__i], __s2[__i])) + return -1; + else if (lt(__s2[__i], __s1[__i])) + return 1; + return 0; + } + + template<typename _CharT> + std::size_t + char_traits<_CharT>:: + length(const char_type* __p) + { + std::size_t __i = 0; + while (!eq(__p[__i], char_type())) + ++__i; + return __i; + } + + template<typename _CharT> + const typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + find(const char_type* __s, std::size_t __n, const char_type& __a) + { + for (std::size_t __i = 0; __i < __n; ++__i) + if (eq(__s[__i], __a)) + return __s + __i; + return 0; + } + + template<typename _CharT> + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + move(char_type* __s1, const char_type* __s2, std::size_t __n) + { + return static_cast<_CharT*>(std::memmove(__s1, __s2, + __n * sizeof(char_type))); + } + + template<typename _CharT> + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + copy(char_type* __s1, const char_type* __s2, std::size_t __n) + { + std::copy(__s2, __s2 + __n, __s1); + return __s1; + } + + template<typename _CharT> + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + assign(char_type* __s, std::size_t __n, char_type __a) + { + std::fill_n(__s, __n, __a); + return __s; + } + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // 21.1 + /** + * @brief Basis for explicit traits specializations. + * + * @note For any given actual character type, this definition is + * probably wrong. Since this is just a thin wrapper around + * __gnu_cxx::char_traits, it is possible to achieve a more + * appropriate definition by specializing __gnu_cxx::char_traits. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 + * for advice on how to make use of this class for "unusual" character + * types. Also, check out include/ext/pod_char_traits.h. + */ + template<class _CharT> + struct char_traits : public __gnu_cxx::char_traits<_CharT> + { }; + + + /// @brief 21.1.3.1 char_traits specializations + template<> + struct char_traits<char> + { + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return memcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return strlen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return static_cast<const char_type*>(memchr(__s, __a, __n)); } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast<char_type*>(memmove(__s1, __s2, __n)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return static_cast<char_type*>(memset(__s, __a, __n)); } + + static char_type + to_char_type(const int_type& __c) + { return static_cast<char_type>(__c); } + + // To keep both the byte 0xff and the eof symbol 0xffffffff + // from ending up as 0xffffffff. + static int_type + to_int_type(const char_type& __c) + { return static_cast<int_type>(static_cast<unsigned char>(__c)); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast<int_type>(EOF); } + + static int_type + not_eof(const int_type& __c) + { return (__c == eof()) ? 0 : __c; } + }; + + +#ifdef _GLIBCXX_USE_WCHAR_T + /// @brief 21.1.3.2 char_traits specializations + template<> + struct char_traits<wchar_t> + { + typedef wchar_t char_type; + typedef wint_t int_type; + typedef streamoff off_type; + typedef wstreampos pos_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return wcslen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return wmemchr(__s, __a, __n); } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return wmemmove(__s1, __s2, __n); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcpy(__s1, __s2, __n); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return wmemset(__s, __a, __n); } + + static char_type + to_char_type(const int_type& __c) { return char_type(__c); } + + static int_type + to_int_type(const char_type& __c) { return int_type(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast<int_type>(WEOF); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? 0 : __c; } + }; +#endif //_GLIBCXX_USE_WCHAR_T + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/codecvt.h b/libstdc++/include/bits/codecvt.h new file mode 100644 index 0000000..d417a6f --- /dev/null +++ b/libstdc++/include/bits/codecvt.h @@ -0,0 +1,474 @@ +// Locale support (codecvt) -*- C++ -*- + +// Copyright (C) 2000, 2001, 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. + +/** @file bits/codecvt.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 22.2.1.5 Template class codecvt +// + +// Written by Benjamin Kosnik <bkoz@redhat.com> + +#ifndef _CODECVT_H +#define _CODECVT_H 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /// @brief Empty base class for codecvt facet [22.2.1.5]. + class codecvt_base + { + public: + enum result + { + ok, + partial, + error, + noconv + }; + }; + + /** + * @brief Common base for codecvt functions. + * + * This template class provides implementations of the public functions + * that forward to the protected virtual functions. + * + * This template also provides abstract stubs for the protected virtual + * functions. + */ + template<typename _InternT, typename _ExternT, typename _StateT> + class __codecvt_abstract_base + : public locale::facet, public codecvt_base + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + + // 22.2.1.5.1 codecvt members + /** + * @brief Convert from internal to external character set. + * + * Converts input string of intern_type to output string of + * extern_type. This is analogous to wcsrtombs. It does this by + * calling codecvt::do_out. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The characters in [from,from_end) are converted and written to + * [to,to_end). from_next and to_next are set to point to the + * character following the last successfully converted character, + * respectively. If the result needed no conversion, from_next and + * to_next are not affected. + * + * The @a state argument should be intialized if the input is at the + * beginning and carried from a previous call if continuing + * conversion. There are no guarantees about how @a state is used. + * + * The result returned is a member of codecvt_base::result. If + * all the input is converted, returns codecvt_base::ok. If no + * conversion is necessary, returns codecvt_base::noconv. If + * the input ends early or there is insufficient space in the + * output, returns codecvt_base::partial. Otherwise the + * conversion failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param from Start of input. + * @param from_end End of input. + * @param from_next Returns start of unconverted data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ + result + out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { + return this->do_out(__state, __from, __from_end, __from_next, + __to, __to_end, __to_next); + } + + /** + * @brief Reset conversion state. + * + * Writes characters to output that would restore @a state to initial + * conditions. The idea is that if a partial conversion occurs, then + * the converting the characters written by this function would leave + * the state in initial conditions, rather than partial conversion + * state. It does this by calling codecvt::do_unshift(). + * + * For example, if 4 external characters always converted to 1 internal + * character, and input to in() had 6 external characters with state + * saved, this function would write two characters to the output and + * set the state to initialized conditions. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The result returned is a member of codecvt_base::result. If the + * state could be reset and data written, returns codecvt_base::ok. If + * no conversion is necessary, returns codecvt_base::noconv. If the + * output has insufficient space, returns codecvt_base::partial. + * Otherwise the reset failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ + result + unshift(state_type& __state, extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { return this->do_unshift(__state, __to,__to_end,__to_next); } + + /** + * @brief Convert from external to internal character set. + * + * Converts input string of extern_type to output string of + * intern_type. This is analogous to mbsrtowcs. It does this by + * calling codecvt::do_in. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The characters in [from,from_end) are converted and written to + * [to,to_end). from_next and to_next are set to point to the + * character following the last successfully converted character, + * respectively. If the result needed no conversion, from_next and + * to_next are not affected. + * + * The @a state argument should be intialized if the input is at the + * beginning and carried from a previous call if continuing + * conversion. There are no guarantees about how @a state is used. + * + * The result returned is a member of codecvt_base::result. If + * all the input is converted, returns codecvt_base::ok. If no + * conversion is necessary, returns codecvt_base::noconv. If + * the input ends early or there is insufficient space in the + * output, returns codecvt_base::partial. Otherwise the + * conversion failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param from Start of input. + * @param from_end End of input. + * @param from_next Returns start of unconverted data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ + result + in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const + { + return this->do_in(__state, __from, __from_end, __from_next, + __to, __to_end, __to_next); + } + + int + encoding() const throw() + { return this->do_encoding(); } + + bool + always_noconv() const throw() + { return this->do_always_noconv(); } + + int + length(state_type& __state, const extern_type* __from, + const extern_type* __end, size_t __max) const + { return this->do_length(__state, __from, __end, __max); } + + int + max_length() const throw() + { return this->do_max_length(); } + + protected: + explicit + __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } + + virtual + ~__codecvt_abstract_base() { } + + /** + * @brief Convert from internal to external character set. + * + * Converts input string of intern_type to output string of + * extern_type. This function is a hook for derived classes to change + * the value returned. @see out for more information. + */ + 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_end, + extern_type*& __to_next) const = 0; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const = 0; + + 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_end, + intern_type*& __to_next) const = 0; + + virtual int + do_encoding() const throw() = 0; + + virtual bool + do_always_noconv() const throw() = 0; + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const = 0; + + virtual int + do_max_length() const throw() = 0; + }; + + /// @brief class codecvt [22.2.1.5]. + /// NB: Generic, mostly useless implementation. + template<typename _InternT, typename _ExternT, typename _StateT> + class codecvt + : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + + protected: + __c_locale _M_c_locale_codecvt; + + public: + static locale::id id; + + explicit + codecvt(size_t __refs = 0) + : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs) { } + + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + + protected: + virtual + ~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_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + 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_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + + template<typename _InternT, typename _ExternT, typename _StateT> + locale::id codecvt<_InternT, _ExternT, _StateT>::id; + + /// @brief class codecvt<char, char, mbstate_t> specialization. + template<> + class codecvt<char, char, mbstate_t> + : public __codecvt_abstract_base<char, char, mbstate_t> + { + public: + // Types: + typedef char intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + protected: + __c_locale _M_c_locale_codecvt; + + public: + static locale::id id; + + explicit + codecvt(size_t __refs = 0); + + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + + protected: + virtual + ~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_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + 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_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + +#ifdef _GLIBCXX_USE_WCHAR_T + /// @brief class codecvt<wchar_t, char, mbstate_t> specialization. + template<> + class codecvt<wchar_t, char, mbstate_t> + : public __codecvt_abstract_base<wchar_t, char, mbstate_t> + { + public: + // Types: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + protected: + __c_locale _M_c_locale_codecvt; + + public: + static locale::id id; + + explicit + codecvt(size_t __refs = 0); + + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + + protected: + virtual + ~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_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + 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_end, + intern_type*& __to_next) const; + + virtual + int do_encoding() const throw(); + + virtual + bool do_always_noconv() const throw(); + + virtual + int do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; +#endif //_GLIBCXX_USE_WCHAR_T + + /// @brief class codecvt_byname [22.2.1.6]. + template<typename _InternT, typename _ExternT, typename _StateT> + class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> + { + public: + explicit + codecvt_byname(const char* __s, size_t __refs = 0) + : codecvt<_InternT, _ExternT, _StateT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_codecvt); + this->_S_create_c_locale(this->_M_c_locale_codecvt, __s); + } + } + + protected: + virtual + ~codecvt_byname() { } + }; + +_GLIBCXX_END_NAMESPACE + +#endif // _CODECVT_H diff --git a/libstdc++/include/bits/concept_check.h b/libstdc++/include/bits/concept_check.h new file mode 100644 index 0000000..98cb42d --- /dev/null +++ b/libstdc++/include/bits/concept_check.h @@ -0,0 +1,85 @@ +// Concept-checking control -*- C++ -*- + +// Copyright (C) 2001 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. + +/** @file concept_check.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CONCEPT_CHECK_H +#define _CONCEPT_CHECK_H 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +// All places in libstdc++-v3 where these are used, or /might/ be used, or +// don't need to be used, or perhaps /should/ be used, are commented with +// "concept requirements" (and maybe some more text). So grep like crazy +// if you're looking for additional places to use these. + +// Concept-checking code is off by default unless users turn it on via +// configure options or editing c++config.h. + +#ifndef _GLIBCXX_CONCEPT_CHECKS + +#define __glibcxx_function_requires(...) +#define __glibcxx_class_requires(_a,_b) +#define __glibcxx_class_requires2(_a,_b,_c) +#define __glibcxx_class_requires3(_a,_b,_c,_d) +#define __glibcxx_class_requires4(_a,_b,_c,_d,_e) + +#else // the checks are on + +#include <bits/boost_concept_check.h> + +// Note that the obvious and elegant approach of +// +//#define glibcxx_function_requires(C) boost::function_requires< boost::C >() +// +// won't work due to concept templates with more than one parameter, e.g., +// BinaryPredicateConcept. The preprocessor tries to split things up on +// the commas in the template argument list. We can't use an inner pair of +// parenthesis to hide the commas, because "boost::(Temp<Foo,Bar>)" isn't +// a valid instantiation pattern. Thus, we steal a feature from C99. + +#define __glibcxx_function_requires(...) \ + __gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >(); +#define __glibcxx_class_requires(_a,_C) \ + _GLIBCXX_CLASS_REQUIRES(_a, __gnu_cxx, _C); +#define __glibcxx_class_requires2(_a,_b,_C) \ + _GLIBCXX_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C); +#define __glibcxx_class_requires3(_a,_b,_c,_C) \ + _GLIBCXX_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C); +#define __glibcxx_class_requires4(_a,_b,_c,_d,_C) \ + _GLIBCXX_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C); + +#endif // enable/disable + +#endif // _GLIBCXX_CONCEPT_CHECK diff --git a/libstdc++/include/bits/cpp_type_traits.h b/libstdc++/include/bits/cpp_type_traits.h new file mode 100644 index 0000000..ed9a48a --- /dev/null +++ b/libstdc++/include/bits/cpp_type_traits.h @@ -0,0 +1,403 @@ +// The -*- C++ -*- type traits classes for internal use in libstdc++ + +// 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. + +/** @file cpp_type_traits.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> + +#ifndef _CPP_TYPE_TRAITS_H +#define _CPP_TYPE_TRAITS_H 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +// +// This file provides some compile-time information about various types. +// These representations were designed, on purpose, to be constant-expressions +// and not types as found in <bits/type_traits.h>. In particular, they +// can be used in control structures and the optimizer hopefully will do +// the obvious thing. +// +// Why integral expressions, and not functions nor types? +// Firstly, these compile-time entities are used as template-arguments +// so function return values won't work: We need compile-time entities. +// We're left with types and constant integral expressions. +// Secondly, from the point of view of ease of use, type-based compile-time +// information is -not- *that* convenient. On has to write lots of +// overloaded functions and to hope that the compiler will select the right +// one. As a net effect, the overall structure isn't very clear at first +// glance. +// Thirdly, partial ordering and overload resolution (of function templates) +// is highly costly in terms of compiler-resource. It is a Good Thing to +// keep these resource consumption as least as possible. +// +// See valarray_array.h for a case use. +// +// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. +// +// Update 2005: types are also provided and <bits/type_traits.h> has been +// removed. +// + +// Forward declaration hack, should really include this from somewhere. +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _Iterator, typename _Container> + class __normal_iterator; + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + +namespace __detail +{ + // NB: g++ can not compile these if declared within the class + // __is_pod itself. + typedef char __one; + typedef char __two[2]; + + template<typename _Tp> + __one __test_type(int _Tp::*); + template<typename _Tp> + __two& __test_type(...); +} // namespace __detail + + + struct __true_type { }; + struct __false_type { }; + + template<bool> + struct __truth_type + { typedef __false_type __type; }; + + template<> + struct __truth_type<true> + { typedef __true_type __type; }; + + // N.B. The conversions to bool are needed due to the issue + // explained in c++/19404. + template<class _Sp, class _Tp> + struct __traitor + { + enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; + typedef typename __truth_type<__value>::__type __type; + }; + + // Compare for equality of types. + template<typename, typename> + struct __are_same + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template<typename _Tp> + struct __are_same<_Tp, _Tp> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + // Holds if the template-argument is a void type. + template<typename _Tp> + struct __is_void + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template<> + struct __is_void<void> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + // + // Integer types + // + template<typename _Tp> + struct __is_integer + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + // Thirteen specializations (yes there are eleven standard integer + // types; 'long long' and 'unsigned long long' are supported as + // extensions) + template<> + struct __is_integer<bool> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<char> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<signed char> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<unsigned char> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + +# ifdef _GLIBCXX_USE_WCHAR_T + template<> + struct __is_integer<wchar_t> + { + enum { __value = 1 }; + typedef __true_type __type; + }; +# endif + + template<> + struct __is_integer<short> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<unsigned short> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<int> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<unsigned int> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<long> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<unsigned long> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<long long> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_integer<unsigned long long> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + // + // Floating point types + // + template<typename _Tp> + struct __is_floating + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + // three specializations (float, double and 'long double') + template<> + struct __is_floating<float> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_floating<double> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + template<> + struct __is_floating<long double> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + // + // Pointer types + // + template<typename _Tp> + struct __is_pointer + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template<typename _Tp> + struct __is_pointer<_Tp*> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + // + // Normal iterator type + // + template<typename _Tp> + struct __is_normal_iterator + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template<typename _Iterator, typename _Container> + struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, + _Container> > + { + enum { __value = 1 }; + typedef __true_type __type; + }; + + // + // An arithmetic type is an integer type or a floating point type + // + template<typename _Tp> + struct __is_arithmetic + : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > + { }; + + // + // A fundamental type is `void' or and arithmetic type + // + template<typename _Tp> + struct __is_fundamental + : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > + { }; + + // + // A scalar type is an arithmetic type or a pointer type + // + template<typename _Tp> + struct __is_scalar + : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > + { }; + + // For the immediate use, the following is a good approximation. + template<typename _Tp> + struct __is_pod + { + enum + { + __value = (sizeof(__detail::__test_type<_Tp>(0)) + != sizeof(__detail::__one)) + }; + }; + + // + // A stripped-down version of std::tr1::is_empty + // + template<typename _Tp> + struct __is_empty + { + private: + template<typename> + struct __first { }; + template<typename _Up> + struct __second + : public _Up { }; + + public: + enum + { + __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>) + }; + }; + + // + // For use in std::copy and std::find overloads for streambuf iterators. + // + template<typename _Tp> + struct __is_char + { + enum { __value = 0 }; + typedef __false_type __type; + }; + + template<> + struct __is_char<char> + { + enum { __value = 1 }; + typedef __true_type __type; + }; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + struct __is_char<wchar_t> + { + enum { __value = 1 }; + typedef __true_type __type; + }; +#endif + +_GLIBCXX_END_NAMESPACE + +#endif //_CPP_TYPE_TRAITS_H diff --git a/libstdc++/include/bits/deque.tcc b/libstdc++/include/bits/deque.tcc new file mode 100644 index 0000000..3f53f20 --- /dev/null +++ b/libstdc++/include/bits/deque.tcc @@ -0,0 +1,778 @@ +// Deque implementation (out of line) -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +// 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file deque.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _DEQUE_TCC +#define _DEQUE_TCC 1 + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + template <typename _Tp, typename _Alloc> + deque<_Tp, _Alloc>& + deque<_Tp, _Alloc>:: + operator=(const deque& __x) + { + const size_type __len = size(); + if (&__x != this) + { + if (__len >= __x.size()) + _M_erase_at_end(std::copy(__x.begin(), __x.end(), + this->_M_impl._M_start)); + else + { + const_iterator __mid = __x.begin() + difference_type(__len); + std::copy(__x.begin(), __mid, this->_M_impl._M_start); + insert(this->_M_impl._M_finish, __mid, __x.end()); + } + } + return *this; + } + + template <typename _Tp, typename _Alloc> + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + insert(iterator __position, const value_type& __x) + { + if (__position._M_cur == this->_M_impl._M_start._M_cur) + { + push_front(__x); + return this->_M_impl._M_start; + } + else if (__position._M_cur == this->_M_impl._M_finish._M_cur) + { + push_back(__x); + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return __tmp; + } + else + return _M_insert_aux(__position, __x); + } + + template <typename _Tp, typename _Alloc> + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + erase(iterator __position) + { + iterator __next = __position; + ++__next; + const difference_type __index = __position - begin(); + if (static_cast<size_type>(__index) < (size() >> 1)) + { + if (__position != begin()) + std::copy_backward(begin(), __position, __next); + pop_front(); + } + else + { + if (__next != end()) + std::copy(__next, end(), __position); + pop_back(); + } + return begin() + __index; + } + + template <typename _Tp, typename _Alloc> + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + erase(iterator __first, iterator __last) + { + if (__first == begin() && __last == end()) + { + clear(); + return end(); + } + else + { + const difference_type __n = __last - __first; + const difference_type __elems_before = __first - begin(); + if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2) + { + if (__first != begin()) + std::copy_backward(begin(), __first, __last); + _M_erase_at_begin(begin() + __n); + } + else + { + if (__last != end()) + std::copy(__last, end(), __first); + _M_erase_at_end(end() - __n); + } + return begin() + __elems_before; + } + } + + template <typename _Tp, class _Alloc> + template <typename _InputIterator> + void + deque<_Tp, _Alloc>:: + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + iterator __cur = begin(); + for (; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + _M_erase_at_end(__cur); + else + insert(end(), __first, __last); + } + + template <typename _Tp, typename _Alloc> + void + deque<_Tp, _Alloc>:: + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) + { + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start, + __x, _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, + this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::__uninitialized_fill_a(this->_M_impl._M_finish, + __new_finish, __x, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + else + _M_insert_aux(__pos, __n, __x); + } + + template <typename _Tp, typename _Alloc> + void + deque<_Tp, _Alloc>:: + _M_fill_initialize(const value_type& __value) + { + _Map_pointer __cur; + try + { + for (__cur = this->_M_impl._M_start._M_node; + __cur < this->_M_impl._M_finish._M_node; + ++__cur) + std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(), + __value, _M_get_Tp_allocator()); + std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first, + this->_M_impl._M_finish._M_cur, + __value, _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur), + _M_get_Tp_allocator()); + __throw_exception_again; + } + } + + template <typename _Tp, typename _Alloc> + template <typename _InputIterator> + void + deque<_Tp, _Alloc>:: + _M_range_initialize(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + this->_M_initialize_map(0); + try + { + for (; __first != __last; ++__first) + push_back(*__first); + } + catch(...) + { + clear(); + __throw_exception_again; + } + } + + template <typename _Tp, typename _Alloc> + template <typename _ForwardIterator> + void + deque<_Tp, _Alloc>:: + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + this->_M_initialize_map(__n); + + _Map_pointer __cur_node; + try + { + for (__cur_node = this->_M_impl._M_start._M_node; + __cur_node < this->_M_impl._M_finish._M_node; + ++__cur_node) + { + _ForwardIterator __mid = __first; + std::advance(__mid, _S_buffer_size()); + std::__uninitialized_copy_a(__first, __mid, *__cur_node, + _M_get_Tp_allocator()); + __first = __mid; + } + std::__uninitialized_copy_a(__first, __last, + this->_M_impl._M_finish._M_first, + _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(this->_M_impl._M_start, + iterator(*__cur_node, __cur_node), + _M_get_Tp_allocator()); + __throw_exception_again; + } + } + + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. + template <typename _Tp, typename _Alloc> + void + deque<_Tp, _Alloc>:: + _M_push_back_aux(const value_type& __t) + { + value_type __t_copy = __t; + _M_reserve_map_at_back(); + *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); + try + { + this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t_copy); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + + 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; + } + catch(...) + { + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); + __throw_exception_again; + } + } + + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. + template <typename _Tp, typename _Alloc> + void + deque<_Tp, _Alloc>:: + _M_push_front_aux(const value_type& __t) + { + value_type __t_copy = __t; + _M_reserve_map_at_front(); + *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); + try + { + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + - 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; + this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t_copy); + } + catch(...) + { + ++this->_M_impl._M_start; + _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); + __throw_exception_again; + } + } + + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. + template <typename _Tp, typename _Alloc> + void deque<_Tp, _Alloc>:: + _M_pop_back_aux() + { + _M_deallocate_node(this->_M_impl._M_finish._M_first); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; + this->_M_impl.destroy(this->_M_impl._M_finish._M_cur); + } + + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. + // Note that if the deque has at least one element (a precondition for this + // member function), and if + // _M_impl._M_start._M_cur == _M_impl._M_start._M_last, + // then the deque must have at least two nodes. + template <typename _Tp, typename _Alloc> + void deque<_Tp, _Alloc>:: + _M_pop_front_aux() + { + this->_M_impl.destroy(this->_M_impl._M_start._M_cur); + _M_deallocate_node(this->_M_impl._M_start._M_first); + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; + } + + template <typename _Tp, typename _Alloc> + template <typename _InputIterator> + void + deque<_Tp, _Alloc>:: + _M_range_insert_aux(iterator __pos, + _InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { std::copy(__first, __last, std::inserter(*this, __pos)); } + + template <typename _Tp, typename _Alloc> + template <typename _ForwardIterator> + void + deque<_Tp, _Alloc>:: + _M_range_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::__uninitialized_copy_a(__first, __last, __new_start, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, + this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::__uninitialized_copy_a(__first, __last, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + else + _M_insert_aux(__pos, __first, __last, __n); + } + + template <typename _Tp, typename _Alloc> + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, const value_type& __x) + { + difference_type __index = __pos - this->_M_impl._M_start; + value_type __x_copy = __x; // XXX copy + if (static_cast<size_type>(__index) < size() / 2) + { + push_front(front()); + iterator __front1 = this->_M_impl._M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = this->_M_impl._M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + std::copy(__front2, __pos1, __front1); + } + else + { + push_back(back()); + iterator __back1 = this->_M_impl._M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = this->_M_impl._M_start + __index; + std::copy_backward(__pos, __back2, __back1); + } + *__pos = __x_copy; + return __pos; + } + + template <typename _Tp, typename _Alloc> + void + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) + { + const difference_type __elems_before = __pos - this->_M_impl._M_start; + const size_type __length = this->size(); + value_type __x_copy = __x; + if (__elems_before < difference_type(__length / 2)) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elems_before; + try + { + if (__elems_before >= difference_type(__n)) + { + iterator __start_n = (this->_M_impl._M_start + + difference_type(__n)); + std::__uninitialized_copy_a(this->_M_impl._M_start, + __start_n, __new_start, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + std::fill(__pos - difference_type(__n), __pos, __x_copy); + } + else + { + std::__uninitialized_copy_fill(this->_M_impl._M_start, + __pos, __new_start, + this->_M_impl._M_start, + __x_copy, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::fill(__old_start, __pos, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, + this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = this->_M_impl._M_finish - __elems_after; + try + { + if (__elems_after > difference_type(__n)) + { + iterator __finish_n = (this->_M_impl._M_finish + - difference_type(__n)); + std::__uninitialized_copy_a(__finish_n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::fill(__pos, __pos + difference_type(__n), __x_copy); + } + else + { + std::__uninitialized_fill_copy(this->_M_impl._M_finish, + __pos + difference_type(__n), + __x_copy, __pos, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::fill(__pos, __old_finish, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + } + + template <typename _Tp, typename _Alloc> + template <typename _ForwardIterator> + void + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n) + { + const difference_type __elemsbefore = __pos - this->_M_impl._M_start; + const size_type __length = size(); + if (static_cast<size_type>(__elemsbefore) < __length / 2) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elemsbefore; + try + { + if (__elemsbefore >= difference_type(__n)) + { + iterator __start_n = (this->_M_impl._M_start + + difference_type(__n)); + std::__uninitialized_copy_a(this->_M_impl._M_start, + __start_n, __new_start, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + std::copy(__first, __last, __pos - difference_type(__n)); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, difference_type(__n) - __elemsbefore); + std::__uninitialized_copy_copy(this->_M_impl._M_start, + __pos, __first, __mid, + __new_start, + _M_get_Tp_allocator()); + this->_M_impl._M_start = __new_start; + std::copy(__mid, __last, __old_start); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, + this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = this->_M_impl._M_finish - __elemsafter; + try + { + if (__elemsafter > difference_type(__n)) + { + iterator __finish_n = (this->_M_impl._M_finish + - difference_type(__n)); + std::__uninitialized_copy_a(__finish_n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::copy(__first, __last, __pos); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elemsafter); + std::__uninitialized_copy_copy(__mid, __last, __pos, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __new_finish; + std::copy(__first, __mid, __pos); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + } + + template<typename _Tp, typename _Alloc> + void + deque<_Tp, _Alloc>:: + _M_destroy_data_aux(iterator __first, iterator __last) + { + for (_Map_pointer __node = __first._M_node + 1; + __node < __last._M_node; ++__node) + std::_Destroy(*__node, *__node + _S_buffer_size(), + _M_get_Tp_allocator()); + + if (__first._M_node != __last._M_node) + { + std::_Destroy(__first._M_cur, __first._M_last, + _M_get_Tp_allocator()); + std::_Destroy(__last._M_first, __last._M_cur, + _M_get_Tp_allocator()); + } + else + std::_Destroy(__first._M_cur, __last._M_cur, + _M_get_Tp_allocator()); + } + + template <typename _Tp, typename _Alloc> + void + deque<_Tp, _Alloc>:: + _M_new_elements_at_front(size_type __new_elems) + { + if (this->max_size() - this->size() < __new_elems) + __throw_length_error(__N("deque::_M_new_elements_at_front")); + + const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) + / _S_buffer_size()); + _M_reserve_map_at_front(__new_nodes); + size_type __i; + try + { + for (__i = 1; __i <= __new_nodes; ++__i) + *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); + } + catch(...) + { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); + __throw_exception_again; + } + } + + template <typename _Tp, typename _Alloc> + void + deque<_Tp, _Alloc>:: + _M_new_elements_at_back(size_type __new_elems) + { + if (this->max_size() - this->size() < __new_elems) + __throw_length_error(__N("deque::_M_new_elements_at_back")); + + const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) + / _S_buffer_size()); + _M_reserve_map_at_back(__new_nodes); + size_type __i; + try + { + for (__i = 1; __i <= __new_nodes; ++__i) + *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); + } + catch(...) + { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); + __throw_exception_again; + } + } + + template <typename _Tp, typename _Alloc> + void + deque<_Tp, _Alloc>:: + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) + { + const size_type __old_num_nodes + = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; + const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; + + _Map_pointer __new_nstart; + if (this->_M_impl._M_map_size > 2 * __new_num_nodes) + { + __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size + - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < this->_M_impl._M_start._M_node) + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + else + std::copy_backward(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart + __old_num_nodes); + } + else + { + size_type __new_map_size = this->_M_impl._M_map_size + + std::max(this->_M_impl._M_map_size, + __nodes_to_add) + 2; + + _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + + this->_M_impl._M_map = __new_map; + this->_M_impl._M_map_size = __new_map_size; + } + + this->_M_impl._M_start._M_set_node(__new_nstart); + this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); + } + + // Overload for deque::iterators, exploiting the "segmented-iterator + // optimization". NB: leave const_iterators alone! + template<typename _Tp> + void + fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first, + const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value) + { + typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; + + for (typename _Self::_Map_pointer __node = __first._M_node + 1; + __node < __last._M_node; ++__node) + std::fill(*__node, *__node + _Self::_S_buffer_size(), __value); + + if (__first._M_node != __last._M_node) + { + std::fill(__first._M_cur, __first._M_last, __value); + std::fill(__last._M_first, __last._M_cur, __value); + } + else + std::fill(__first._M_cur, __last._M_cur, __value); + } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/fstream.tcc b/libstdc++/include/bits/fstream.tcc new file mode 100644 index 0000000..5520f9b --- /dev/null +++ b/libstdc++/include/bits/fstream.tcc @@ -0,0 +1,908 @@ +// File based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file fstream.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 27.8 File-based streams +// + +#ifndef _FSTREAM_TCC +#define _FSTREAM_TCC 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _CharT, typename _Traits> + void + basic_filebuf<_CharT, _Traits>:: + _M_allocate_internal_buffer() + { + // Allocate internal buffer only if one doesn't already exist + // (either allocated or provided by the user via setbuf). + if (!_M_buf_allocated && !_M_buf) + { + _M_buf = new char_type[_M_buf_size]; + _M_buf_allocated = true; + } + } + + template<typename _CharT, typename _Traits> + void + basic_filebuf<_CharT, _Traits>:: + _M_destroy_internal_buffer() throw() + { + if (_M_buf_allocated) + { + delete [] _M_buf; + _M_buf = NULL; + _M_buf_allocated = false; + } + delete [] _M_ext_buf; + _M_ext_buf = NULL; + _M_ext_buf_size = 0; + _M_ext_next = NULL; + _M_ext_end = NULL; + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>:: + basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock), + _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(), + _M_state_last(), _M_buf(NULL), _M_buf_size(BUFSIZ), + _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(), + _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false), + _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0), + _M_ext_end(0) + { + if (has_facet<__codecvt_type>(this->_M_buf_locale)) + _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale); + } + + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* + basic_filebuf<_CharT, _Traits>:: + open(const char* __s, ios_base::openmode __mode) + { + __filebuf_type *__ret = NULL; + if (!this->is_open()) + { + _M_file.open(__s, __mode); + if (this->is_open()) + { + _M_allocate_internal_buffer(); + _M_mode = __mode; + + // Setup initial buffer to 'uncommitted' mode. + _M_reading = false; + _M_writing = false; + _M_set_buffer(-1); + + // Reset to initial state. + _M_state_last = _M_state_cur = _M_state_beg; + + // 27.8.1.3,4 + if ((__mode & ios_base::ate) + && this->seekoff(0, ios_base::end, __mode) + == pos_type(off_type(-1))) + this->close(); + else + __ret = this; + } + } + return __ret; + } + + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* + basic_filebuf<_CharT, _Traits>:: + close() throw() + { + __filebuf_type* __ret = NULL; + if (this->is_open()) + { + bool __testfail = false; + try + { + if (!_M_terminate_output()) + __testfail = true; + } + catch(...) + { __testfail = true; } + + // NB: Do this here so that re-opened filebufs will be cool... + _M_mode = ios_base::openmode(0); + _M_pback_init = false; + _M_destroy_internal_buffer(); + _M_reading = false; + _M_writing = false; + _M_set_buffer(-1); + _M_state_last = _M_state_cur = _M_state_beg; + + if (!_M_file.close()) + __testfail = true; + + if (!__testfail) + __ret = this; + } + return __ret; + } + + template<typename _CharT, typename _Traits> + streamsize + basic_filebuf<_CharT, _Traits>:: + showmanyc() + { + streamsize __ret = -1; + const bool __testin = _M_mode & ios_base::in; + if (__testin && this->is_open()) + { + // For a stateful encoding (-1) the pending sequence might be just + // shift and unshift prefixes with no actual character. + __ret = this->egptr() - this->gptr(); + +#if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM + // About this workaround, see libstdc++/20806. + const bool __testbinary = _M_mode & ios_base::binary; + if (__check_facet(_M_codecvt).encoding() >= 0 + && __testbinary) +#else + if (__check_facet(_M_codecvt).encoding() >= 0) +#endif + __ret += _M_file.showmanyc() / _M_codecvt->max_length(); + } + return __ret; + } + + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + underflow() + { + int_type __ret = traits_type::eof(); + const bool __testin = _M_mode & ios_base::in; + if (__testin && !_M_writing) + { + // Check for pback madness, and if so swich back to the + // normal buffers and jet outta here before expensive + // fileops happen... + _M_destroy_pback(); + + if (this->gptr() < this->egptr()) + return traits_type::to_int_type(*this->gptr()); + + // Get and convert input sequence. + const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; + + // Will be set to true if ::read() returns 0 indicating EOF. + bool __got_eof = false; + // Number of internal characters produced. + streamsize __ilen = 0; + codecvt_base::result __r = codecvt_base::ok; + if (__check_facet(_M_codecvt).always_noconv()) + { + __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()), + __buflen); + if (__ilen == 0) + __got_eof = true; + } + else + { + // Worst-case number of external bytes. + // XXX Not done encoding() == -1. + const int __enc = _M_codecvt->encoding(); + streamsize __blen; // Minimum buffer size. + streamsize __rlen; // Number of chars to read. + if (__enc > 0) + __blen = __rlen = __buflen * __enc; + else + { + __blen = __buflen + _M_codecvt->max_length() - 1; + __rlen = __buflen; + } + const streamsize __remainder = _M_ext_end - _M_ext_next; + __rlen = __rlen > __remainder ? __rlen - __remainder : 0; + + // An imbue in 'read' mode implies first converting the external + // chars already present. + if (_M_reading && this->egptr() == this->eback() && __remainder) + __rlen = 0; + + // Allocate buffer if necessary and move unconverted + // bytes to front. + if (_M_ext_buf_size < __blen) + { + char* __buf = new char[__blen]; + if (__remainder) + std::memcpy(__buf, _M_ext_next, __remainder); + + delete [] _M_ext_buf; + _M_ext_buf = __buf; + _M_ext_buf_size = __blen; + } + else if (__remainder) + std::memmove(_M_ext_buf, _M_ext_next, __remainder); + + _M_ext_next = _M_ext_buf; + _M_ext_end = _M_ext_buf + __remainder; + _M_state_last = _M_state_cur; + + do + { + if (__rlen > 0) + { + // Sanity check! + // This may fail if the return value of + // codecvt::max_length() is bogus. + if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) + { + __throw_ios_failure(__N("basic_filebuf::underflow " + "codecvt::max_length() " + "is not valid")); + } + streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); + if (__elen == 0) + __got_eof = true; + else if (__elen == -1) + break; + _M_ext_end += __elen; + } + + char_type* __iend; + __r = _M_codecvt->in(_M_state_cur, _M_ext_next, + _M_ext_end, _M_ext_next, this->eback(), + this->eback() + __buflen, __iend); + if (__r == codecvt_base::noconv) + { + size_t __avail = _M_ext_end - _M_ext_buf; + __ilen = std::min(__avail, __buflen); + traits_type::copy(this->eback(), + reinterpret_cast<char_type*>(_M_ext_buf), __ilen); + _M_ext_next = _M_ext_buf + __ilen; + } + else + __ilen = __iend - this->eback(); + + // _M_codecvt->in may return error while __ilen > 0: this is + // ok, and actually occurs in case of mixed encodings (e.g., + // XML files). + if (__r == codecvt_base::error) + break; + + __rlen = 1; + } + while (__ilen == 0 && !__got_eof); + } + + if (__ilen > 0) + { + _M_set_buffer(__ilen); + _M_reading = true; + __ret = traits_type::to_int_type(*this->gptr()); + } + else if (__got_eof) + { + // If the actual end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without an + // intervening seek. + _M_set_buffer(-1); + _M_reading = false; + // However, reaching it while looping on partial means that + // the file has got an incomplete character. + if (__r == codecvt_base::partial) + __throw_ios_failure(__N("basic_filebuf::underflow " + "incomplete character in file")); + } + else if (__r == codecvt_base::error) + __throw_ios_failure(__N("basic_filebuf::underflow " + "invalid byte sequence in file")); + else + __throw_ios_failure(__N("basic_filebuf::underflow " + "error reading the file")); + } + return __ret; + } + + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + pbackfail(int_type __i) + { + int_type __ret = traits_type::eof(); + const bool __testin = _M_mode & ios_base::in; + if (__testin && !_M_writing) + { + // Remember whether the pback buffer is active, otherwise below + // we may try to store in it a second char (libstdc++/9761). + const bool __testpb = _M_pback_init; + const bool __testeof = traits_type::eq_int_type(__i, __ret); + int_type __tmp; + if (this->eback() < this->gptr()) + { + this->gbump(-1); + __tmp = traits_type::to_int_type(*this->gptr()); + } + else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1))) + { + __tmp = this->underflow(); + if (traits_type::eq_int_type(__tmp, __ret)) + return __ret; + } + else + { + // At the beginning of the buffer, need to make a + // putback position available. But the seek may fail + // (f.i., at the beginning of a file, see + // libstdc++/9439) and in that case we return + // traits_type::eof(). + return __ret; + } + + // Try to put back __i into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && traits_type::eq_int_type(__i, __tmp)) + __ret = __i; + else if (__testeof) + __ret = traits_type::not_eof(__i); + else if (!__testpb) + { + _M_create_pback(); + _M_reading = true; + *this->gptr() = traits_type::to_char_type(__i); + __ret = __i; + } + } + return __ret; + } + + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + overflow(int_type __c) + { + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(__c, __ret); + const bool __testout = _M_mode & ios_base::out; + if (__testout && !_M_reading) + { + if (this->pbase() < this->pptr()) + { + // If appropriate, append the overflow char. + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + + // Convert pending sequence to external representation, + // and output. + if (_M_convert_to_external(this->pbase(), + this->pptr() - this->pbase())) + { + _M_set_buffer(0); + __ret = traits_type::not_eof(__c); + } + } + else if (_M_buf_size > 1) + { + // Overflow in 'uncommitted' mode: set _M_writing, set + // the buffer to the initial 'write' mode, and put __c + // into the buffer. + _M_set_buffer(0); + _M_writing = true; + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + __ret = traits_type::not_eof(__c); + } + else + { + // Unbuffered. + char_type __conv = traits_type::to_char_type(__c); + if (__testeof || _M_convert_to_external(&__conv, 1)) + { + _M_writing = true; + __ret = traits_type::not_eof(__c); + } + } + } + return __ret; + } + + template<typename _CharT, typename _Traits> + bool + basic_filebuf<_CharT, _Traits>:: + _M_convert_to_external(_CharT* __ibuf, streamsize __ilen) + { + // Sizes of external and pending output. + streamsize __elen; + streamsize __plen; + if (__check_facet(_M_codecvt).always_noconv()) + { + __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen); + __plen = __ilen; + } + else + { + // Worst-case number of external bytes needed. + // XXX Not done encoding() == -1. + streamsize __blen = __ilen * _M_codecvt->max_length(); + char* __buf = static_cast<char*>(__builtin_alloca(__blen)); + + char* __bend; + const char_type* __iend; + codecvt_base::result __r; + __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, + __iend, __buf, __buf + __blen, __bend); + + if (__r == codecvt_base::ok || __r == codecvt_base::partial) + __blen = __bend - __buf; + else if (__r == codecvt_base::noconv) + { + // Same as the always_noconv case above. + __buf = reinterpret_cast<char*>(__ibuf); + __blen = __ilen; + } + else + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " + "conversion error")); + + __elen = _M_file.xsputn(__buf, __blen); + __plen = __blen; + + // Try once more for partial conversions. + if (__r == codecvt_base::partial && __elen == __plen) + { + const char_type* __iresume = __iend; + streamsize __rlen = this->pptr() - __iend; + __r = _M_codecvt->out(_M_state_cur, __iresume, + __iresume + __rlen, __iend, __buf, + __buf + __blen, __bend); + if (__r != codecvt_base::error) + { + __rlen = __bend - __buf; + __elen = _M_file.xsputn(__buf, __rlen); + __plen = __rlen; + } + else + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " + "conversion error")); + } + } + return __elen == __plen; + } + + template<typename _CharT, typename _Traits> + streamsize + basic_filebuf<_CharT, _Traits>:: + xsgetn(_CharT* __s, streamsize __n) + { + // Clear out pback buffer before going on to the real deal... + streamsize __ret = 0; + if (_M_pback_init) + { + if (__n > 0 && this->gptr() == this->eback()) + { + *__s++ = *this->gptr(); + this->gbump(1); + __ret = 1; + --__n; + } + _M_destroy_pback(); + } + + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n > __buflen we read directly instead of using the + // buffer repeatedly. + const bool __testin = _M_mode & ios_base::in; + const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; + + if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() + && __testin && !_M_writing) + { + // First, copy the chars already present in the buffer. + const streamsize __avail = this->egptr() - this->gptr(); + if (__avail != 0) + { + if (__avail == 1) + *__s = *this->gptr(); + else + traits_type::copy(__s, this->gptr(), __avail); + __s += __avail; + this->gbump(__avail); + __ret += __avail; + __n -= __avail; + } + + // Need to loop in case of short reads (relatively common + // with pipes). + streamsize __len; + for (;;) + { + __len = _M_file.xsgetn(reinterpret_cast<char*>(__s), + __n); + if (__len == -1) + __throw_ios_failure(__N("basic_filebuf::xsgetn " + "error reading the file")); + if (__len == 0) + break; + + __n -= __len; + __ret += __len; + if (__n == 0) + break; + + __s += __len; + } + + if (__n == 0) + { + _M_set_buffer(0); + _M_reading = true; + } + else if (__len == 0) + { + // If end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without + // an intervening seek. + _M_set_buffer(-1); + _M_reading = false; + } + } + else + __ret += __streambuf_type::xsgetn(__s, __n); + + return __ret; + } + + template<typename _CharT, typename _Traits> + streamsize + basic_filebuf<_CharT, _Traits>:: + xsputn(const _CharT* __s, streamsize __n) + { + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n is sufficiently large we write directly instead of + // using the buffer. + streamsize __ret = 0; + const bool __testout = _M_mode & ios_base::out; + if (__check_facet(_M_codecvt).always_noconv() + && __testout && !_M_reading) + { + // Measurement would reveal the best choice. + const streamsize __chunk = 1ul << 10; + streamsize __bufavail = this->epptr() - this->pptr(); + + // Don't mistake 'uncommitted' mode buffered with unbuffered. + if (!_M_writing && _M_buf_size > 1) + __bufavail = _M_buf_size - 1; + + const streamsize __limit = std::min(__chunk, __bufavail); + if (__n >= __limit) + { + const streamsize __buffill = this->pptr() - this->pbase(); + const char* __buf = reinterpret_cast<const char*>(this->pbase()); + __ret = _M_file.xsputn_2(__buf, __buffill, + reinterpret_cast<const char*>(__s), + __n); + if (__ret == __buffill + __n) + { + _M_set_buffer(0); + _M_writing = true; + } + if (__ret > __buffill) + __ret -= __buffill; + else + __ret = 0; + } + else + __ret = __streambuf_type::xsputn(__s, __n); + } + else + __ret = __streambuf_type::xsputn(__s, __n); + return __ret; + } + + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::__streambuf_type* + basic_filebuf<_CharT, _Traits>:: + setbuf(char_type* __s, streamsize __n) + { + if (!this->is_open()) + if (__s == 0 && __n == 0) + _M_buf_size = 1; + else if (__s && __n > 0) + { + // This is implementation-defined behavior, and assumes that + // an external char_type array of length __n exists and has + // been pre-allocated. If this is not the case, things will + // quickly blow up. When __n > 1, __n - 1 positions will be + // used for the get area, __n - 1 for the put area and 1 + // position to host the overflow char of a full put area. + // When __n == 1, 1 position will be used for the get area + // and 0 for the put area, as in the unbuffered case above. + _M_buf = __s; + _M_buf_size = __n; + } + return this; + } + + + // According to 27.8.1.4 p11 - 13, seekoff should ignore the last + // argument (of type openmode). + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) + { + int __width = 0; + if (_M_codecvt) + __width = _M_codecvt->encoding(); + if (__width < 0) + __width = 0; + + pos_type __ret = pos_type(off_type(-1)); + const bool __testfail = __off != 0 && __width <= 0; + if (this->is_open() && !__testfail) + { + // Ditch any pback buffers to avoid confusion. + _M_destroy_pback(); + + // Correct state at destination. Note that this is the correct + // state for the current position during output, because + // codecvt::unshift() returns the state to the initial state. + // This is also the correct state at the end of the file because + // an unshift sequence should have been written at the end. + __state_type __state = _M_state_beg; + off_type __computed_off = __off * __width; + if (_M_reading && __way == ios_base::cur) + { + if (_M_codecvt->always_noconv()) + __computed_off += this->gptr() - this->egptr(); + else + { + // Calculate offset from _M_ext_buf that corresponds + // to gptr(). Note: uses _M_state_last, which + // corresponds to eback(). + const int __gptr_off = + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, + this->gptr() - this->eback()); + __computed_off += _M_ext_buf + __gptr_off - _M_ext_end; + + // _M_state_last is modified by codecvt::length() so + // it now corresponds to gptr(). + __state = _M_state_last; + } + } + __ret = _M_seek(__computed_off, __way, __state); + } + return __ret; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 171. Strange seekpos() semantics due to joint position + // According to the resolution of DR 171, seekpos should ignore the last + // argument (of type openmode). + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + seekpos(pos_type __pos, ios_base::openmode) + { + pos_type __ret = pos_type(off_type(-1)); + if (this->is_open()) + { + // Ditch any pback buffers to avoid confusion. + _M_destroy_pback(); + __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state()); + } + return __ret; + } + + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state) + { + pos_type __ret = pos_type(off_type(-1)); + if (_M_terminate_output()) + { + // Returns pos_type(off_type(-1)) in case of failure. + __ret = pos_type(_M_file.seekoff(__off, __way)); + if (__ret != pos_type(off_type(-1))) + { + _M_reading = false; + _M_writing = false; + _M_ext_next = _M_ext_end = _M_ext_buf; + _M_set_buffer(-1); + _M_state_cur = __state; + __ret.state(_M_state_cur); + } + } + return __ret; + } + + template<typename _CharT, typename _Traits> + bool + basic_filebuf<_CharT, _Traits>:: + _M_terminate_output() + { + // Part one: update the output sequence. + bool __testvalid = true; + if (this->pbase() < this->pptr()) + { + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __testvalid = false; + } + + // Part two: output unshift sequence. + if (_M_writing && !__check_facet(_M_codecvt).always_noconv() + && __testvalid) + { + // Note: this value is arbitrary, since there is no way to + // get the length of the unshift sequence from codecvt, + // without calling unshift. + const size_t __blen = 128; + char __buf[__blen]; + codecvt_base::result __r; + streamsize __ilen = 0; + + do + { + char* __next; + __r = _M_codecvt->unshift(_M_state_cur, __buf, + __buf + __blen, __next); + if (__r == codecvt_base::error) + __testvalid = false; + else if (__r == codecvt_base::ok || + __r == codecvt_base::partial) + { + __ilen = __next - __buf; + if (__ilen > 0) + { + const streamsize __elen = _M_file.xsputn(__buf, __ilen); + if (__elen != __ilen) + __testvalid = false; + } + } + } + while (__r == codecvt_base::partial && __ilen > 0 && __testvalid); + + if (__testvalid) + { + // This second call to overflow() is required by the standard, + // but it's not clear why it's needed, since the output buffer + // should be empty by this point (it should have been emptied + // in the first call to overflow()). + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __testvalid = false; + } + } + return __testvalid; + } + + template<typename _CharT, typename _Traits> + int + basic_filebuf<_CharT, _Traits>:: + sync() + { + // Make sure that the internal buffer resyncs its idea of + // the file position with the external file. + int __ret = 0; + if (this->pbase() < this->pptr()) + { + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __ret = -1; + } + return __ret; + } + + template<typename _CharT, typename _Traits> + void + basic_filebuf<_CharT, _Traits>:: + imbue(const locale& __loc) + { + bool __testvalid = true; + + const __codecvt_type* _M_codecvt_tmp = 0; + if (__builtin_expect(has_facet<__codecvt_type>(__loc), true)) + _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc); + + if (this->is_open()) + { + // encoding() == -1 is ok only at the beginning. + if ((_M_reading || _M_writing) + && __check_facet(_M_codecvt).encoding() == -1) + __testvalid = false; + else + { + if (_M_reading) + { + if (__check_facet(_M_codecvt).always_noconv()) + { + if (_M_codecvt_tmp + && !__check_facet(_M_codecvt_tmp).always_noconv()) + __testvalid = this->seekoff(0, ios_base::cur, _M_mode) + != pos_type(off_type(-1)); + } + else + { + // External position corresponding to gptr(). + _M_ext_next = _M_ext_buf + + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, + this->gptr() - this->eback()); + const streamsize __remainder = _M_ext_end - _M_ext_next; + if (__remainder) + std::memmove(_M_ext_buf, _M_ext_next, __remainder); + + _M_ext_next = _M_ext_buf; + _M_ext_end = _M_ext_buf + __remainder; + _M_set_buffer(-1); + _M_state_last = _M_state_cur = _M_state_beg; + } + } + else if (_M_writing && (__testvalid = _M_terminate_output())) + _M_set_buffer(-1); + } + } + + if (__testvalid) + _M_codecvt = _M_codecvt_tmp; + else + _M_codecvt = 0; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_filebuf<char>; + extern template class basic_ifstream<char>; + extern template class basic_ofstream<char>; + extern template class basic_fstream<char>; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_filebuf<wchar_t>; + extern template class basic_ifstream<wchar_t>; + extern template class basic_ofstream<wchar_t>; + extern template class basic_fstream<wchar_t>; +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/functexcept.h b/libstdc++/include/bits/functexcept.h new file mode 100644 index 0000000..59358c4 --- /dev/null +++ b/libstdc++/include/bits/functexcept.h @@ -0,0 +1,95 @@ +// Function-Based Exception Support -*- C++ -*- + +// Copyright (C) 2001, 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. + +/** @file functexcept.h + * This header provides support for -fno-exceptions. + */ + +// +// ISO C++ 14882: 19.1 Exception classes +// + +#ifndef _FUNCTEXCEPT_H +#define _FUNCTEXCEPT_H 1 + +#include <bits/c++config.h> +#include <exception_defines.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Helper for exception objects in <except> + void + __throw_bad_exception(void) __attribute__((__noreturn__)); + + // Helper for exception objects in <new> + void + __throw_bad_alloc(void) __attribute__((__noreturn__)); + + // Helper for exception objects in <typeinfo> + void + __throw_bad_cast(void) __attribute__((__noreturn__)); + + void + __throw_bad_typeid(void) __attribute__((__noreturn__)); + + // Helpers for exception objects in <stdexcept> + void + __throw_logic_error(const char*) __attribute__((__noreturn__)); + + void + __throw_domain_error(const char*) __attribute__((__noreturn__)); + + void + __throw_invalid_argument(const char*) __attribute__((__noreturn__)); + + void + __throw_length_error(const char*) __attribute__((__noreturn__)); + + void + __throw_out_of_range(const char*) __attribute__((__noreturn__)); + + void + __throw_runtime_error(const char*) __attribute__((__noreturn__)); + + void + __throw_range_error(const char*) __attribute__((__noreturn__)); + + void + __throw_overflow_error(const char*) __attribute__((__noreturn__)); + + void + __throw_underflow_error(const char*) __attribute__((__noreturn__)); + + // Helpers for exception objects in basic_ios + void + __throw_ios_failure(const char*) __attribute__((__noreturn__)); + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/gslice.h b/libstdc++/include/bits/gslice.h new file mode 100644 index 0000000..12bfc32 --- /dev/null +++ b/libstdc++/include/bits/gslice.h @@ -0,0 +1,170 @@ +// The template and inlines for the -*- C++ -*- gslice class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file gslice.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _GSLICE_H +#define _GSLICE_H 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Class defining multi-dimensional subset of an array. + * + * The slice class represents a multi-dimensional subset of an array, + * specified by three parameter sets: start offset, size array, and stride + * array. The start offset is the index of the first element of the array + * that is part of the subset. The size and stride array describe each + * dimension of the slice. Size is the number of elements in that + * dimension, and stride is the distance in the array between successive + * elements in that dimension. Each dimension's size and stride is taken + * to begin at an array element described by the previous dimension. The + * size array and stride array must be the same size. + * + * For example, if you have offset==3, stride[0]==11, size[1]==3, + * stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6], + * slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17], + * slice[1,2]==array[20]. + */ + class gslice + { + public: + /// Construct an empty slice. + gslice (); + + /** + * @brief Construct a slice. + * + * Constructs a slice with as many dimensions as the length of the @a l + * and @a s arrays. + * + * @param o Offset in array of first element. + * @param l Array of dimension lengths. + * @param s Array of dimension strides between array elements. + */ + gslice(size_t, const valarray<size_t>&, const valarray<size_t>&); + + // XXX: the IS says the copy-ctor and copy-assignment operators are + // synthetized by the compiler but they are just unsuitable + // for a ref-counted semantic + /// Copy constructor. + gslice(const gslice&); + + /// Destructor. + ~gslice(); + + // XXX: See the note above. + /// Assignment operator. + gslice& operator=(const gslice&); + + /// Return array offset of first slice element. + size_t start() const; + + /// Return array of sizes of slice dimensions. + valarray<size_t> size() const; + + /// Return array of array strides for each dimension. + valarray<size_t> stride() const; + + private: + struct _Indexer + { + size_t _M_count; + size_t _M_start; + valarray<size_t> _M_size; + valarray<size_t> _M_stride; + valarray<size_t> _M_index; // Linear array of referenced indices + _Indexer(size_t, const valarray<size_t>&, + const valarray<size_t>&); + void + _M_increment_use() + { ++_M_count; } + + size_t + _M_decrement_use() + { return --_M_count; } + }; + + _Indexer* _M_index; + + template<typename _Tp> friend class valarray; + }; + + inline size_t + gslice::start () const + { return _M_index ? _M_index->_M_start : 0; } + + inline valarray<size_t> + gslice::size () const + { return _M_index ? _M_index->_M_size : valarray<size_t>(); } + + inline valarray<size_t> + gslice::stride () const + { return _M_index ? _M_index->_M_stride : valarray<size_t>(); } + + inline gslice::gslice () : _M_index(0) {} + + inline + gslice::gslice(size_t __o, const valarray<size_t>& __l, + const valarray<size_t>& __s) + : _M_index(new gslice::_Indexer(__o, __l, __s)) {} + + inline + gslice::gslice(const gslice& __g) : _M_index(__g._M_index) + { if (_M_index) _M_index->_M_increment_use(); } + + inline + gslice::~gslice() + { + if (_M_index && _M_index->_M_decrement_use() == 0) + delete _M_index; + } + + inline gslice& + gslice::operator= (const gslice& __g) + { + if (__g._M_index) + __g._M_index->_M_increment_use(); + if (_M_index && _M_index->_M_decrement_use() == 0) + delete _M_index; + _M_index = __g._M_index; + return *this; + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _GSLICE_H */ diff --git a/libstdc++/include/bits/gslice_array.h b/libstdc++/include/bits/gslice_array.h new file mode 100644 index 0000000..55ddc3b --- /dev/null +++ b/libstdc++/include/bits/gslice_array.h @@ -0,0 +1,214 @@ +// The template and inlines for the -*- C++ -*- gslice_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file gslice_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _GSLICE_ARRAY_H +#define _GSLICE_ARRAY_H 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Reference to multi-dimensional subset of an array. + * + * A gslice_array is a reference to the actual elements of an array + * specified by a gslice. The way to get a gslice_array is to call + * operator[](gslice) on a valarray. The returned gslice_array then + * permits carrying operations out on the referenced subset of elements in + * the original valarray. For example, operator+=(valarray) will add + * values to the subset of elements in the underlying valarray this + * gslice_array refers to. + * + * @param Tp Element type. + */ + template<typename _Tp> + class gslice_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + gslice_array(const gslice_array&); + + /// Assignment operator. Assigns slice elements to corresponding + /// elements of @a a. + gslice_array& operator=(const gslice_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator=(const _Tp&) const; + + template<class _Dom> + void operator=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator*=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator/=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator%=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator+=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator-=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator^=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator&=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator|=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator<<=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator>>=(const _Expr<_Dom, _Tp>&) const; + + private: + _Array<_Tp> _M_array; + const valarray<size_t>& _M_index; + + friend class valarray<_Tp>; + + gslice_array(_Array<_Tp>, const valarray<size_t>&); + + // not implemented + gslice_array(); + }; + + template<typename _Tp> + inline + gslice_array<_Tp>::gslice_array(_Array<_Tp> __a, + const valarray<size_t>& __i) + : _M_array(__a), _M_index(__i) {} + + template<typename _Tp> + inline + gslice_array<_Tp>::gslice_array(const gslice_array<_Tp>& __a) + : _M_array(__a._M_array), _M_index(__a._M_index) {} + + template<typename _Tp> + inline gslice_array<_Tp>& + gslice_array<_Tp>::operator=(const gslice_array<_Tp>& __a) + { + std::__valarray_copy(_Array<_Tp>(__a._M_array), + _Array<size_t>(__a._M_index), _M_index.size(), + _M_array, _Array<size_t>(_M_index)); + return *this; + } + + template<typename _Tp> + inline void + gslice_array<_Tp>::operator=(const _Tp& __t) const + { + std::__valarray_fill(_M_array, _Array<size_t>(_M_index), + _M_index.size(), __t); + } + + template<typename _Tp> + inline void + gslice_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { + std::__valarray_copy(_Array<_Tp>(__v), __v.size(), + _M_array, _Array<size_t>(_M_index)); + } + + template<typename _Tp> + template<class _Dom> + inline void + gslice_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const + { + std::__valarray_copy (__e, _M_index.size(), _M_array, + _Array<size_t>(_M_index)); + } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline void \ + gslice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ + { \ + _Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), \ + _Array<_Tp>(__v), __v.size()); \ + } \ + \ + template<typename _Tp> \ + template<class _Dom> \ + inline void \ + gslice_array<_Tp>::operator _Op##= (const _Expr<_Dom, _Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), __e,\ + _M_index.size()); \ + } + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +_GLIBCXX_END_NAMESPACE + +#endif /* _GSLICE_ARRAY_H */ diff --git a/libstdc++/include/bits/indirect_array.h b/libstdc++/include/bits/indirect_array.h new file mode 100644 index 0000000..d43d801 --- /dev/null +++ b/libstdc++/include/bits/indirect_array.h @@ -0,0 +1,208 @@ +// The template and inlines for the -*- C++ -*- indirect_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 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. + +/** @file indirect_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _INDIRECT_ARRAY_H +#define _INDIRECT_ARRAY_H 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Reference to arbitrary subset of an array. + * + * An indirect_array is a reference to the actual elements of an array + * specified by an ordered array of indices. The way to get an + * indirect_array is to call operator[](valarray<size_t>) on a valarray. + * The returned indirect_array then permits carrying operations out on the + * referenced subset of elements in the original valarray. + * + * For example, if an indirect_array is obtained using the array (4,2,0) as + * an argument, and then assigned to an array containing (1,2,3), then the + * underlying array will have array[0]==3, array[2]==2, and array[4]==1. + * + * @param Tp Element type. + */ + template <class _Tp> + class indirect_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + indirect_array(const indirect_array&); + + /// Assignment operator. Assigns elements to corresponding elements + /// of @a a. + indirect_array& operator=(const indirect_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator= (const _Tp&) const; + // ~indirect_array(); + + template<class _Dom> + void operator=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator*=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator/=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator%=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator+=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator-=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator^=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator&=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator|=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator<<=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator>>=(const _Expr<_Dom, _Tp>&) const; + + private: + /// Copy constructor. Both slices refer to the same underlying array. + indirect_array(_Array<_Tp>, size_t, _Array<size_t>); + + friend class valarray<_Tp>; + friend class gslice_array<_Tp>; + + const size_t _M_sz; + const _Array<size_t> _M_index; + const _Array<_Tp> _M_array; + + // not implemented + indirect_array(); + }; + + template<typename _Tp> + inline + indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a) + : _M_sz(__a._M_sz), _M_index(__a._M_index), _M_array(__a._M_array) {} + + template<typename _Tp> + inline + indirect_array<_Tp>::indirect_array(_Array<_Tp> __a, size_t __s, + _Array<size_t> __i) + : _M_sz(__s), _M_index(__i), _M_array(__a) {} + + template<typename _Tp> + inline indirect_array<_Tp>& + indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array, + _M_index); + return *this; + } + + template<typename _Tp> + inline void + indirect_array<_Tp>::operator=(const _Tp& __t) const + { std::__valarray_fill(_M_array, _M_index, _M_sz, __t); } + + template<typename _Tp> + inline void + indirect_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { std::__valarray_copy(_Array<_Tp>(__v), _M_sz, _M_array, _M_index); } + + template<typename _Tp> + template<class _Dom> + inline void + indirect_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const + { std::__valarray_copy(__e, _M_sz, _M_array, _M_index); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline void \ + indirect_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_index, _Array<_Tp>(__v), _M_sz); \ + } \ + \ + template<typename _Tp> \ + template<class _Dom> \ + inline void \ + indirect_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_index, __e, _M_sz); \ + } + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +_GLIBCXX_END_NAMESPACE + +#endif /* _INDIRECT_ARRAY_H */ diff --git a/libstdc++/include/bits/ios_base.h b/libstdc++/include/bits/ios_base.h new file mode 100644 index 0000000..33dc256 --- /dev/null +++ b/libstdc++/include/bits/ios_base.h @@ -0,0 +1,968 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file ios_base.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 27.4 Iostreams base classes +// + +#ifndef _IOS_BASE_H +#define _IOS_BASE_H 1 + +#pragma GCC system_header + +#include <ext/atomicity.h> +#include <bits/localefwd.h> +#include <bits/locale_classes.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // The following definitions of bitmask types are enums, not ints, + // as permitted (but not required) in the standard, in order to provide + // better type safety in iostream calls. A side effect is that + // expressions involving them are no longer compile-time constants. + enum _Ios_Fmtflags + { + _S_boolalpha = 1L << 0, + _S_dec = 1L << 1, + _S_fixed = 1L << 2, + _S_hex = 1L << 3, + _S_internal = 1L << 4, + _S_left = 1L << 5, + _S_oct = 1L << 6, + _S_right = 1L << 7, + _S_scientific = 1L << 8, + _S_showbase = 1L << 9, + _S_showpoint = 1L << 10, + _S_showpos = 1L << 11, + _S_skipws = 1L << 12, + _S_unitbuf = 1L << 13, + _S_uppercase = 1L << 14, + _S_adjustfield = _S_left | _S_right | _S_internal, + _S_basefield = _S_dec | _S_oct | _S_hex, + _S_floatfield = _S_scientific | _S_fixed, + _S_ios_fmtflags_end = 1L << 16 + }; + + inline _Ios_Fmtflags + operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast<int>(__a) & static_cast<int>(__b)); } + + inline _Ios_Fmtflags + operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast<int>(__a) | static_cast<int>(__b)); } + + inline _Ios_Fmtflags + operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast<int>(__a) ^ static_cast<int>(__b)); } + + inline _Ios_Fmtflags& + operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a | __b; } + + inline _Ios_Fmtflags& + operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a & __b; } + + inline _Ios_Fmtflags& + operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a ^ __b; } + + inline _Ios_Fmtflags + operator~(_Ios_Fmtflags __a) + { return _Ios_Fmtflags(~static_cast<int>(__a)); } + + + enum _Ios_Openmode + { + _S_app = 1L << 0, + _S_ate = 1L << 1, + _S_bin = 1L << 2, + _S_in = 1L << 3, + _S_out = 1L << 4, + _S_trunc = 1L << 5, + _S_ios_openmode_end = 1L << 16 + }; + + inline _Ios_Openmode + operator&(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast<int>(__a) & static_cast<int>(__b)); } + + inline _Ios_Openmode + operator|(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast<int>(__a) | static_cast<int>(__b)); } + + inline _Ios_Openmode + operator^(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast<int>(__a) ^ static_cast<int>(__b)); } + + inline _Ios_Openmode& + operator|=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a | __b; } + + inline _Ios_Openmode& + operator&=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a & __b; } + + inline _Ios_Openmode& + operator^=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a ^ __b; } + + inline _Ios_Openmode + operator~(_Ios_Openmode __a) + { return _Ios_Openmode(~static_cast<int>(__a)); } + + + enum _Ios_Iostate + { + _S_goodbit = 0, + _S_badbit = 1L << 0, + _S_eofbit = 1L << 1, + _S_failbit = 1L << 2, + _S_ios_iostate_end = 1L << 16 + }; + + inline _Ios_Iostate + operator&(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast<int>(__a) & static_cast<int>(__b)); } + + inline _Ios_Iostate + operator|(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast<int>(__a) | static_cast<int>(__b)); } + + inline _Ios_Iostate + operator^(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast<int>(__a) ^ static_cast<int>(__b)); } + + inline _Ios_Iostate& + operator|=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a | __b; } + + inline _Ios_Iostate& + operator&=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a & __b; } + + inline _Ios_Iostate& + operator^=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a ^ __b; } + + inline _Ios_Iostate + operator~(_Ios_Iostate __a) + { return _Ios_Iostate(~static_cast<int>(__a)); } + + enum _Ios_Seekdir + { + _S_beg = 0, + _S_cur = SEEK_CUR, + _S_end = SEEK_END, + _S_ios_seekdir_end = 1L << 16 + }; + + // 27.4.2 Class ios_base + /** + * @brief The base of the I/O class hierarchy. + * + * This class defines everything that can be defined about I/O that does + * not depend on the type of characters being input or output. Most + * people will only see @c ios_base when they need to specify the full + * name of the various I/O flags (e.g., the openmodes). + */ + class ios_base + { + public: + + // 27.4.2.1.1 Class ios_base::failure + /// These are thrown to indicate problems. Doc me. + class failure : public exception + { + public: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 48. Use of non-existent exception constructor + explicit + failure(const string& __str) throw(); + + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual + ~failure() throw(); + + virtual const char* + what() const throw(); + + private: + string _M_msg; + }; + + // 27.4.2.1.2 Type ios_base::fmtflags + /** + * @brief This is a bitmask type. + * + * @c "_Ios_Fmtflags" is implementation-defined, but it is valid to + * perform bitwise operations on these values and expect the Right + * Thing to happen. Defined objects of type fmtflags are: + * - boolalpha + * - dec + * - fixed + * - hex + * - internal + * - left + * - oct + * - right + * - scientific + * - showbase + * - showpoint + * - showpos + * - skipws + * - unitbuf + * - uppercase + * - adjustfield + * - basefield + * - floatfield + */ + typedef _Ios_Fmtflags fmtflags; + + /// Insert/extract @c bool in alphabetic rather than numeric format. + static const fmtflags boolalpha = _S_boolalpha; + + /// Converts integer input or generates integer output in decimal base. + static const fmtflags dec = _S_dec; + + /// Generate floating-point output in fixed-point notation. + static const fmtflags fixed = _S_fixed; + + /// Converts integer input or generates integer output in hexadecimal base. + static const fmtflags hex = _S_hex; + + /// Adds fill characters at a designated internal point in certain + /// generated output, or identical to @c right if no such point is + /// designated. + static const fmtflags internal = _S_internal; + + /// Adds fill characters on the right (final positions) of certain + /// generated output. (I.e., the thing you print is flush left.) + static const fmtflags left = _S_left; + + /// Converts integer input or generates integer output in octal base. + static const fmtflags oct = _S_oct; + + /// Adds fill characters on the left (initial positions) of certain + /// generated output. (I.e., the thing you print is flush right.) + static const fmtflags right = _S_right; + + /// Generates floating-point output in scientific notation. + static const fmtflags scientific = _S_scientific; + + /// Generates a prefix indicating the numeric base of generated integer + /// output. + static const fmtflags showbase = _S_showbase; + + /// Generates a decimal-point character unconditionally in generated + /// floating-point output. + static const fmtflags showpoint = _S_showpoint; + + /// Generates a + sign in non-negative generated numeric output. + static const fmtflags showpos = _S_showpos; + + /// Skips leading white space before certain input operations. + static const fmtflags skipws = _S_skipws; + + /// Flushes output after each output operation. + static const fmtflags unitbuf = _S_unitbuf; + + /// Replaces certain lowercase letters with their uppercase equivalents + /// in generated output. + static const fmtflags uppercase = _S_uppercase; + + /// A mask of left|right|internal. Useful for the 2-arg form of @c setf. + static const fmtflags adjustfield = _S_adjustfield; + + /// A mask of dec|oct|hex. Useful for the 2-arg form of @c setf. + static const fmtflags basefield = _S_basefield; + + /// A mask of scientific|fixed. Useful for the 2-arg form of @c setf. + static const fmtflags floatfield = _S_floatfield; + + // 27.4.2.1.3 Type ios_base::iostate + /** + * @brief This is a bitmask type. + * + * @c "_Ios_Iostate" is implementation-defined, but it is valid to + * perform bitwise operations on these values and expect the Right + * Thing to happen. Defined objects of type iostate are: + * - badbit + * - eofbit + * - failbit + * - goodbit + */ + typedef _Ios_Iostate iostate; + + /// Indicates a loss of integrity in an input or output sequence (such + /// as an irrecoverable read error from a file). + static const iostate badbit = _S_badbit; + + /// Indicates that an input operation reached the end of an input sequence. + static const iostate eofbit = _S_eofbit; + + /// Indicates that an input operation failed to read the expected + /// characters, or that an output operation failed to generate the + /// desired characters. + static const iostate failbit = _S_failbit; + + /// Indicates all is well. + static const iostate goodbit = _S_goodbit; + + // 27.4.2.1.4 Type ios_base::openmode + /** + * @brief This is a bitmask type. + * + * @c "_Ios_Openmode" is implementation-defined, but it is valid to + * perform bitwise operations on these values and expect the Right + * Thing to happen. Defined objects of type openmode are: + * - app + * - ate + * - binary + * - in + * - out + * - trunc + */ + typedef _Ios_Openmode openmode; + + /// Seek to end before each write. + static const openmode app = _S_app; + + /// Open and seek to end immediately after opening. + static const openmode ate = _S_ate; + + /// Perform input and output in binary mode (as opposed to text mode). + /// This is probably not what you think it is; see + /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#3 and + /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#7 for more. + static const openmode binary = _S_bin; + + /// Open for input. Default for @c ifstream and fstream. + static const openmode in = _S_in; + + /// Open for output. Default for @c ofstream and fstream. + static const openmode out = _S_out; + + /// Open for input. Default for @c ofstream. + static const openmode trunc = _S_trunc; + + // 27.4.2.1.5 Type ios_base::seekdir + /** + * @brief This is an enumerated type. + * + * @c "_Ios_Seekdir" is implementation-defined. Defined values + * of type seekdir are: + * - beg + * - cur, equivalent to @c SEEK_CUR in the C standard library. + * - end, equivalent to @c SEEK_END in the C standard library. + */ + typedef _Ios_Seekdir seekdir; + + /// Request a seek relative to the beginning of the stream. + static const seekdir beg = _S_beg; + + /// Request a seek relative to the current position within the sequence. + static const seekdir cur = _S_cur; + + /// Request a seek relative to the current end of the sequence. + static const seekdir end = _S_end; + + // Annex D.6 + typedef int io_state; + typedef int open_mode; + typedef int seek_dir; + + typedef std::streampos streampos; + typedef std::streamoff streamoff; + + // Callbacks; + /** + * @brief The set of events that may be passed to an event callback. + * + * erase_event is used during ~ios() and copyfmt(). imbue_event is used + * during imbue(). copyfmt_event is used during copyfmt(). + */ + enum event + { + erase_event, + imbue_event, + copyfmt_event + }; + + /** + * @brief The type of an event callback function. + * @param event One of the members of the event enum. + * @param ios_base Reference to the ios_base object. + * @param int The integer provided when the callback was registered. + * + * Event callbacks are user defined functions that get called during + * several ios_base and basic_ios functions, specifically imbue(), + * copyfmt(), and ~ios(). + */ + typedef void (*event_callback) (event, ios_base&, int); + + /** + * @brief Add the callback __fn with parameter __index. + * @param __fn The function to add. + * @param __index The integer to pass to the function when invoked. + * + * Registers a function as an event callback with an integer parameter to + * be passed to the function when invoked. Multiple copies of the + * function are allowed. If there are multiple callbacks, they are + * invoked in the order they were registered. + */ + void + register_callback(event_callback __fn, int __index); + + protected: + //@{ + /** + * @if maint + * ios_base data members (doc me) + * @endif + */ + streamsize _M_precision; + streamsize _M_width; + fmtflags _M_flags; + iostate _M_exception; + iostate _M_streambuf_state; + //@} + + // 27.4.2.6 Members for callbacks + // 27.4.2.6 ios_base callbacks + struct _Callback_list + { + // Data Members + _Callback_list* _M_next; + ios_base::event_callback _M_fn; + int _M_index; + _Atomic_word _M_refcount; // 0 means one reference. + + _Callback_list(ios_base::event_callback __fn, int __index, + _Callback_list* __cb) + : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { } + + void + _M_add_reference() { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } + + // 0 => OK to delete. + int + _M_remove_reference() + { return __gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1); } + }; + + _Callback_list* _M_callbacks; + + void + _M_call_callbacks(event __ev) throw(); + + void + _M_dispose_callbacks(void); + + // 27.4.2.5 Members for iword/pword storage + struct _Words + { + void* _M_pword; + long _M_iword; + _Words() : _M_pword(0), _M_iword(0) { } + }; + + // Only for failed iword/pword calls. + _Words _M_word_zero; + + // Guaranteed storage. + // The first 5 iword and pword slots are reserved for internal use. + enum { _S_local_word_size = 8 }; + _Words _M_local_word[_S_local_word_size]; + + // Allocated storage. + int _M_word_size; + _Words* _M_word; + + _Words& + _M_grow_words(int __index, bool __iword); + + // Members for locale and locale caching. + locale _M_ios_locale; + + void + _M_init(); + + public: + + // 27.4.2.1.6 Class ios_base::Init + // Used to initialize standard streams. In theory, g++ could use + // -finit-priority to order this stuff correctly without going + // through these machinations. + class Init + { + friend class ios_base; + public: + Init(); + ~Init(); + + private: + static _Atomic_word _S_refcount; + static bool _S_synced_with_stdio; + }; + + // [27.4.2.2] fmtflags state functions + /** + * @brief Access to format flags. + * @return The format control flags for both input and output. + */ + inline fmtflags + flags() const { return _M_flags; } + + /** + * @brief Setting new format flags all at once. + * @param fmtfl The new flags to set. + * @return The previous format control flags. + * + * This function overwrites all the format flags with @a fmtfl. + */ + inline fmtflags + flags(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags = __fmtfl; + return __old; + } + + /** + * @brief Setting new format flags. + * @param fmtfl Additional flags to set. + * @return The previous format control flags. + * + * This function sets additional flags in format control. Flags that + * were previously set remain set. + */ + inline fmtflags + setf(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags |= __fmtfl; + return __old; + } + + /** + * @brief Setting new format flags. + * @param fmtfl Additional flags to set. + * @param mask The flags mask for @a fmtfl. + * @return The previous format control flags. + * + * This function clears @a mask in the format flags, then sets + * @a fmtfl @c & @a mask. An example mask is @c ios_base::adjustfield. + */ + inline fmtflags + setf(fmtflags __fmtfl, fmtflags __mask) + { + fmtflags __old = _M_flags; + _M_flags &= ~__mask; + _M_flags |= (__fmtfl & __mask); + return __old; + } + + /** + * @brief Clearing format flags. + * @param mask The flags to unset. + * + * This function clears @a mask in the format flags. + */ + inline void + unsetf(fmtflags __mask) { _M_flags &= ~__mask; } + + /** + * @brief Flags access. + * @return The precision to generate on certain output operations. + * + * @if maint + * Be careful if you try to give a definition of "precision" here; see + * DR 189. + * @endif + */ + inline streamsize + precision() const { return _M_precision; } + + /** + * @brief Changing flags. + * @param prec The new precision value. + * @return The previous value of precision(). + */ + inline streamsize + precision(streamsize __prec) + { + streamsize __old = _M_precision; + _M_precision = __prec; + return __old; + } + + /** + * @brief Flags access. + * @return The minimum field width to generate on output operations. + * + * "Minimum field width" refers to the number of characters. + */ + inline streamsize + width() const { return _M_width; } + + /** + * @brief Changing flags. + * @param wide The new width value. + * @return The previous value of width(). + */ + inline streamsize + width(streamsize __wide) + { + streamsize __old = _M_width; + _M_width = __wide; + return __old; + } + + // [27.4.2.4] ios_base static members + /** + * @brief Interaction with the standard C I/O objects. + * @param sync Whether to synchronize or not. + * @return True if the standard streams were previously synchronized. + * + * The synchronization referred to is @e only that between the standard + * C facilities (e.g., stdout) and the standard C++ objects (e.g., + * cout). User-declared streams are unaffected. See + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#8 for more. + */ + static bool + sync_with_stdio(bool __sync = true); + + // [27.4.2.3] ios_base locale functions + /** + * @brief Setting a new locale. + * @param loc The new locale. + * @return The previous locale. + * + * Sets the new locale for this stream, and then invokes each callback + * with imbue_event. + */ + locale + imbue(const locale& __loc); + + /** + * @brief Locale access + * @return A copy of the current locale. + * + * If @c imbue(loc) has previously been called, then this function + * returns @c loc. Otherwise, it returns a copy of @c std::locale(), + * the global C++ locale. + */ + inline locale + getloc() const { return _M_ios_locale; } + + /** + * @brief Locale access + * @return A reference to the current locale. + * + * Like getloc above, but returns a reference instead of + * generating a copy. + */ + inline const locale& + _M_getloc() const { return _M_ios_locale; } + + // [27.4.2.5] ios_base storage functions + /** + * @brief Access to unique indices. + * @return An integer different from all previous calls. + * + * This function returns a unique integer every time it is called. It + * can be used for any purpose, but is primarily intended to be a unique + * index for the iword and pword functions. The expectation is that an + * application calls xalloc in order to obtain an index in the iword and + * pword arrays that can be used without fear of conflict. + * + * The implementation maintains a static variable that is incremented and + * returned on each invocation. xalloc is guaranteed to return an index + * that is safe to use in the iword and pword arrays. + */ + static int + xalloc() throw(); + + /** + * @brief Access to integer array. + * @param __ix Index into the array. + * @return A reference to an integer associated with the index. + * + * The iword function provides access to an array of integers that can be + * used for any purpose. The array grows as required to hold the + * supplied index. All integers in the array are initialized to 0. + * + * The implementation reserves several indices. You should use xalloc to + * obtain an index that is safe to use. Also note that since the array + * can grow dynamically, it is not safe to hold onto the reference. + */ + inline long& + iword(int __ix) + { + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, true); + return __word._M_iword; + } + + /** + * @brief Access to void pointer array. + * @param __ix Index into the array. + * @return A reference to a void* associated with the index. + * + * The pword function provides access to an array of pointers that can be + * used for any purpose. The array grows as required to hold the + * supplied index. All pointers in the array are initialized to 0. + * + * The implementation reserves several indices. You should use xalloc to + * obtain an index that is safe to use. Also note that since the array + * can grow dynamically, it is not safe to hold onto the reference. + */ + inline void*& + pword(int __ix) + { + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, false); + return __word._M_pword; + } + + // Destructor + /** + * Invokes each callback with erase_event. Destroys local storage. + * + * Note that the ios_base object for the standard streams never gets + * destroyed. As a result, any callbacks registered with the standard + * streams will not get invoked with erase_event (unless copyfmt is + * used). + */ + virtual ~ios_base(); + + protected: + ios_base(); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 50. Copy constructor and assignment operator of ios_base + private: + ios_base(const ios_base&); + + ios_base& + operator=(const ios_base&); + }; + + // [27.4.5.1] fmtflags manipulators + /// Calls base.setf(ios_base::boolalpha). + inline ios_base& + boolalpha(ios_base& __base) + { + __base.setf(ios_base::boolalpha); + return __base; + } + + /// Calls base.unsetf(ios_base::boolalpha). + inline ios_base& + noboolalpha(ios_base& __base) + { + __base.unsetf(ios_base::boolalpha); + return __base; + } + + /// Calls base.setf(ios_base::showbase). + inline ios_base& + showbase(ios_base& __base) + { + __base.setf(ios_base::showbase); + return __base; + } + + /// Calls base.unsetf(ios_base::showbase). + inline ios_base& + noshowbase(ios_base& __base) + { + __base.unsetf(ios_base::showbase); + return __base; + } + + /// Calls base.setf(ios_base::showpoint). + inline ios_base& + showpoint(ios_base& __base) + { + __base.setf(ios_base::showpoint); + return __base; + } + + /// Calls base.unsetf(ios_base::showpoint). + inline ios_base& + noshowpoint(ios_base& __base) + { + __base.unsetf(ios_base::showpoint); + return __base; + } + + /// Calls base.setf(ios_base::showpos). + inline ios_base& + showpos(ios_base& __base) + { + __base.setf(ios_base::showpos); + return __base; + } + + /// Calls base.unsetf(ios_base::showpos). + inline ios_base& + noshowpos(ios_base& __base) + { + __base.unsetf(ios_base::showpos); + return __base; + } + + /// Calls base.setf(ios_base::skipws). + inline ios_base& + skipws(ios_base& __base) + { + __base.setf(ios_base::skipws); + return __base; + } + + /// Calls base.unsetf(ios_base::skipws). + inline ios_base& + noskipws(ios_base& __base) + { + __base.unsetf(ios_base::skipws); + return __base; + } + + /// Calls base.setf(ios_base::uppercase). + inline ios_base& + uppercase(ios_base& __base) + { + __base.setf(ios_base::uppercase); + return __base; + } + + /// Calls base.unsetf(ios_base::uppercase). + inline ios_base& + nouppercase(ios_base& __base) + { + __base.unsetf(ios_base::uppercase); + return __base; + } + + /// Calls base.setf(ios_base::unitbuf). + inline ios_base& + unitbuf(ios_base& __base) + { + __base.setf(ios_base::unitbuf); + return __base; + } + + /// Calls base.unsetf(ios_base::unitbuf). + inline ios_base& + nounitbuf(ios_base& __base) + { + __base.unsetf(ios_base::unitbuf); + return __base; + } + + // [27.4.5.2] adjustfield anipulators + /// Calls base.setf(ios_base::internal, ios_base::adjustfield). + inline ios_base& + internal(ios_base& __base) + { + __base.setf(ios_base::internal, ios_base::adjustfield); + return __base; + } + + /// Calls base.setf(ios_base::left, ios_base::adjustfield). + inline ios_base& + left(ios_base& __base) + { + __base.setf(ios_base::left, ios_base::adjustfield); + return __base; + } + + /// Calls base.setf(ios_base::right, ios_base::adjustfield). + inline ios_base& + right(ios_base& __base) + { + __base.setf(ios_base::right, ios_base::adjustfield); + return __base; + } + + // [27.4.5.3] basefield anipulators + /// Calls base.setf(ios_base::dec, ios_base::basefield). + inline ios_base& + dec(ios_base& __base) + { + __base.setf(ios_base::dec, ios_base::basefield); + return __base; + } + + /// Calls base.setf(ios_base::hex, ios_base::basefield). + inline ios_base& + hex(ios_base& __base) + { + __base.setf(ios_base::hex, ios_base::basefield); + return __base; + } + + /// Calls base.setf(ios_base::oct, ios_base::basefield). + inline ios_base& + oct(ios_base& __base) + { + __base.setf(ios_base::oct, ios_base::basefield); + return __base; + } + + // [27.4.5.4] floatfield anipulators + /// Calls base.setf(ios_base::fixed, ios_base::floatfield). + inline ios_base& + fixed(ios_base& __base) + { + __base.setf(ios_base::fixed, ios_base::floatfield); + return __base; + } + + /// Calls base.setf(ios_base::scientific, ios_base::floatfield). + inline ios_base& + scientific(ios_base& __base) + { + __base.setf(ios_base::scientific, ios_base::floatfield); + return __base; + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _IOS_BASE_H */ + diff --git a/libstdc++/include/bits/istream.tcc b/libstdc++/include/bits/istream.tcc new file mode 100644 index 0000000..13facc4 --- /dev/null +++ b/libstdc++/include/bits/istream.tcc @@ -0,0 +1,1047 @@ +// istream classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, +// 2006, 2007 +// 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. + +/** @file istream.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +#ifndef _ISTREAM_TCC +#define _ISTREAM_TCC 1 + +#pragma GCC system_header + +#include <locale> +#include <ostream> // For flush() + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>::sentry:: + sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + if (__in.good()) + { + if (__in.tie()) + __in.tie()->flush(); + if (!__noskip && (__in.flags() & ios_base::skipws)) + { + const __int_type __eof = traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + const __ctype_type& __ct = __check_facet(__in._M_ctype); + while (!traits_type::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, + traits_type::to_char_type(__c))) + __c = __sb->snextc(); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 195. Should basic_istream::sentry's constructor ever + // set eofbit? + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + } + + if (__in.good() && __err == ios_base::goodbit) + _M_ok = true; + else + { + __err |= ios_base::failbit; + __in.setstate(__err); + } + } + + template<typename _CharT, typename _Traits> + template<typename _ValueT> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + _M_extract(_ValueT& __v) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __v); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(short& __n) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 118. basic_istream uses nonexistent num_get member functions. + long __l; + _M_extract(__l); + if (!this->fail()) + { + if (numeric_limits<short>::min() <= __l + && __l <= numeric_limits<short>::max()) + __n = __l; + else + this->setstate(ios_base::failbit); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(int& __n) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 118. basic_istream uses nonexistent num_get member functions. + long __l; + _M_extract(__l); + if (!this->fail()) + { + if (numeric_limits<int>::min() <= __l + && __l <= numeric_limits<int>::max()) + __n = __l; + else + this->setstate(ios_base::failbit); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__streambuf_type* __sbout) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, false); + if (__cerb && __sbout) + { + try + { + bool __ineof; + if (!__copy_streambufs_eof(this->rdbuf(), __sbout, __ineof)) + __err |= ios_base::failbit; + if (__ineof) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::failbit); } + } + else if (!__sbout) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template<typename _CharT, typename _Traits> + typename basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + get(void) + { + const int_type __eof = traits_type::eof(); + int_type __c = __eof; + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + __c = this->rdbuf()->sbumpc(); + // 27.6.1.1 paragraph 3 + if (!traits_type::eq_int_type(__c, __eof)) + _M_gcount = 1; + else + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return __c; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type& __c) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __cb = this->rdbuf()->sbumpc(); + // 27.6.1.1 paragraph 3 + if (!traits_type::eq_int_type(__cb, traits_type::eof())) + { + _M_gcount = 1; + __c = traits_type::to_char_type(__cb); + } + else + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->snextc(); + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 243. get and getline when sentry reports failure. + if (__n > 0) + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(__streambuf_type& __sb, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __this_sb = this->rdbuf(); + int_type __c = __this_sb->sgetc(); + char_type __c2 = traits_type::to_char_type(__c); + + while (!traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim) + && !traits_type::eq_int_type(__sb.sputc(__c2), __eof)) + { + ++_M_gcount; + __c = __this_sb->snextc(); + __c2 = traits_type::to_char_type(__c); + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + getline(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) + { + *__s++ = traits_type::to_char_type(__c); + __c = __sb->snextc(); + ++_M_gcount; + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else + { + if (traits_type::eq_int_type(__c, __idelim)) + { + __sb->sbumpc(); + ++_M_gcount; + } + else + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 243. get and getline when sentry reports failure. + if (__n > 0) + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + // We provide three overloads, since the first two are much simpler + // than the general case. Also, the latter two can thus adopt the + // same "batchy" strategy used by getline above. + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + ignore(void) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + + if (traits_type::eq_int_type(__sb->sbumpc(), __eof)) + __err |= ios_base::eofbit; + else + _M_gcount = 1; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + ignore(streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + // N.B. On LFS-enabled platforms streamsize is still 32 bits + // wide: if we want to implement the standard mandated behavior + // for n == max() (see 27.6.1.3/24) we are at risk of signed + // integer overflow: thus these contortions. Also note that, + // by definition, when more than 2G chars are actually ignored, + // _M_gcount (the return value of gcount, that is) cannot be + // really correct, being unavoidably too small. + bool __large_ignore = false; + while (true) + { + while (_M_gcount < __n + && !traits_type::eq_int_type(__c, __eof)) + { + ++_M_gcount; + __c = __sb->snextc(); + } + if (__n == numeric_limits<streamsize>::max() + && !traits_type::eq_int_type(__c, __eof)) + { + _M_gcount = numeric_limits<streamsize>::min(); + __large_ignore = true; + } + else + break; + } + + if (__large_ignore) + _M_gcount = numeric_limits<streamsize>::max(); + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + ignore(streamsize __n, int_type __delim) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + // See comment above. + bool __large_ignore = false; + while (true) + { + while (_M_gcount < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __delim)) + { + ++_M_gcount; + __c = __sb->snextc(); + } + if (__n == numeric_limits<streamsize>::max() + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __delim)) + { + _M_gcount = numeric_limits<streamsize>::min(); + __large_ignore = true; + } + else + break; + } + + if (__large_ignore) + _M_gcount = numeric_limits<streamsize>::max(); + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (traits_type::eq_int_type(__c, __delim)) + { + if (_M_gcount < numeric_limits<streamsize>::max()) + ++_M_gcount; + __sb->sbumpc(); + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<typename _CharT, typename _Traits> + typename basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + peek(void) + { + int_type __c = traits_type::eof(); + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + __c = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__c, traits_type::eof())) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return __c; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + read(char_type* __s, streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + _M_gcount = this->rdbuf()->sgetn(__s, __n); + if (_M_gcount != __n) + __err |= (ios_base::eofbit | ios_base::failbit); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<typename _CharT, typename _Traits> + streamsize + basic_istream<_CharT, _Traits>:: + readsome(char_type* __s, streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + // Cannot compare int_type with streamsize generically. + const streamsize __num = this->rdbuf()->in_avail(); + if (__num > 0) + _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n)); + else if (__num == -1) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return _M_gcount; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + putback(char_type __c) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 60. What is a formatted input function? + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb + || traits_type::eq_int_type(__sb->sputbackc(__c), __eof)) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + unget(void) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 60. What is a formatted input function? + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb + || traits_type::eq_int_type(__sb->sungetc(), __eof)) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<typename _CharT, typename _Traits> + int + basic_istream<_CharT, _Traits>:: + sync(void) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + int __ret = -1; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + __streambuf_type* __sb = this->rdbuf(); + if (__sb) + { + if (__sb->pubsync() == -1) + __err |= ios_base::badbit; + else + __ret = 0; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return __ret; + } + + template<typename _CharT, typename _Traits> + typename basic_istream<_CharT, _Traits>::pos_type + basic_istream<_CharT, _Traits>:: + tellg(void) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + pos_type __ret = pos_type(-1); + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, + ios_base::in); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(pos_type __pos) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::in); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(off_type __off, ios_base::seekdir __dir) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::in); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + // 27.6.1.2.3 Character extraction templates + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __int_type __cb = __in.rdbuf()->sbumpc(); + if (!_Traits::eq_int_type(__cb, _Traits::eof())) + __c = _Traits::to_char_type(__cb); + else + __err |= (ios_base::eofbit | ios_base::failbit); + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + if (__err) + __in.setstate(__err); + } + return __in; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename _Traits::int_type int_type; + typedef _CharT char_type; + typedef ctype<_CharT> __ctype_type; + + streamsize __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + // Figure out how many characters to extract. + streamsize __num = __in.width(); + if (__num <= 0) + __num = numeric_limits<streamsize>::max(); + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + + const int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + int_type __c = __sb->sgetc(); + + while (__extracted < __num - 1 + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, + _Traits::to_char_type(__c))) + { + *__s++ = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 68. Extractors for char* should store null at end + *__s = char_type(); + __in.width(0); + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + // 27.6.1.4 Standard basic_istream manipulators + template<typename _CharT, typename _Traits> + basic_istream<_CharT,_Traits>& + ws(basic_istream<_CharT,_Traits>& __in) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef typename __istream_type::int_type __int_type; + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (!_Traits::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, _Traits::to_char_type(__c))) + __c = __sb->snextc(); + + if (_Traits::eq_int_type(__c, __eof)) + __in.setstate(ios_base::eofbit); + return __in; + } + + // 21.3.7.9 basic_string::getline and operators + template<typename _CharT, typename _Traits, typename _Alloc> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const streamsize __w = __in.width(); + const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) + : __str.max_size(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + __in.width(0); + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + // 211. operator>>(istream&, string&) doesn't set failbit + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + try + { + __str.erase(); + const __int_type __idelim = _Traits::to_int_type(__delim); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !_Traits::eq_int_type(__c, __idelim)) + { + __str += _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (_Traits::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_istream<char>; + extern template istream& ws(istream&); + extern template istream& operator>>(istream&, char&); + extern template istream& operator>>(istream&, char*); + extern template istream& operator>>(istream&, unsigned char&); + extern template istream& operator>>(istream&, signed char&); + extern template istream& operator>>(istream&, unsigned char*); + extern template istream& operator>>(istream&, signed char*); + + extern template istream& istream::_M_extract(unsigned short&); + extern template istream& istream::_M_extract(unsigned int&); + extern template istream& istream::_M_extract(long&); + extern template istream& istream::_M_extract(unsigned long&); + extern template istream& istream::_M_extract(bool&); +#ifdef _GLIBCXX_USE_LONG_LONG + extern template istream& istream::_M_extract(long long&); + extern template istream& istream::_M_extract(unsigned long long&); +#endif + extern template istream& istream::_M_extract(float&); + extern template istream& istream::_M_extract(double&); + extern template istream& istream::_M_extract(long double&); + extern template istream& istream::_M_extract(void*&); + + extern template class basic_iostream<char>; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_istream<wchar_t>; + extern template wistream& ws(wistream&); + extern template wistream& operator>>(wistream&, wchar_t&); + extern template wistream& operator>>(wistream&, wchar_t*); + + extern template wistream& wistream::_M_extract(unsigned short&); + extern template wistream& wistream::_M_extract(unsigned int&); + extern template wistream& wistream::_M_extract(long&); + extern template wistream& wistream::_M_extract(unsigned long&); + extern template wistream& wistream::_M_extract(bool&); +#ifdef _GLIBCXX_USE_LONG_LONG + extern template wistream& wistream::_M_extract(long long&); + extern template wistream& wistream::_M_extract(unsigned long long&); +#endif + extern template wistream& wistream::_M_extract(float&); + extern template wistream& wistream::_M_extract(double&); + extern template wistream& wistream::_M_extract(long double&); + extern template wistream& wistream::_M_extract(void*&); + + extern template class basic_iostream<wchar_t>; +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/list.tcc b/libstdc++/include/bits/list.tcc new file mode 100644 index 0000000..f2849fb --- /dev/null +++ b/libstdc++/include/bits/list.tcc @@ -0,0 +1,385 @@ +// List implementation (out of line) -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file list.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LIST_TCC +#define _LIST_TCC 1 + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + template<typename _Tp, typename _Alloc> + void + _List_base<_Tp, _Alloc>:: + _M_clear() + { + typedef _List_node<_Tp> _Node; + _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next); + while (__cur != &this->_M_impl._M_node) + { + _Node* __tmp = __cur; + __cur = static_cast<_Node*>(__cur->_M_next); + _M_get_Tp_allocator().destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + } + + template<typename _Tp, typename _Alloc> + typename list<_Tp, _Alloc>::iterator + list<_Tp, _Alloc>:: + insert(iterator __position, const value_type& __x) + { + _Node* __tmp = _M_create_node(__x); + __tmp->hook(__position._M_node); + return iterator(__tmp); + } + + template<typename _Tp, typename _Alloc> + typename list<_Tp, _Alloc>::iterator + list<_Tp, _Alloc>:: + erase(iterator __position) + { + iterator __ret = iterator(__position._M_node->_M_next); + _M_erase(__position); + return __ret; + } + + template<typename _Tp, typename _Alloc> + void + list<_Tp, _Alloc>:: + resize(size_type __new_size, value_type __x) + { + iterator __i = begin(); + size_type __len = 0; + for (; __i != end() && __len < __new_size; ++__i, ++__len) + ; + if (__len == __new_size) + erase(__i, end()); + else // __i == end() + insert(end(), __new_size - __len, __x); + } + + template<typename _Tp, typename _Alloc> + list<_Tp, _Alloc>& + list<_Tp, _Alloc>:: + operator=(const list& __x) + { + if (this != &__x) + { + iterator __first1 = begin(); + iterator __last1 = end(); + const_iterator __first2 = __x.begin(); + const_iterator __last2 = __x.end(); + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + return *this; + } + + template<typename _Tp, typename _Alloc> + void + list<_Tp, _Alloc>:: + _M_fill_assign(size_type __n, const value_type& __val) + { + iterator __i = begin(); + for (; __i != end() && __n > 0; ++__i, --__n) + *__i = __val; + if (__n > 0) + insert(end(), __n, __val); + else + erase(__i, end()); + } + + template<typename _Tp, typename _Alloc> + template <typename _InputIterator> + void + list<_Tp, _Alloc>:: + _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2, + __false_type) + { + iterator __first1 = begin(); + iterator __last1 = end(); + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + + template<typename _Tp, typename _Alloc> + void + list<_Tp, _Alloc>:: + remove(const value_type& __value) + { + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) + { + iterator __next = __first; + ++__next; + if (*__first == __value) + _M_erase(__first); + __first = __next; + } + } + + template<typename _Tp, typename _Alloc> + void + list<_Tp, _Alloc>:: + unique() + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (*__first == *__next) + _M_erase(__next); + else + __first = __next; + __next = __first; + } + } + + template<typename _Tp, typename _Alloc> + void + list<_Tp, _Alloc>:: + merge(list& __x) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 300. list::merge() specification incomplete + if (this != &__x) + { + _M_check_equal_allocators(__x); + + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) + { + iterator __next = __first2; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } + } + + template<typename _Tp, typename _Alloc> + template <typename _StrictWeakOrdering> + void + list<_Tp, _Alloc>:: + merge(list& __x, _StrictWeakOrdering __comp) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 300. list::merge() specification incomplete + if (this != &__x) + { + _M_check_equal_allocators(__x); + + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) + { + iterator __next = __first2; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } + } + + template<typename _Tp, typename _Alloc> + void + list<_Tp, _Alloc>:: + sort() + { + // Do nothing if the list has length 0 or 1. + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + __counter != __fill && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge(*(__counter - 1)); + swap( *(__fill - 1) ); + } + } + + template<typename _Tp, typename _Alloc> + template <typename _Predicate> + void + list<_Tp, _Alloc>:: + remove_if(_Predicate __pred) + { + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) + { + iterator __next = __first; + ++__next; + if (__pred(*__first)) + _M_erase(__first); + __first = __next; + } + } + + template<typename _Tp, typename _Alloc> + template <typename _BinaryPredicate> + void + list<_Tp, _Alloc>:: + unique(_BinaryPredicate __binary_pred) + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(*__first, *__next)) + _M_erase(__next); + else + __first = __next; + __next = __first; + } + } + + template<typename _Tp, typename _Alloc> + template <typename _StrictWeakOrdering> + void + list<_Tp, _Alloc>:: + sort(_StrictWeakOrdering __comp) + { + // Do nothing if the list has length 0 or 1. + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + __counter != __fill && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry, __comp); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge(*(__counter - 1), __comp); + swap(*(__fill - 1)); + } + } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif /* _LIST_TCC */ + diff --git a/libstdc++/include/bits/locale_classes.h b/libstdc++/include/bits/locale_classes.h new file mode 100644 index 0000000..547e21d --- /dev/null +++ b/libstdc++/include/bits/locale_classes.h @@ -0,0 +1,582 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file locale_classes.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 22.1 Locales +// + +#ifndef _LOCALE_CLASSES_H +#define _LOCALE_CLASSES_H 1 + +#pragma GCC system_header + +#include <bits/localefwd.h> +#include <cstring> // For strcmp. +#include <string> +#include <ext/atomicity.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // 22.1.1 Class locale + /** + * @brief Container class for localization functionality. + * + * The locale class is first a class wrapper for C library locales. It is + * also an extensible container for user-defined localization. A locale is + * a collection of facets that implement various localization features such + * as money, time, and number printing. + * + * Constructing C++ locales does not change the C library locale. + * + * This library supports efficient construction and copying of locales + * through a reference counting implementation of the locale class. + */ + class locale + { + public: + // Types: + /// Definition of locale::category. + typedef int category; + + // Forward decls and friends: + class facet; + class id; + class _Impl; + + friend class facet; + friend class _Impl; + + template<typename _Facet> + friend bool + has_facet(const locale&) throw(); + + template<typename _Facet> + friend const _Facet& + use_facet(const locale&); + + template<typename _Cache> + friend struct __use_cache; + + //@{ + /** + * @brief Category values. + * + * The standard category values are none, ctype, numeric, collate, time, + * monetary, and messages. They form a bitmask that supports union and + * intersection. The category all is the union of these values. + * + * @if maint + * NB: Order must match _S_facet_categories definition in locale.cc + * @endif + */ + static const category none = 0; + static const category ctype = 1L << 0; + static const category numeric = 1L << 1; + static const category collate = 1L << 2; + static const category time = 1L << 3; + static const category monetary = 1L << 4; + static const category messages = 1L << 5; + static const category all = (ctype | numeric | collate | + time | monetary | messages); + //@} + + // Construct/copy/destroy: + + /** + * @brief Default constructor. + * + * Constructs a copy of the global locale. If no locale has been + * explicitly set, this is the "C" locale. + */ + locale() throw(); + + /** + * @brief Copy constructor. + * + * Constructs a copy of @a other. + * + * @param other The locale to copy. + */ + locale(const locale& __other) throw(); + + /** + * @brief Named locale constructor. + * + * Constructs a copy of the named C library locale. + * + * @param s Name of the locale to construct. + * @throw std::runtime_error if s is null or an undefined locale. + */ + explicit + locale(const char* __s); + + /** + * @brief Construct locale with facets from another locale. + * + * Constructs a copy of the locale @a base. The facets specified by @a + * cat are replaced with those from the locale named by @a s. If base is + * named, this locale instance will also be named. + * + * @param base The locale to copy. + * @param s Name of the locale to use facets from. + * @param cat Set of categories defining the facets to use from s. + * @throw std::runtime_error if s is null or an undefined locale. + */ + locale(const locale& __base, const char* __s, category __cat); + + /** + * @brief Construct locale with facets from another locale. + * + * Constructs a copy of the locale @a base. The facets specified by @a + * cat are replaced with those from the locale @a add. If @a base and @a + * add are named, this locale instance will also be named. + * + * @param base The locale to copy. + * @param add The locale to use facets from. + * @param cat Set of categories defining the facets to use from add. + */ + locale(const locale& __base, const locale& __add, category __cat); + + /** + * @brief Construct locale with another facet. + * + * Constructs a copy of the locale @a other. The facet @f is added to + * @other, replacing an existing facet of type Facet if there is one. If + * @f is null, this locale is a copy of @a other. + * + * @param other The locale to copy. + * @param f The facet to add in. + */ + template<typename _Facet> + locale(const locale& __other, _Facet* __f); + + /// Locale destructor. + ~locale() throw(); + + /** + * @brief Assignment operator. + * + * Set this locale to be a copy of @a other. + * + * @param other The locale to copy. + * @return A reference to this locale. + */ + const locale& + operator=(const locale& __other) throw(); + + /** + * @brief Construct locale with another facet. + * + * Constructs and returns a new copy of this locale. Adds or replaces an + * existing facet of type Facet from the locale @a other into the new + * locale. + * + * @param Facet The facet type to copy from other + * @param other The locale to copy from. + * @return Newly constructed locale. + * @throw std::runtime_error if other has no facet of type Facet. + */ + template<typename _Facet> + locale + combine(const locale& __other) const; + + // Locale operations: + /** + * @brief Return locale name. + * @return Locale name or "*" if unnamed. + */ + string + name() const; + + /** + * @brief Locale equality. + * + * @param other The locale to compare against. + * @return True if other and this refer to the same locale instance, are + * copies, or have the same name. False otherwise. + */ + bool + operator==(const locale& __other) const throw (); + + /** + * @brief Locale inequality. + * + * @param other The locale to compare against. + * @return ! (*this == other) + */ + inline bool + operator!=(const locale& __other) const throw () + { return !(this->operator==(__other)); } + + /** + * @brief Compare two strings according to collate. + * + * Template operator to compare two strings using the compare function of + * the collate facet in this locale. One use is to provide the locale to + * the sort function. For example, a vector v of strings could be sorted + * according to locale loc by doing: + * @code + * std::sort(v.begin(), v.end(), loc); + * @endcode + * + * @param s1 First string to compare. + * @param s2 Second string to compare. + * @return True if collate<Char> facet compares s1 < s2, else false. + */ + template<typename _Char, typename _Traits, typename _Alloc> + bool + operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, + const basic_string<_Char, _Traits, _Alloc>& __s2) const; + + // Global locale objects: + /** + * @brief Set global locale + * + * This function sets the global locale to the argument and returns a + * copy of the previous global locale. If the argument has a name, it + * will also call std::setlocale(LC_ALL, loc.name()). + * + * @param locale The new locale to make global. + * @return Copy of the old global locale. + */ + static locale + global(const locale&); + + /** + * @brief Return reference to the "C" locale. + */ + static const locale& + classic(); + + private: + // The (shared) implementation + _Impl* _M_impl; + + // The "C" reference locale + static _Impl* _S_classic; + + // Current global locale + static _Impl* _S_global; + + // Names of underlying locale categories. + // NB: locale::global() has to know how to modify all the + // underlying categories, not just the ones required by the C++ + // standard. + static const char* const* const _S_categories; + + // Number of standard categories. For C++, these categories are + // collate, ctype, monetary, numeric, time, and messages. These + // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE, + // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE + // 1003.1-2001) specifies LC_MESSAGES. + // In addition to the standard categories, the underlying + // operating system is allowed to define extra LC_* + // macros. For GNU systems, the following are also valid: + // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, + // and LC_IDENTIFICATION. + enum { _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES }; + +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif + + explicit + locale(_Impl*) throw(); + + static void + _S_initialize(); + + static void + _S_initialize_once(); + + static category + _S_normalize_category(category); + + void + _M_coalesce(const locale& __base, const locale& __add, category __cat); + }; + + + // 22.1.1.1.2 Class locale::facet + /** + * @brief Localization functionality base class. + * + * The facet class is the base class for a localization feature, such as + * money, time, and number printing. It provides common support for facets + * and reference management. + * + * Facets may not be copied or assigned. + */ + class locale::facet + { + private: + friend class locale; + friend class locale::_Impl; + + mutable _Atomic_word _M_refcount; + + // Contains data from the underlying "C" library for the classic locale. + static __c_locale _S_c_locale; + + // String literal for the name of the classic locale. + static const char _S_c_name[2]; + +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif + + static void + _S_initialize_once(); + + protected: + /** + * @brief Facet constructor. + * + * This is the constructor provided by the standard. If refs is 0, the + * facet is destroyed when the last referencing locale is destroyed. + * Otherwise the facet will never be destroyed. + * + * @param refs The initial value for reference count. + */ + explicit + facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0) + { } + + /// Facet destructor. + virtual + ~facet(); + + static void + _S_create_c_locale(__c_locale& __cloc, const char* __s, + __c_locale __old = 0); + + static __c_locale + _S_clone_c_locale(__c_locale& __cloc); + + static void + _S_destroy_c_locale(__c_locale& __cloc); + + // Returns data from the underlying "C" library data for the + // classic locale. + static __c_locale + _S_get_c_locale(); + + static const char* + _S_get_c_name(); + + private: + inline void + _M_add_reference() const throw() + { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } + + inline void + _M_remove_reference() const throw() + { + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1) + { + try + { delete this; } + catch (...) + { } + } + } + + facet(const facet&); // Not defined. + + facet& + operator=(const facet&); // Not defined. + }; + + + // 22.1.1.1.3 Class locale::id + /** + * @brief Facet ID class. + * + * The ID class provides facets with an index used to identify them. + * Every facet class must define a public static member locale::id, or be + * derived from a facet that provides this member, otherwise the facet + * cannot be used in a locale. The locale::id ensures that each class + * type gets a unique identifier. + */ + class locale::id + { + private: + friend class locale; + friend class locale::_Impl; + + template<typename _Facet> + friend const _Facet& + use_facet(const locale&); + + template<typename _Facet> + friend bool + has_facet(const locale&) throw (); + + // NB: There is no accessor for _M_index because it may be used + // before the constructor is run; the effect of calling a member + // function (even an inline) would be undefined. + mutable size_t _M_index; + + // Last id number assigned. + static _Atomic_word _S_refcount; + + void + operator=(const id&); // Not defined. + + id(const id&); // Not defined. + + public: + // NB: This class is always a static data member, and thus can be + // counted on to be zero-initialized. + /// Constructor. + id() { } + + size_t + _M_id() const; + }; + + + // Implementation object for locale. + class locale::_Impl + { + public: + // Friends. + friend class locale; + friend class locale::facet; + + template<typename _Facet> + friend bool + has_facet(const locale&) throw(); + + template<typename _Facet> + friend const _Facet& + use_facet(const locale&); + + template<typename _Cache> + friend struct __use_cache; + + private: + // Data Members. + _Atomic_word _M_refcount; + const facet** _M_facets; + size_t _M_facets_size; + const facet** _M_caches; + char** _M_names; + static const locale::id* const _S_id_ctype[]; + static const locale::id* const _S_id_numeric[]; + static const locale::id* const _S_id_collate[]; + static const locale::id* const _S_id_time[]; + static const locale::id* const _S_id_monetary[]; + static const locale::id* const _S_id_messages[]; + static const locale::id* const* const _S_facet_categories[]; + + inline void + _M_add_reference() throw() + { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } + + inline void + _M_remove_reference() throw() + { + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1) + { + try + { delete this; } + catch(...) + { } + } + } + + _Impl(const _Impl&, size_t); + _Impl(const char*, size_t); + _Impl(size_t) throw(); + + ~_Impl() throw(); + + _Impl(const _Impl&); // Not defined. + + void + operator=(const _Impl&); // Not defined. + + inline bool + _M_check_same_name() + { + bool __ret = true; + if (_M_names[1]) + // We must actually compare all the _M_names: can be all equal! + for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i) + __ret = std::strcmp(_M_names[__i], _M_names[__i + 1]) == 0; + return __ret; + } + + void + _M_replace_categories(const _Impl*, category); + + void + _M_replace_category(const _Impl*, const locale::id* const*); + + void + _M_replace_facet(const _Impl*, const locale::id*); + + void + _M_install_facet(const locale::id*, const facet*); + + template<typename _Facet> + inline void + _M_init_facet(_Facet* __facet) + { _M_install_facet(&_Facet::id, __facet); } + + void + _M_install_cache(const facet*, size_t); + }; + + template<typename _Facet> + locale::locale(const locale& __other, _Facet* __f) + { + _M_impl = new _Impl(*__other._M_impl, 1); + + try + { _M_impl->_M_install_facet(&_Facet::id, __f); } + catch(...) + { + _M_impl->_M_remove_reference(); + __throw_exception_again; + } + delete [] _M_impl->_M_names[0]; + _M_impl->_M_names[0] = 0; // Unnamed. + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/locale_facets.h b/libstdc++/include/bits/locale_facets.h new file mode 100644 index 0000000..e31ae17 --- /dev/null +++ b/libstdc++/include/bits/locale_facets.h @@ -0,0 +1,4688 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file locale_facets.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 22.1 Locales +// + +#ifndef _LOCALE_FACETS_H +#define _LOCALE_FACETS_H 1 + +#pragma GCC system_header + +#include <ctime> // For struct tm +#include <cwctype> // For wctype_t +#include <bits/ctype_base.h> +#include <iosfwd> +#include <bits/ios_base.h> // For ios_base, ios_base::iostate +#include <streambuf> +#include <bits/cpp_type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // NB: Don't instantiate required wchar_t facets if no wchar_t support. +#ifdef _GLIBCXX_USE_WCHAR_T +# define _GLIBCXX_NUM_FACETS 28 +#else +# define _GLIBCXX_NUM_FACETS 14 +#endif + + // Convert string to numeric value of type _Tv and store results. + // NB: This is specialized for all required types, there is no + // generic definition. + template<typename _Tv> + void + __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, + const __c_locale& __cloc); + + // Explicit specializations for required types. + template<> + void + __convert_to_v(const char*, float&, ios_base::iostate&, + const __c_locale&); + + template<> + void + __convert_to_v(const char*, double&, ios_base::iostate&, + const __c_locale&); + + template<> + void + __convert_to_v(const char*, long double&, ios_base::iostate&, + const __c_locale&); + + // NB: __pad is a struct, rather than a function, so it can be + // partially-specialized. + template<typename _CharT, typename _Traits> + struct __pad + { + static void + _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, + const _CharT* __olds, const streamsize __newlen, + const streamsize __oldlen, const bool __num); + }; + + // Used by both numeric and monetary facets. + // Inserts "group separator" characters into an array of characters. + // It's recursive, one iteration per group. It moves the characters + // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this + // only with __glen != 0. + template<typename _CharT> + _CharT* + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, + const _CharT* __first, const _CharT* __last); + + // This template permits specializing facet output code for + // ostreambuf_iterator. For ostreambuf_iterator, sputn is + // significantly more efficient than incrementing iterators. + template<typename _CharT> + inline + ostreambuf_iterator<_CharT> + __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len) + { + __s._M_put(__ws, __len); + return __s; + } + + // This is the unspecialized form of the template. + template<typename _CharT, typename _OutIter> + inline + _OutIter + __write(_OutIter __s, const _CharT* __ws, int __len) + { + for (int __j = 0; __j < __len; __j++, ++__s) + *__s = __ws[__j]; + return __s; + } + + + // 22.2.1.1 Template class ctype + // Include host and configuration specific ctype enums for ctype_base. + + // Common base for ctype<_CharT>. + /** + * @brief Common base for ctype facet + * + * This template class provides implementations of the public functions + * that forward to the protected virtual functions. + * + * This template also provides abtract stubs for the protected virtual + * functions. + */ + template<typename _CharT> + class __ctype_abstract_base : public locale::facet, public ctype_base + { + public: + // Types: + /// Typedef for the template parameter + typedef _CharT char_type; + + /** + * @brief Test char_type classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * It does so by returning the value of ctype<char_type>::do_is(). + * + * @param c The char_type to compare the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + bool + is(mask __m, char_type __c) const + { return this->do_is(__m, __c); } + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char_type in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the char array. It does so by returning the value of + * ctype<char_type>::do_is(). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + const char_type* + is(const char_type *__lo, const char_type *__hi, mask *__vec) const + { return this->do_is(__lo, __hi, __vec); } + + /** + * @brief Find char_type matching a mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is true. It does so by returning + * ctype<char_type>::do_scan_is(). + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to matching char_type if found, else @a hi. + */ + const char_type* + scan_is(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_is(__m, __lo, __hi); } + + /** + * @brief Find char_type not matching a mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is false. It does so by returning + * ctype<char_type>::do_scan_not(). + * + * @param m The mask to compare against. + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return Pointer to non-matching char if found, else @a hi. + */ + const char_type* + scan_not(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_not(__m, __lo, __hi); } + + /** + * @brief Convert to uppercase. + * + * This function converts the argument to uppercase if possible. + * If not possible (for example, '2'), returns the argument. It does + * so by returning ctype<char_type>::do_toupper(). + * + * @param c The char_type to convert. + * @return The uppercase char_type if convertible, else @a c. + */ + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } + + /** + * @brief Convert array to uppercase. + * + * This function converts each char_type in the range [lo,hi) to + * uppercase if possible. Other elements remain untouched. It does so + * by returning ctype<char_type>:: do_toupper(lo, hi). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + toupper(char_type *__lo, const char_type* __hi) const + { return this->do_toupper(__lo, __hi); } + + /** + * @brief Convert to lowercase. + * + * This function converts the argument to lowercase if possible. If + * not possible (for example, '2'), returns the argument. It does so + * by returning ctype<char_type>::do_tolower(c). + * + * @param c The char_type to convert. + * @return The lowercase char_type if convertible, else @a c. + */ + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } + + /** + * @brief Convert array to lowercase. + * + * This function converts each char_type in the range [lo,hi) to + * lowercase if possible. Other elements remain untouched. It does so + * by returning ctype<char_type>:: do_tolower(lo, hi). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + tolower(char_type* __lo, const char_type* __hi) const + { return this->do_tolower(__lo, __hi); } + + /** + * @brief Widen char to char_type + * + * This function converts the char argument to char_type using the + * simplest reasonable transformation. It does so by returning + * ctype<char_type>::do_widen(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted char_type. + */ + char_type + widen(char __c) const + { return this->do_widen(__c); } + + /** + * @brief Widen array to char_type + * + * This function converts each char in the input to char_type using the + * simplest reasonable transformation. It does so by returning + * ctype<char_type>::do_widen(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char* + widen(const char* __lo, const char* __hi, char_type* __to) const + { return this->do_widen(__lo, __hi, __to); } + + /** + * @brief Narrow char_type to char + * + * This function converts the char_type to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. It does so by returning + * ctype<char_type>::do_narrow(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char_type to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + char + narrow(char_type __c, char __dfault) const + { return this->do_narrow(__c, __dfault); } + + /** + * @brief Narrow array to char array + * + * This function converts each char_type in the input to char using the + * simplest reasonable transformation and writes the results to the + * destination array. For any char_type in the input that cannot be + * converted, @a dfault is used instead. It does so by returning + * ctype<char_type>::do_narrow(lo, hi, dfault, to). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char_type* + narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char *__to) const + { return this->do_narrow(__lo, __hi, __dfault, __to); } + + protected: + explicit + __ctype_abstract_base(size_t __refs = 0): facet(__refs) { } + + virtual + ~__ctype_abstract_base() { } + + /** + * @brief Test char_type classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param c The char_type to find the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + virtual bool + do_is(mask __m, char_type __c) const = 0; + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char_type in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the input. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, + mask* __vec) const = 0; + + /** + * @brief Find char_type matching mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is true. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching char_type if found, else @a hi. + */ + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; + + /** + * @brief Find char_type not matching mask + * + * This function searches for and returns a pointer to the first + * char_type c of [lo,hi) for which is(m,c) is false. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching char_type if found, else @a hi. + */ + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; + + /** + * @brief Convert to uppercase. + * + * This virtual function converts the char_type argument to uppercase + * if possible. If not possible (for example, '2'), returns the + * argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The char_type to convert. + * @return The uppercase char_type if convertible, else @a c. + */ + virtual char_type + do_toupper(char_type) const = 0; + + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each char_type in the range [lo,hi) + * to uppercase if possible. Other elements remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const = 0; + + /** + * @brief Convert to lowercase. + * + * This virtual function converts the argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The char_type to convert. + * @return The lowercase char_type if convertible, else @a c. + */ + virtual char_type + do_tolower(char_type) const = 0; + + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each char_type in the range [lo,hi) + * to lowercase if possible. Other elements remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const = 0; + + /** + * @brief Widen char + * + * This virtual function converts the char to char_type using the + * simplest reasonable transformation. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted char_type + */ + virtual char_type + do_widen(char) const = 0; + + /** + * @brief Widen char array + * + * This function converts each char in the input to char_type using the + * simplest reasonable transformation. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char* + do_widen(const char* __lo, const char* __hi, + char_type* __dest) const = 0; + + /** + * @brief Narrow char_type to char + * + * This virtual function converts the argument to char using the + * simplest reasonable transformation. If the conversion fails, dfault + * is returned instead. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char_type to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type, char __dfault) const = 0; + + /** + * @brief Narrow char_type array to char + * + * This virtual function converts each char_type in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any element in the input that + * cannot be converted, @a dfault is used instead. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __dest) const = 0; + }; + + // NB: Generic, mostly useless implementation. + /** + * @brief Template ctype facet + * + * This template class defines classification and conversion functions for + * character sets. It wraps <cctype> functionality. Ctype gets used by + * streams for many I/O operations. + * + * This template provides the protected virtual functions the developer + * will have to replace in a derived class or specialization to make a + * working facet. The public functions that access them are defined in + * __ctype_abstract_base, to allow for implementation flexibility. See + * ctype<wchar_t> for an example. The functions are documented in + * __ctype_abstract_base. + * + * Note: implementations are provided for all the protected virtual + * functions, but will likely not be useful. + */ + template<typename _CharT> + class ctype : public __ctype_abstract_base<_CharT> + { + public: + // Types: + typedef _CharT char_type; + typedef typename __ctype_abstract_base<_CharT>::mask mask; + + /// The facet id for ctype<char_type> + static locale::id id; + + explicit + ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } + + protected: + virtual + ~ctype(); + + virtual bool + do_is(mask __m, char_type __c) const; + + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; + + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; + + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const; + + virtual char_type + do_toupper(char_type __c) const; + + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + virtual char_type + do_tolower(char_type __c) const; + + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + virtual char_type + do_widen(char __c) const; + + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const; + + virtual char + do_narrow(char_type, char __dfault) const; + + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __dest) const; + }; + + template<typename _CharT> + locale::id ctype<_CharT>::id; + + // 22.2.1.3 ctype<char> specialization. + /** + * @brief The ctype<char> specialization. + * + * This class defines classification and conversion functions for + * the char type. It gets used by char streams for many I/O + * operations. The char specialization provides a number of + * optimizations as well. + */ + template<> + class ctype<char> : public locale::facet, public ctype_base + { + public: + // Types: + /// Typedef for the template parameter char. + typedef char char_type; + + protected: + // Data Members: + __c_locale _M_c_locale_ctype; + bool _M_del; + __to_type _M_toupper; + __to_type _M_tolower; + const mask* _M_table; + mutable char _M_widen_ok; + mutable char _M_widen[1 + static_cast<unsigned char>(-1)]; + mutable char _M_narrow[1 + static_cast<unsigned char>(-1)]; + mutable char _M_narrow_ok; // 0 uninitialized, 1 init, + // 2 memcpy can't be used + + public: + /// The facet id for ctype<char> + static locale::id id; + /// The size of the mask table. It is SCHAR_MAX + 1. + static const size_t table_size = 1 + static_cast<unsigned char>(-1); + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param table If non-zero, table is used as the per-char mask. + * Else classic_table() is used. + * @param del If true, passes ownership of table to this facet. + * @param refs Passed to the base facet class. + */ + explicit + ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); + + /** + * @brief Constructor performs static initialization. + * + * This constructor is used to construct the initial C locale facet. + * + * @param cloc Handle to C locale data. + * @param table If non-zero, table is used as the per-char mask. + * @param del If true, passes ownership of table to this facet. + * @param refs Passed to the base facet class. + */ + explicit + ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, + size_t __refs = 0); + + /** + * @brief Test char classification. + * + * This function compares the mask table[c] to @a m. + * + * @param c The char to compare the mask of. + * @param m The mask to compare against. + * @return True if m & table[c] is true, false otherwise. + */ + inline bool + is(mask __m, char __c) const; + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char in the range [lo, hi) and + * successively writes it to vec. vec must have as many elements as + * the char array. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + inline const char* + is(const char* __lo, const char* __hi, mask* __vec) const; + + /** + * @brief Find char matching a mask + * + * This function searches for and returns the first char in [lo,hi) for + * which is(m,char) is true. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching char if found, else @a hi. + */ + inline const char* + scan_is(mask __m, const char* __lo, const char* __hi) const; + + /** + * @brief Find char not matching a mask + * + * This function searches for and returns a pointer to the first char + * in [lo,hi) for which is(m,char) is false. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching char if found, else @a hi. + */ + inline const char* + scan_not(mask __m, const char* __lo, const char* __hi) const; + + /** + * @brief Convert to uppercase. + * + * This function converts the char argument to uppercase if possible. + * If not possible (for example, '2'), returns the argument. + * + * toupper() acts as if it returns ctype<char>::do_toupper(c). + * do_toupper() must always return the same result for the same input. + * + * @param c The char to convert. + * @return The uppercase char if convertible, else @a c. + */ + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } + + /** + * @brief Convert array to uppercase. + * + * This function converts each char in the range [lo,hi) to uppercase + * if possible. Other chars remain untouched. + * + * toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi). + * do_toupper() must always return the same result for the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + toupper(char_type *__lo, const char_type* __hi) const + { return this->do_toupper(__lo, __hi); } + + /** + * @brief Convert to lowercase. + * + * This function converts the char argument to lowercase if possible. + * If not possible (for example, '2'), returns the argument. + * + * tolower() acts as if it returns ctype<char>::do_tolower(c). + * do_tolower() must always return the same result for the same input. + * + * @param c The char to convert. + * @return The lowercase char if convertible, else @a c. + */ + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } + + /** + * @brief Convert array to lowercase. + * + * This function converts each char in the range [lo,hi) to lowercase + * if possible. Other chars remain untouched. + * + * tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi). + * do_tolower() must always return the same result for the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + tolower(char_type* __lo, const char_type* __hi) const + { return this->do_tolower(__lo, __hi); } + + /** + * @brief Widen char + * + * This function converts the char to char_type using the simplest + * reasonable transformation. For an underived ctype<char> facet, the + * argument will be returned unchanged. + * + * This function works as if it returns ctype<char>::do_widen(c). + * do_widen() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted character. + */ + char_type + widen(char __c) const + { + if (_M_widen_ok) + return _M_widen[static_cast<unsigned char>(__c)]; + this->_M_widen_init(); + return this->do_widen(__c); + } + + /** + * @brief Widen char array + * + * This function converts each char in the input to char using the + * simplest reasonable transformation. For an underived ctype<char> + * facet, the argument will be copied unchanged. + * + * This function works as if it returns ctype<char>::do_widen(c). + * do_widen() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char* + widen(const char* __lo, const char* __hi, char_type* __to) const + { + if (_M_widen_ok == 1) + { + memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_widen_ok) + _M_widen_init(); + return this->do_widen(__lo, __hi, __to); + } + + /** + * @brief Narrow char + * + * This function converts the char to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. For an underived ctype<char> facet, @a c + * will be returned unchanged. + * + * This function works as if it returns ctype<char>::do_narrow(c). + * do_narrow() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @param dfault Char to return if conversion fails. + * @return The converted character. + */ + char + narrow(char_type __c, char __dfault) const + { + if (_M_narrow[static_cast<unsigned char>(__c)]) + return _M_narrow[static_cast<unsigned char>(__c)]; + const char __t = do_narrow(__c, __dfault); + if (__t != __dfault) + _M_narrow[static_cast<unsigned char>(__c)] = __t; + return __t; + } + + /** + * @brief Narrow char array + * + * This function converts each char in the input to char using the + * simplest reasonable transformation and writes the results to the + * destination array. For any char in the input that cannot be + * converted, @a dfault is used instead. For an underived ctype<char> + * facet, the argument will be copied unchanged. + * + * This function works as if it returns ctype<char>::do_narrow(lo, hi, + * dfault, to). do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char_type* + narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char *__to) const + { + if (__builtin_expect(_M_narrow_ok == 1, true)) + { + memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_narrow_ok) + _M_narrow_init(); + return this->do_narrow(__lo, __hi, __dfault, __to); + } + + protected: + /// Returns a pointer to the mask table provided to the constructor, or + /// the default from classic_table() if none was provided. + const mask* + table() const throw() + { return _M_table; } + + /// Returns a pointer to the C locale mask table. + static const mask* + classic_table() throw(); + + /** + * @brief Destructor. + * + * This function deletes table() if @a del was true in the + * constructor. + */ + virtual + ~ctype(); + + /** + * @brief Convert to uppercase. + * + * This virtual function converts the char argument to uppercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The char to convert. + * @return The uppercase char if convertible, else @a c. + */ + virtual char_type + do_toupper(char_type) const; + + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each char in the range [lo,hi) to + * uppercase if possible. Other chars remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Convert to lowercase. + * + * This virtual function converts the char argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The char to convert. + * @return The lowercase char if convertible, else @a c. + */ + virtual char_type + do_tolower(char_type) const; + + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each char in the range [lo,hi) to + * lowercase if possible. Other chars remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Widen char + * + * This virtual function converts the char to char using the simplest + * reasonable transformation. For an underived ctype<char> facet, the + * argument will be returned unchanged. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted character. + */ + virtual char_type + do_widen(char __c) const + { return __c; } + + /** + * @brief Widen char array + * + * This function converts each char in the range [lo,hi) to char using + * the simplest reasonable transformation. For an underived + * ctype<char> facet, the argument will be copied unchanged. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const + { + memcpy(__dest, __lo, __hi - __lo); + return __hi; + } + + /** + * @brief Narrow char + * + * This virtual function converts the char to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. For an underived ctype<char> facet, @a c will be + * returned unchanged. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type __c, char) const + { return __c; } + + /** + * @brief Narrow char array to char array + * + * This virtual function converts each char in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any char in the input that + * cannot be converted, @a dfault is used instead. For an underived + * ctype<char> facet, the argument will be copied unchanged. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char, char* __dest) const + { + memcpy(__dest, __lo, __hi - __lo); + return __hi; + } + + private: + + void _M_widen_init() const + { + char __tmp[sizeof(_M_widen)]; + for (size_t __i = 0; __i < sizeof(_M_widen); ++__i) + __tmp[__i] = __i; + do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen); + + _M_widen_ok = 1; + // Set _M_widen_ok to 2 if memcpy can't be used. + if (memcmp(__tmp, _M_widen, sizeof(_M_widen))) + _M_widen_ok = 2; + } + + // Fill in the narrowing cache and flag whether all values are + // valid or not. _M_narrow_ok is set to 2 if memcpy can't + // be used. + void _M_narrow_init() const + { + char __tmp[sizeof(_M_narrow)]; + for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i) + __tmp[__i] = __i; + do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow); + + _M_narrow_ok = 1; + if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow))) + _M_narrow_ok = 2; + else + { + // Deal with the special case of zero: renarrow with a + // different default and compare. + char __c; + do_narrow(__tmp, __tmp + 1, 1, &__c); + if (__c == 1) + _M_narrow_ok = 2; + } + } + }; + + template<> + const ctype<char>& + use_facet<ctype<char> >(const locale& __loc); + +#ifdef _GLIBCXX_USE_WCHAR_T + // 22.2.1.3 ctype<wchar_t> specialization + /** + * @brief The ctype<wchar_t> specialization. + * + * This class defines classification and conversion functions for the + * wchar_t type. It gets used by wchar_t streams for many I/O operations. + * The wchar_t specialization provides a number of optimizations as well. + * + * ctype<wchar_t> inherits its public methods from + * __ctype_abstract_base<wchar_t>. + */ + template<> + class ctype<wchar_t> : public __ctype_abstract_base<wchar_t> + { + public: + // Types: + /// Typedef for the template parameter wchar_t. + typedef wchar_t char_type; + typedef wctype_t __wmask_type; + + protected: + __c_locale _M_c_locale_ctype; + + // Pre-computed narrowed and widened chars. + bool _M_narrow_ok; + char _M_narrow[128]; + wint_t _M_widen[1 + static_cast<unsigned char>(-1)]; + + // Pre-computed elements for do_is. + mask _M_bit[16]; + __wmask_type _M_wmask[16]; + + public: + // Data Members: + /// The facet id for ctype<wchar_t> + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + ctype(size_t __refs = 0); + + /** + * @brief Constructor performs static initialization. + * + * This constructor is used to construct the initial C locale facet. + * + * @param cloc Handle to C locale data. + * @param refs Passed to the base facet class. + */ + explicit + ctype(__c_locale __cloc, size_t __refs = 0); + + protected: + __wmask_type + _M_convert_to_wmask(const mask __m) const; + + /// Destructor + virtual + ~ctype(); + + /** + * @brief Test wchar_t classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param c The wchar_t to find the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + virtual bool + do_is(mask __m, char_type __c) const; + + /** + * @brief Return a mask array. + * + * This function finds the mask for each wchar_t in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the input. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; + + /** + * @brief Find wchar_t matching mask + * + * This function searches for and returns the first wchar_t c in + * [lo,hi) for which is(m,c) is true. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching wchar_t if found, else @a hi. + */ + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; + + /** + * @brief Find wchar_t not matching mask + * + * This function searches for and returns a pointer to the first + * wchar_t c of [lo,hi) for which is(m,c) is false. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching wchar_t if found, else @a hi. + */ + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const; + + /** + * @brief Convert to uppercase. + * + * This virtual function converts the wchar_t argument to uppercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The wchar_t to convert. + * @return The uppercase wchar_t if convertible, else @a c. + */ + virtual char_type + do_toupper(char_type) const; + + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * uppercase if possible. Other elements remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Convert to lowercase. + * + * This virtual function converts the argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The wchar_t to convert. + * @return The lowercase wchar_t if convertible, else @a c. + */ + virtual char_type + do_tolower(char_type) const; + + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * lowercase if possible. Other elements remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Widen char to wchar_t + * + * This virtual function converts the char to wchar_t using the + * simplest reasonable transformation. For an underived ctype<wchar_t> + * facet, the argument will be cast to wchar_t. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted wchar_t. + */ + virtual char_type + do_widen(char) const; + + /** + * @brief Widen char array to wchar_t array + * + * This function converts each char in the input to wchar_t using the + * simplest reasonable transformation. For an underived ctype<wchar_t> + * facet, the argument will be copied, casting each element to wchar_t. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const; + + /** + * @brief Narrow wchar_t to char + * + * This virtual function converts the argument to char using + * the simplest reasonable transformation. If the conversion + * fails, dfault is returned instead. For an underived + * ctype<wchar_t> facet, @a c will be cast to char and + * returned. + * + * do_narrow() is a hook for a derived facet to change the + * behavior of narrowing. do_narrow() must always return the + * same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The wchar_t to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type, char __dfault) const; + + /** + * @brief Narrow wchar_t array to char array + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any wchar_t in the input that + * cannot be converted, @a dfault is used instead. For an underived + * ctype<wchar_t> facet, the argument will be copied, casting each + * element to char. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __dest) const; + + // For use at construction time only. + void + _M_initialize_ctype(); + }; + + template<> + const ctype<wchar_t>& + use_facet<ctype<wchar_t> >(const locale& __loc); +#endif //_GLIBCXX_USE_WCHAR_T + + /// @brief class ctype_byname [22.2.1.2]. + template<typename _CharT> + class ctype_byname : public ctype<_CharT> + { + public: + typedef _CharT char_type; + + explicit + ctype_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~ctype_byname() { }; + }; + + /// 22.2.1.4 Class ctype_byname specializations. + template<> + ctype_byname<char>::ctype_byname(const char*, size_t refs); + + template<> + ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs); + +_GLIBCXX_END_NAMESPACE + +// Include host and configuration specific ctype inlines. +#include <bits/ctype_inline.h> + +// 22.2.1.5 Template class codecvt +#include <bits/codecvt.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // 22.2.2 The numeric category. + class __num_base + { + public: + // NB: Code depends on the order of _S_atoms_out elements. + // Below are the indices into _S_atoms_out. + enum + { + _S_ominus, + _S_oplus, + _S_ox, + _S_oX, + _S_odigits, + _S_odigits_end = _S_odigits + 16, + _S_oudigits = _S_odigits_end, + _S_oudigits_end = _S_oudigits + 16, + _S_oe = _S_odigits + 14, // For scientific notation, 'e' + _S_oE = _S_oudigits + 14, // For scientific notation, 'E' + _S_oend = _S_oudigits_end + }; + + // A list of valid numeric literals for output. This array + // contains chars that will be passed through the current locale's + // ctype<_CharT>.widen() and then used to render numbers. + // For the standard "C" locale, this is + // "-+xX0123456789abcdef0123456789ABCDEF". + static const char* _S_atoms_out; + + // String literal of acceptable (narrow) input, for num_get. + // "-+xX0123456789abcdefABCDEF" + static const char* _S_atoms_in; + + enum + { + _S_iminus, + _S_iplus, + _S_ix, + _S_iX, + _S_izero, + _S_ie = _S_izero + 14, + _S_iE = _S_izero + 20, + _S_iend = 26 + }; + + // num_put + // Construct and return valid scanf format for floating point types. + static void + _S_format_float(const ios_base& __io, char* __fptr, char __mod); + }; + + template<typename _CharT> + struct __numpunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + const _CharT* _M_truename; + size_t _M_truename_size; + const _CharT* _M_falsename; + size_t _M_falsename_size; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + + // A list of valid numeric literals for output: in the standard + // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF". + // This array contains the chars after having been passed + // through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms_out[__num_base::_S_oend]; + + // A list of valid numeric literals for input: in the standard + // "C" locale, this is "-+xX0123456789abcdefABCDEF" + // This array contains the chars after having been passed + // through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms_in[__num_base::_S_iend]; + + bool _M_allocated; + + __numpunct_cache(size_t __refs = 0) : facet(__refs), + _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), + _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL), + _M_falsename_size(0), _M_decimal_point(_CharT()), + _M_thousands_sep(_CharT()), _M_allocated(false) + { } + + ~__numpunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __numpunct_cache& + operator=(const __numpunct_cache&); + + explicit + __numpunct_cache(const __numpunct_cache&); + }; + + template<typename _CharT> + __numpunct_cache<_CharT>::~__numpunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_truename; + delete [] _M_falsename; + } + } + + /** + * @brief Numpunct facet. + * + * This facet stores several pieces of information related to printing and + * scanning numbers, such as the decimal point character. It takes a + * template parameter specifying the char type. The numpunct facet is + * used by streams for many I/O operations involving numbers. + * + * The numpunct template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from a numpunct facet. + */ + template<typename _CharT> + class numpunct : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + typedef __numpunct_cache<_CharT> __cache_type; + + protected: + __cache_type* _M_data; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Numpunct constructor. + * + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) + { _M_initialize_numpunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up the + * predefined locale facets. + * + * @param cache __numpunct_cache object. + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) + { _M_initialize_numpunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_data(NULL) + { _M_initialize_numpunct(__cloc); } + + /** + * @brief Return decimal point character. + * + * This function returns a char_type to use as a decimal point. It + * does so by returning returning + * numpunct<char_type>::do_decimal_point(). + * + * @return @a char_type representing a decimal point. + */ + char_type + decimal_point() const + { return this->do_decimal_point(); } + + /** + * @brief Return thousands separator character. + * + * This function returns a char_type to use as a thousands + * separator. It does so by returning returning + * numpunct<char_type>::do_thousands_sep(). + * + * @return char_type representing a thousands separator. + */ + char_type + thousands_sep() const + { return this->do_thousands_sep(); } + + /** + * @brief Return grouping specification. + * + * This function returns a string representing groupings for the + * integer part of a number. Groupings indicate where thousands + * separators should be inserted in the integer part of a number. + * + * Each char in the return string is interpret as an integer + * rather than a character. These numbers represent the number + * of digits in a group. The first char in the string + * represents the number of digits in the least significant + * group. If a char is negative, it indicates an unlimited + * number of digits for the group. If more chars from the + * string are required to group a number, the last char is used + * repeatedly. + * + * For example, if the grouping() returns "\003\002" and is + * applied to the number 123456789, this corresponds to + * 12,34,56,789. Note that if the string was "32", this would + * put more than 50 digits into the least significant group if + * the character set is ASCII. + * + * The string is returned by calling + * numpunct<char_type>::do_grouping(). + * + * @return string representing grouping specification. + */ + string + grouping() const + { return this->do_grouping(); } + + /** + * @brief Return string representation of bool true. + * + * This function returns a string_type containing the text + * representation for true bool variables. It does so by calling + * numpunct<char_type>::do_truename(). + * + * @return string_type representing printed form of true. + */ + string_type + truename() const + { return this->do_truename(); } + + /** + * @brief Return string representation of bool false. + * + * This function returns a string_type containing the text + * representation for false bool variables. It does so by calling + * numpunct<char_type>::do_falsename(). + * + * @return string_type representing printed form of false. + */ + string_type + falsename() const + { return this->do_falsename(); } + + protected: + /// Destructor. + virtual + ~numpunct(); + + /** + * @brief Return decimal point character. + * + * Returns a char_type to use as a decimal point. This function is a + * hook for derived classes to change the value returned. + * + * @return @a char_type representing a decimal point. + */ + virtual char_type + do_decimal_point() const + { return _M_data->_M_decimal_point; } + + /** + * @brief Return thousands separator character. + * + * Returns a char_type to use as a thousands separator. This function + * is a hook for derived classes to change the value returned. + * + * @return @a char_type representing a thousands separator. + */ + virtual char_type + do_thousands_sep() const + { return _M_data->_M_thousands_sep; } + + /** + * @brief Return grouping specification. + * + * Returns a string representing groupings for the integer part of a + * number. This function is a hook for derived classes to change the + * value returned. @see grouping() for details. + * + * @return String representing grouping specification. + */ + virtual string + do_grouping() const + { return _M_data->_M_grouping; } + + /** + * @brief Return string representation of bool true. + * + * Returns a string_type containing the text representation for true + * bool variables. This function is a hook for derived classes to + * change the value returned. + * + * @return string_type representing printed form of true. + */ + virtual string_type + do_truename() const + { return _M_data->_M_truename; } + + /** + * @brief Return string representation of bool false. + * + * Returns a string_type containing the text representation for false + * bool variables. This function is a hook for derived classes to + * change the value returned. + * + * @return string_type representing printed form of false. + */ + virtual string_type + do_falsename() const + { return _M_data->_M_falsename; } + + // For use at construction time only. + void + _M_initialize_numpunct(__c_locale __cloc = NULL); + }; + + template<typename _CharT> + locale::id numpunct<_CharT>::id; + + template<> + numpunct<char>::~numpunct(); + + template<> + void + numpunct<char>::_M_initialize_numpunct(__c_locale __cloc); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + numpunct<wchar_t>::~numpunct(); + + template<> + void + numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc); +#endif + + /// @brief class numpunct_byname [22.2.3.2]. + template<typename _CharT> + class numpunct_byname : public numpunct<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + numpunct_byname(const char* __s, size_t __refs = 0) + : numpunct<_CharT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_numpunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } + } + + protected: + virtual + ~numpunct_byname() { } + }; + +_GLIBCXX_BEGIN_LDBL_NAMESPACE + /** + * @brief Facet for parsing number strings. + * + * This facet encapsulates the code to parse and return a number + * from a string. It is used by the istream numeric extraction + * operators. + * + * The num_get template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the num_get facet. + */ + template<typename _CharT, typename _InIter> + class num_get : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + num_get(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Numeric parsing. + * + * Parses the input stream into the bool @a v. It does so by calling + * num_get::do_get(). + * + * If ios_base::boolalpha is set, attempts to read + * ctype<CharT>::truename() or ctype<CharT>::falsename(). Sets + * @a v to true or false if successful. Sets err to + * ios_base::failbit if reading the string fails. Sets err to + * ios_base::eofbit if the stream is emptied. + * + * If ios_base::boolalpha is not set, proceeds as with reading a long, + * except if the value is 1, sets @a v to true, if the value is 0, sets + * @a v to false, and otherwise set err to ios_base::failbit. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the integral variable @a v. It does so + * by calling num_get::do_get(). + * + * Parsing is affected by the flag settings in @a io. + * + * The basic parse is affected by the value of io.flags() & + * ios_base::basefield. If equal to ios_base::oct, parses like the + * scanf %o specifier. Else if equal to ios_base::hex, parses like %X + * specifier. Else if basefield equal to 0, parses like the %i + * specifier. Otherwise, parses like %d for signed and %u for unsigned + * types. The matching type length modifier is also used. + * + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } +#endif + //@} + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the integral variable @a v. It does so + * by calling num_get::do_get(). + * + * The input characters are parsed like the scanf %g specifier. The + * matching type length modifier is also used. + * + * The decimal point character used is numpunct::decimal_point(). + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + //@} + + /** + * @brief Numeric parsing. + * + * Parses the input stream into the pointer variable @a v. It does so + * by calling num_get::do_get(). + * + * The input characters are parsed like the scanf %p specifier. + * + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * Note that the digit grouping effect for pointers is a bit ambiguous + * in the standard and shouldn't be relied on. See DR 344. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + protected: + /// Destructor. + virtual ~num_get() { } + + iter_type + _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, + string& __xtrc) const; + + template<typename _ValueT> + iter_type + _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, + _ValueT& __v) const; + + template<typename _CharT2> + typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, int>::__type + _M_find(const _CharT2*, size_t __len, _CharT2 __c) const + { + int __ret = -1; + if (__len <= 10) + { + if (__c >= _CharT2('0') && __c < _CharT2(_CharT2('0') + __len)) + __ret = __c - _CharT2('0'); + } + else + { + if (__c >= _CharT2('0') && __c <= _CharT2('9')) + __ret = __c - _CharT2('0'); + else if (__c >= _CharT2('a') && __c <= _CharT2('f')) + __ret = 10 + (__c - _CharT2('a')); + else if (__c >= _CharT2('A') && __c <= _CharT2('F')) + __ret = 10 + (__c - _CharT2('A')); + } + return __ret; + } + + template<typename _CharT2> + typename __gnu_cxx::__enable_if<!__is_char<_CharT2>::__value, + int>::__type + _M_find(const _CharT2* __zero, size_t __len, _CharT2 __c) const + { + int __ret = -1; + const char_type* __q = char_traits<_CharT2>::find(__zero, __len, __c); + if (__q) + { + __ret = __q - __zero; + if (__ret > 15) + __ret -= 6; + } + return __ret; + } + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the variable @a v. This function is a + * hook for derived classes to change the value returned. @see get() + * for more details. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; + + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned short&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned int&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned long&) const; + +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + long long&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned long long&) const; +#endif + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + float&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + double&) const; + + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + __do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + double&) const; +#else + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + long double&) const; +#endif + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + void*&) const; + + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + long double&) const; +#endif + //@} + }; + + template<typename _CharT, typename _InIter> + locale::id num_get<_CharT, _InIter>::id; + + + /** + * @brief Facet for converting numbers to strings. + * + * This facet encapsulates the code to convert a number to a string. It is + * used by the ostream numeric insertion operators. + * + * The num_put template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the num_put facet. + */ + template<typename _CharT, typename _OutIter> + class num_put : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + num_put(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Numeric formatting. + * + * Formats the boolean @a v and inserts it into a stream. It does so + * by calling num_put::do_put(). + * + * If ios_base::boolalpha is set, writes ctype<CharT>::truename() or + * ctype<CharT>::falsename(). Otherwise formats @a v as an int. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const + { return this->do_put(__s, __f, __fill, __v); } + + //@{ + /** + * @brief Numeric formatting. + * + * Formats the integral value @a v and inserts it into a + * stream. It does so by calling num_put::do_put(). + * + * Formatting is affected by the flag settings in @a io. + * + * The basic format is affected by the value of io.flags() & + * ios_base::basefield. If equal to ios_base::oct, formats like the + * printf %o specifier. Else if equal to ios_base::hex, formats like + * %x or %X with ios_base::uppercase unset or set respectively. + * Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu + * for unsigned values. Note that if both oct and hex are set, neither + * will take effect. + * + * If ios_base::showpos is set, '+' is output before positive values. + * If ios_base::showbase is set, '0' precedes octal values (except 0) + * and '0[xX]' precedes hex values. + * + * Thousands separators are inserted according to numpunct::grouping() + * and numpunct::thousands_sep(). The decimal point character used is + * numpunct::decimal_point(). + * + * If io.width() is non-zero, enough @a fill characters are inserted to + * make the result at least that wide. If + * (io.flags() & ios_base::adjustfield) == ios_base::left, result is + * padded at the end. If ios_base::internal, then padding occurs + * immediately after either a '+' or '-' or after '0x' or '0X'. + * Otherwise, padding occurs at the beginning. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, long __v) const + { return this->do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + unsigned long __v) const + { return this->do_put(__s, __f, __fill, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const + { return this->do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + unsigned long long __v) const + { return this->do_put(__s, __f, __fill, __v); } +#endif + //@} + + //@{ + /** + * @brief Numeric formatting. + * + * Formats the floating point value @a v and inserts it into a stream. + * It does so by calling num_put::do_put(). + * + * Formatting is affected by the flag settings in @a io. + * + * The basic format is affected by the value of io.flags() & + * ios_base::floatfield. If equal to ios_base::fixed, formats like the + * printf %f specifier. Else if equal to ios_base::scientific, formats + * like %e or %E with ios_base::uppercase unset or set respectively. + * Otherwise, formats like %g or %G depending on uppercase. Note that + * if both fixed and scientific are set, the effect will also be like + * %g or %G. + * + * The output precision is given by io.precision(). This precision is + * capped at numeric_limits::digits10 + 2 (different for double and + * long double). The default precision is 6. + * + * If ios_base::showpos is set, '+' is output before positive values. + * If ios_base::showpoint is set, a decimal point will always be + * output. + * + * Thousands separators are inserted according to numpunct::grouping() + * and numpunct::thousands_sep(). The decimal point character used is + * numpunct::decimal_point(). + * + * If io.width() is non-zero, enough @a fill characters are inserted to + * make the result at least that wide. If + * (io.flags() & ios_base::adjustfield) == ios_base::left, result is + * padded at the end. If ios_base::internal, then padding occurs + * immediately after either a '+' or '-' or after '0x' or '0X'. + * Otherwise, padding occurs at the beginning. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, double __v) const + { return this->do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + long double __v) const + { return this->do_put(__s, __f, __fill, __v); } + //@} + + /** + * @brief Numeric formatting. + * + * Formats the pointer value @a v and inserts it into a stream. It + * does so by calling num_put::do_put(). + * + * This function formats @a v as an unsigned long with ios_base::hex + * and ios_base::showbase set. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + const void* __v) const + { return this->do_put(__s, __f, __fill, __v); } + + protected: + template<typename _ValueT> + iter_type + _M_insert_float(iter_type, ios_base& __io, char_type __fill, + char __mod, _ValueT __v) const; + + void + _M_group_float(const char* __grouping, size_t __grouping_size, + char_type __sep, const char_type* __p, char_type* __new, + char_type* __cs, int& __len) const; + + template<typename _ValueT> + iter_type + _M_insert_int(iter_type, ios_base& __io, char_type __fill, + _ValueT __v) const; + + void + _M_group_int(const char* __grouping, size_t __grouping_size, + char_type __sep, ios_base& __io, char_type* __new, + char_type* __cs, int& __len) const; + + void + _M_pad(char_type __fill, streamsize __w, ios_base& __io, + char_type* __new, const char_type* __cs, int& __len) const; + + /// Destructor. + virtual + ~num_put() { }; + + //@{ + /** + * @brief Numeric formatting. + * + * These functions do the work of formatting numeric values and + * inserting them into a stream. This function is a hook for derived + * classes to change the value returned. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, bool __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, unsigned long) const; + +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long long __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const; +#endif + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, double __v) const; + + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + __do_put(iter_type, ios_base&, char_type __fill, double __v) const; +#else + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long double __v) const; +#endif + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, const void* __v) const; + + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long double __v) const; +#endif + //@} + }; + + template <typename _CharT, typename _OutIter> + locale::id num_put<_CharT, _OutIter>::id; + +_GLIBCXX_END_LDBL_NAMESPACE + + /** + * @brief Facet for localized string comparison. + * + * This facet encapsulates the code to compare strings in a localized + * manner. + * + * The collate template uses protected virtual functions to provide + * the actual results. The public accessors forward the call to + * the virtual functions. These virtual functions are hooks for + * developers to implement the behavior they require from the + * collate facet. + */ + template<typename _CharT> + class collate : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + protected: + // Underlying "C" library locale information saved from + // initialization, needed by collate_byname as well. + __c_locale _M_c_locale_collate; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + collate(size_t __refs = 0) + : facet(__refs), _M_c_locale_collate(_S_get_c_locale()) + { } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param refs Passed to the base facet class. + */ + explicit + collate(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc)) + { } + + /** + * @brief Compare two strings. + * + * This function compares two strings and returns the result by calling + * collate::do_compare(). + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + int + compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const + { return this->do_compare(__lo1, __hi1, __lo2, __hi2); } + + /** + * @brief Transform string to comparable form. + * + * This function is a wrapper for strxfrm functionality. It takes the + * input string and returns a modified string that can be directly + * compared to other transformed strings. In the "C" locale, this + * function just returns a copy of the input string. In some other + * locales, it may replace two chars with one, change a char for + * another, etc. It does so by returning collate::do_transform(). + * + * @param lo Start of string. + * @param hi End of string. + * @return Transformed string_type. + */ + string_type + transform(const _CharT* __lo, const _CharT* __hi) const + { return this->do_transform(__lo, __hi); } + + /** + * @brief Return hash of a string. + * + * This function computes and returns a hash on the input string. It + * does so by returning collate::do_hash(). + * + * @param lo Start of string. + * @param hi End of string. + * @return Hash value. + */ + long + hash(const _CharT* __lo, const _CharT* __hi) const + { return this->do_hash(__lo, __hi); } + + // Used to abstract out _CharT bits in virtual member functions, below. + int + _M_compare(const _CharT*, const _CharT*) const; + + size_t + _M_transform(_CharT*, const _CharT*, size_t) const; + + protected: + /// Destructor. + virtual + ~collate() + { _S_destroy_c_locale(_M_c_locale_collate); } + + /** + * @brief Compare two strings. + * + * This function is a hook for derived classes to change the value + * returned. @see compare(). + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + virtual int + do_compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const; + + /** + * @brief Transform string to comparable form. + * + * This function is a hook for derived classes to change the value + * returned. + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + virtual string_type + do_transform(const _CharT* __lo, const _CharT* __hi) const; + + /** + * @brief Return hash of a string. + * + * This function computes and returns a hash on the input string. This + * function is a hook for derived classes to change the value returned. + * + * @param lo Start of string. + * @param hi End of string. + * @return Hash value. + */ + virtual long + do_hash(const _CharT* __lo, const _CharT* __hi) const; + }; + + template<typename _CharT> + locale::id collate<_CharT>::id; + + // Specializations. + template<> + int + collate<char>::_M_compare(const char*, const char*) const; + + template<> + size_t + collate<char>::_M_transform(char*, const char*, size_t) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + int + collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const; + + template<> + size_t + collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const; +#endif + + /// @brief class collate_byname [22.2.4.2]. + template<typename _CharT> + class collate_byname : public collate<_CharT> + { + public: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + explicit + collate_byname(const char* __s, size_t __refs = 0) + : collate<_CharT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_collate); + this->_S_create_c_locale(this->_M_c_locale_collate, __s); + } + } + + protected: + virtual + ~collate_byname() { } + }; + + + /** + * @brief Time format ordering data. + * + * This class provides an enum representing different orderings of day, + * month, and year. + */ + class time_base + { + public: + enum dateorder { no_order, dmy, mdy, ymd, ydm }; + }; + + template<typename _CharT> + struct __timepunct_cache : public locale::facet + { + // List of all known timezones, with GMT first. + static const _CharT* _S_timezones[14]; + + const _CharT* _M_date_format; + const _CharT* _M_date_era_format; + const _CharT* _M_time_format; + const _CharT* _M_time_era_format; + const _CharT* _M_date_time_format; + const _CharT* _M_date_time_era_format; + const _CharT* _M_am; + const _CharT* _M_pm; + const _CharT* _M_am_pm_format; + + // Day names, starting with "C"'s Sunday. + const _CharT* _M_day1; + const _CharT* _M_day2; + const _CharT* _M_day3; + const _CharT* _M_day4; + const _CharT* _M_day5; + const _CharT* _M_day6; + const _CharT* _M_day7; + + // Abbreviated day names, starting with "C"'s Sun. + const _CharT* _M_aday1; + const _CharT* _M_aday2; + const _CharT* _M_aday3; + const _CharT* _M_aday4; + const _CharT* _M_aday5; + const _CharT* _M_aday6; + const _CharT* _M_aday7; + + // Month names, starting with "C"'s January. + const _CharT* _M_month01; + const _CharT* _M_month02; + const _CharT* _M_month03; + const _CharT* _M_month04; + const _CharT* _M_month05; + const _CharT* _M_month06; + const _CharT* _M_month07; + const _CharT* _M_month08; + const _CharT* _M_month09; + const _CharT* _M_month10; + const _CharT* _M_month11; + const _CharT* _M_month12; + + // Abbreviated month names, starting with "C"'s Jan. + const _CharT* _M_amonth01; + const _CharT* _M_amonth02; + const _CharT* _M_amonth03; + const _CharT* _M_amonth04; + const _CharT* _M_amonth05; + const _CharT* _M_amonth06; + const _CharT* _M_amonth07; + const _CharT* _M_amonth08; + const _CharT* _M_amonth09; + const _CharT* _M_amonth10; + const _CharT* _M_amonth11; + const _CharT* _M_amonth12; + + bool _M_allocated; + + __timepunct_cache(size_t __refs = 0) : facet(__refs), + _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL), + _M_time_era_format(NULL), _M_date_time_format(NULL), + _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL), + _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL), + _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL), + _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL), + _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL), + _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL), + _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL), + _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL), + _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL), + _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL), + _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL), + _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false) + { } + + ~__timepunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __timepunct_cache& + operator=(const __timepunct_cache&); + + explicit + __timepunct_cache(const __timepunct_cache&); + }; + + template<typename _CharT> + __timepunct_cache<_CharT>::~__timepunct_cache() + { + if (_M_allocated) + { + // Unused. + } + } + + // Specializations. + template<> + const char* + __timepunct_cache<char>::_S_timezones[14]; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + const wchar_t* + __timepunct_cache<wchar_t>::_S_timezones[14]; +#endif + + // Generic. + template<typename _CharT> + const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; + + template<typename _CharT> + class __timepunct : public locale::facet + { + public: + // Types: + typedef _CharT __char_type; + typedef basic_string<_CharT> __string_type; + typedef __timepunct_cache<_CharT> __cache_type; + + protected: + __cache_type* _M_data; + __c_locale _M_c_locale_timepunct; + const char* _M_name_timepunct; + + public: + /// Numpunct facet id. + static locale::id id; + + explicit + __timepunct(size_t __refs = 0); + + explicit + __timepunct(__cache_type* __cache, size_t __refs = 0); + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit + __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); + + // FIXME: for error checking purposes _M_put should return the return + // value of strftime/wcsftime. + void + _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, + const tm* __tm) const; + + void + _M_date_formats(const _CharT** __date) const + { + // Always have default first. + __date[0] = _M_data->_M_date_format; + __date[1] = _M_data->_M_date_era_format; + } + + void + _M_time_formats(const _CharT** __time) const + { + // Always have default first. + __time[0] = _M_data->_M_time_format; + __time[1] = _M_data->_M_time_era_format; + } + + void + _M_date_time_formats(const _CharT** __dt) const + { + // Always have default first. + __dt[0] = _M_data->_M_date_time_format; + __dt[1] = _M_data->_M_date_time_era_format; + } + + void + _M_am_pm_format(const _CharT* __ampm) const + { __ampm = _M_data->_M_am_pm_format; } + + void + _M_am_pm(const _CharT** __ampm) const + { + __ampm[0] = _M_data->_M_am; + __ampm[1] = _M_data->_M_pm; + } + + void + _M_days(const _CharT** __days) const + { + __days[0] = _M_data->_M_day1; + __days[1] = _M_data->_M_day2; + __days[2] = _M_data->_M_day3; + __days[3] = _M_data->_M_day4; + __days[4] = _M_data->_M_day5; + __days[5] = _M_data->_M_day6; + __days[6] = _M_data->_M_day7; + } + + void + _M_days_abbreviated(const _CharT** __days) const + { + __days[0] = _M_data->_M_aday1; + __days[1] = _M_data->_M_aday2; + __days[2] = _M_data->_M_aday3; + __days[3] = _M_data->_M_aday4; + __days[4] = _M_data->_M_aday5; + __days[5] = _M_data->_M_aday6; + __days[6] = _M_data->_M_aday7; + } + + void + _M_months(const _CharT** __months) const + { + __months[0] = _M_data->_M_month01; + __months[1] = _M_data->_M_month02; + __months[2] = _M_data->_M_month03; + __months[3] = _M_data->_M_month04; + __months[4] = _M_data->_M_month05; + __months[5] = _M_data->_M_month06; + __months[6] = _M_data->_M_month07; + __months[7] = _M_data->_M_month08; + __months[8] = _M_data->_M_month09; + __months[9] = _M_data->_M_month10; + __months[10] = _M_data->_M_month11; + __months[11] = _M_data->_M_month12; + } + + void + _M_months_abbreviated(const _CharT** __months) const + { + __months[0] = _M_data->_M_amonth01; + __months[1] = _M_data->_M_amonth02; + __months[2] = _M_data->_M_amonth03; + __months[3] = _M_data->_M_amonth04; + __months[4] = _M_data->_M_amonth05; + __months[5] = _M_data->_M_amonth06; + __months[6] = _M_data->_M_amonth07; + __months[7] = _M_data->_M_amonth08; + __months[8] = _M_data->_M_amonth09; + __months[9] = _M_data->_M_amonth10; + __months[10] = _M_data->_M_amonth11; + __months[11] = _M_data->_M_amonth12; + } + + protected: + virtual + ~__timepunct(); + + // For use at construction time only. + void + _M_initialize_timepunct(__c_locale __cloc = NULL); + }; + + template<typename _CharT> + locale::id __timepunct<_CharT>::id; + + // Specializations. + template<> + void + __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc); + + template<> + void + __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + void + __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc); + + template<> + void + __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*, + const tm*) const; +#endif + +_GLIBCXX_END_NAMESPACE + + // Include host and configuration specific timepunct functions. + #include <bits/time_members.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Facet for parsing dates and times. + * + * This facet encapsulates the code to parse and return a date or + * time from a string. It is used by the istream numeric + * extraction operators. + * + * The time_get template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_get facet. + */ + template<typename _CharT, typename _InIter> + class time_get : public locale::facet, public time_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + //@} + typedef basic_string<_CharT> __string_type; + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_get(size_t __refs = 0) + : facet (__refs) { } + + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. If the format "x" for the associated + * locale uses other fields, this function returns + * timebase::dateorder::noorder. + * + * NOTE: The library always returns noorder at the moment. + * + * @return A member of timebase::dateorder. + */ + dateorder + date_order() const + { return this->do_date_order(); } + + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_time(). + * + * If there is a valid time string according to format "x", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the time string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + iter_type + get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_time(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_date(). + * + * If there is a valid date string according to format "X", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the date string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + iter_type + get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_date(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_weekday(). + * + * Parsing starts by parsing an abbreviated weekday name. If a valid + * abbreviation is followed by a character that would lead to the full + * weekday name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + iter_type + get_weekday(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_monthname(). + * + * Parsing starts by parsing an abbreviated month name. If a valid + * abbreviation is followed by a character that would lead to the full + * month name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= + * ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + iter_type + get_monthname(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. The result is + * returned by calling time_get::do_get_year(). + * + * 4 consecutive digits are interpreted as a full year. If there are + * exactly 2 consecutive digits, the library interprets this as the + * number of years since 1900. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + iter_type + get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_year(__beg, __end, __io, __err, __tm); } + + protected: + /// Destructor. + virtual + ~time_get() { } + + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. This function is a hook for derived + * classes to change the value returned. + * + * @return A member of timebase::dateorder. + */ + virtual dateorder + do_date_order() const; + + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_time() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + virtual iter_type + do_get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_date() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + virtual iter_type + do_get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_weekday() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + virtual iter_type + do_get_weekday(iter_type __beg, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_monthname() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + virtual iter_type + do_get_monthname(iter_type __beg, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. This function is a + * hook for derived classes to change the value returned. @see + * get_year() for details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + virtual iter_type + do_get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + // Extract numeric component of length __len. + iter_type + _M_extract_num(iter_type __beg, iter_type __end, int& __member, + int __min, int __max, size_t __len, + ios_base& __io, ios_base::iostate& __err) const; + + // Extract day or month name, or any unique array of string + // literals in a const _CharT* array. + iter_type + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const; + + // Extract on a component-by-component basis, via __format argument. + iter_type + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const; + }; + + template<typename _CharT, typename _InIter> + locale::id time_get<_CharT, _InIter>::id; + + /// @brief class time_get_byname [22.2.5.2]. + template<typename _CharT, typename _InIter> + class time_get_byname : public time_get<_CharT, _InIter> + { + public: + // Types: + typedef _CharT char_type; + typedef _InIter iter_type; + + explicit + time_get_byname(const char*, size_t __refs = 0) + : time_get<_CharT, _InIter>(__refs) { } + + protected: + virtual + ~time_get_byname() { } + }; + + /** + * @brief Facet for outputting dates and times. + * + * This facet encapsulates the code to format and output dates and times + * according to formats used by strftime(). + * + * The time_put template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_put facet. + */ + template<typename _CharT, typename _OutIter> + class time_put : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_put(size_t __refs = 0) + : facet(__refs) { } + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format string. The format string is interpreted as by + * strftime(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param beg Start of format string. + * @param end End of format string. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + const _CharT* __beg, const _CharT* __end) const; + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. The format and modifier + * are interpreted as by strftime(). It does so by returning + * time_put::do_put(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, + const tm* __tm, char __format, char __mod = 0) const + { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } + + protected: + /// Destructor. + virtual + ~time_put() + { } + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. This function is a hook + * for derived classes to change the value returned. @see put() for + * more details. + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + char __format, char __mod) const; + }; + + template<typename _CharT, typename _OutIter> + locale::id time_put<_CharT, _OutIter>::id; + + /// @brief class time_put_byname [22.2.5.4]. + template<typename _CharT, typename _OutIter> + class time_put_byname : public time_put<_CharT, _OutIter> + { + public: + // Types: + typedef _CharT char_type; + typedef _OutIter iter_type; + + explicit + time_put_byname(const char*, size_t __refs = 0) + : time_put<_CharT, _OutIter>(__refs) + { }; + + protected: + virtual + ~time_put_byname() { } + }; + + + /** + * @brief Money format ordering data. + * + * This class contains an ordered array of 4 fields to represent the + * pattern for formatting a money amount. Each field may contain one entry + * from the part enum. symbol, sign, and value must be present and the + * remaining field must contain either none or space. @see + * moneypunct::pos_format() and moneypunct::neg_format() for details of how + * these fields are interpreted. + */ + class money_base + { + public: + enum part { none, space, symbol, sign, value }; + struct pattern { char field[4]; }; + + static const pattern _S_default_pattern; + + enum + { + _S_minus, + _S_zero, + _S_end = 11 + }; + + // String literal of acceptable (narrow) input/output, for + // money_get/money_put. "-0123456789" + static const char* _S_atoms; + + // Construct and return valid pattern consisting of some combination of: + // space none symbol sign value + static pattern + _S_construct_pattern(char __precedes, char __space, char __posn); + }; + + template<typename _CharT, bool _Intl> + struct __moneypunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + const _CharT* _M_curr_symbol; + size_t _M_curr_symbol_size; + const _CharT* _M_positive_sign; + size_t _M_positive_sign_size; + const _CharT* _M_negative_sign; + size_t _M_negative_sign_size; + int _M_frac_digits; + money_base::pattern _M_pos_format; + money_base::pattern _M_neg_format; + + // A list of valid numeric literals for input and output: in the standard + // "C" locale, this is "-0123456789". This array contains the chars after + // having been passed through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms[money_base::_S_end]; + + bool _M_allocated; + + __moneypunct_cache(size_t __refs = 0) : facet(__refs), + _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), + _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), + _M_curr_symbol(NULL), _M_curr_symbol_size(0), + _M_positive_sign(NULL), _M_positive_sign_size(0), + _M_negative_sign(NULL), _M_negative_sign_size(0), + _M_frac_digits(0), + _M_pos_format(money_base::pattern()), + _M_neg_format(money_base::pattern()), _M_allocated(false) + { } + + ~__moneypunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __moneypunct_cache& + operator=(const __moneypunct_cache&); + + explicit + __moneypunct_cache(const __moneypunct_cache&); + }; + + template<typename _CharT, bool _Intl> + __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_curr_symbol; + delete [] _M_positive_sign; + delete [] _M_negative_sign; + } + } + + /** + * @brief Facet for formatting data for money amounts. + * + * This facet encapsulates the punctuation, grouping and other formatting + * features of money amount string representations. + */ + template<typename _CharT, bool _Intl> + class moneypunct : public locale::facet, public money_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + typedef __moneypunct_cache<_CharT, _Intl> __cache_type; + + private: + __cache_type* _M_data; + + public: + /// This value is provided by the standard, but no reason for its + /// existence. + static const bool intl = _Intl; + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) + { _M_initialize_moneypunct(); } + + /** + * @brief Constructor performs initialization. + * + * This is an internal constructor. + * + * @param cache Cache for optimization. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) + { _M_initialize_moneypunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) + : facet(__refs), _M_data(NULL) + { _M_initialize_moneypunct(__cloc, __s); } + + /** + * @brief Return decimal point character. + * + * This function returns a char_type to use as a decimal point. It + * does so by returning returning + * moneypunct<char_type>::do_decimal_point(). + * + * @return @a char_type representing a decimal point. + */ + char_type + decimal_point() const + { return this->do_decimal_point(); } + + /** + * @brief Return thousands separator character. + * + * This function returns a char_type to use as a thousands + * separator. It does so by returning returning + * moneypunct<char_type>::do_thousands_sep(). + * + * @return char_type representing a thousands separator. + */ + char_type + thousands_sep() const + { return this->do_thousands_sep(); } + + /** + * @brief Return grouping specification. + * + * This function returns a string representing groupings for the + * integer part of an amount. Groupings indicate where thousands + * separators should be inserted. + * + * Each char in the return string is interpret as an integer rather + * than a character. These numbers represent the number of digits in a + * group. The first char in the string represents the number of digits + * in the least significant group. If a char is negative, it indicates + * an unlimited number of digits for the group. If more chars from the + * string are required to group a number, the last char is used + * repeatedly. + * + * For example, if the grouping() returns "\003\002" and is applied to + * the number 123456789, this corresponds to 12,34,56,789. Note that + * if the string was "32", this would put more than 50 digits into the + * least significant group if the character set is ASCII. + * + * The string is returned by calling + * moneypunct<char_type>::do_grouping(). + * + * @return string representing grouping specification. + */ + string + grouping() const + { return this->do_grouping(); } + + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. It + * does so by returning returning + * moneypunct<char_type>::do_curr_symbol(). + * + * @return @a string_type representing a currency symbol. + */ + string_type + curr_symbol() const + { return this->do_curr_symbol(); } + + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. It does so by returning returning + * moneypunct<char_type>::do_positive_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by pos_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a positive sign. + */ + string_type + positive_sign() const + { return this->do_positive_sign(); } + + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. It does so by returning returning + * moneypunct<char_type>::do_negative_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by neg_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a negative sign. + */ + string_type + negative_sign() const + { return this->do_negative_sign(); } + + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. It does so by returning + * returning moneypunct<char_type>::do_frac_digits(). + * + * The fractional part of a money amount is optional. But if it is + * present, there must be frac_digits() digits. + * + * @return Number of digits in amount fraction. + */ + int + frac_digits() const + { return this->do_frac_digits(); } + + //@{ + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive or negative valued money amount. It does so by returning + * returning moneypunct<char_type>::do_pos_format() or + * moneypunct<char_type>::do_neg_format(). + * + * The pattern has 4 fields describing the ordering of symbol, sign, + * value, and none or space. There must be one of each in the pattern. + * The none and space enums may not appear in the first field and space + * may not appear in the final field. + * + * The parts of a money string must appear in the order indicated by + * the fields of the pattern. The symbol field indicates that the + * value of curr_symbol() may be present. The sign field indicates + * that the value of positive_sign() or negative_sign() must be + * present. The value field indicates that the absolute value of the + * money amount is present. none indicates 0 or more whitespace + * characters, except at the end, where it permits no whitespace. + * space indicates that 1 or more whitespace characters must be + * present. + * + * For example, for the US locale and pos_format() pattern + * {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() == + * '+', and value 10.01, and options set to force the symbol, the + * corresponding string is "$+10.01". + * + * @return Pattern for money values. + */ + pattern + pos_format() const + { return this->do_pos_format(); } + + pattern + neg_format() const + { return this->do_neg_format(); } + //@} + + protected: + /// Destructor. + virtual + ~moneypunct(); + + /** + * @brief Return decimal point character. + * + * Returns a char_type to use as a decimal point. This function is a + * hook for derived classes to change the value returned. + * + * @return @a char_type representing a decimal point. + */ + virtual char_type + do_decimal_point() const + { return _M_data->_M_decimal_point; } + + /** + * @brief Return thousands separator character. + * + * Returns a char_type to use as a thousands separator. This function + * is a hook for derived classes to change the value returned. + * + * @return @a char_type representing a thousands separator. + */ + virtual char_type + do_thousands_sep() const + { return _M_data->_M_thousands_sep; } + + /** + * @brief Return grouping specification. + * + * Returns a string representing groupings for the integer part of a + * number. This function is a hook for derived classes to change the + * value returned. @see grouping() for details. + * + * @return String representing grouping specification. + */ + virtual string + do_grouping() const + { return _M_data->_M_grouping; } + + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. + * This function is a hook for derived classes to change the value + * returned. @see curr_symbol() for details. + * + * @return @a string_type representing a currency symbol. + */ + virtual string_type + do_curr_symbol() const + { return _M_data->_M_curr_symbol; } + + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. This function is a hook for derived classes to change the + * value returned. @see positive_sign() for details. + * + * @return @a string_type representing a positive sign. + */ + virtual string_type + do_positive_sign() const + { return _M_data->_M_positive_sign; } + + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. This function is a hook for derived classes to change the + * value returned. @see negative_sign() for details. + * + * @return @a string_type representing a negative sign. + */ + virtual string_type + do_negative_sign() const + { return _M_data->_M_negative_sign; } + + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. This function is a hook for + * derived classes to change the value returned. @see frac_digits() + * for details. + * + * @return Number of digits in amount fraction. + */ + virtual int + do_frac_digits() const + { return _M_data->_M_frac_digits; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive valued money amount. This function is a hook for derived + * classes to change the value returned. @see pos_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern + do_pos_format() const + { return _M_data->_M_pos_format; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * negative valued money amount. This function is a hook for derived + * classes to change the value returned. @see neg_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern + do_neg_format() const + { return _M_data->_M_neg_format; } + + // For use at construction time only. + void + _M_initialize_moneypunct(__c_locale __cloc = NULL, + const char* __name = NULL); + }; + + template<typename _CharT, bool _Intl> + locale::id moneypunct<_CharT, _Intl>::id; + + template<typename _CharT, bool _Intl> + const bool moneypunct<_CharT, _Intl>::intl; + + template<> + moneypunct<char, true>::~moneypunct(); + + template<> + moneypunct<char, false>::~moneypunct(); + + template<> + void + moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*); + + template<> + void + moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + moneypunct<wchar_t, true>::~moneypunct(); + + template<> + moneypunct<wchar_t, false>::~moneypunct(); + + template<> + void + moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale, + const char*); + + template<> + void + moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale, + const char*); +#endif + + /// @brief class moneypunct_byname [22.2.6.4]. + template<typename _CharT, bool _Intl> + class moneypunct_byname : public moneypunct<_CharT, _Intl> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + static const bool intl = _Intl; + + explicit + moneypunct_byname(const char* __s, size_t __refs = 0) + : moneypunct<_CharT, _Intl>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_moneypunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } + } + + protected: + virtual + ~moneypunct_byname() { } + }; + + template<typename _CharT, bool _Intl> + const bool moneypunct_byname<_CharT, _Intl>::intl; + +_GLIBCXX_BEGIN_LDBL_NAMESPACE + /** + * @brief Facet for parsing monetary amounts. + * + * This facet encapsulates the code to parse and return a monetary + * amount from a string. + * + * The money_get template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_get facet. + */ + template<typename _CharT, typename _InIter> + class money_get : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + typedef basic_string<_CharT> string_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_get(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a units as an integral + * value moneypunct::frac_digits() * the actual amount. For example, + * the string $10.01 in a US locale would store 1001 in @a units. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). @a units is + * unchanged if parsing fails. + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param units Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const + { return this->do_get(__s, __end, __intl, __io, __err, __units); } + + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a digits. For example, + * the string $10.01 in a US locale would store "1001" in @a digits. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param digits Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const + { return this->do_get(__s, __end, __intl, __io, __err, __digits); } + + protected: + /// Destructor. + virtual + ~money_get() { } + + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, double& __units) const; +#else + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const; +#endif + + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const; + + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const; +#endif + + template<bool _Intl> + iter_type + _M_extract(iter_type __s, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __digits) const; + }; + + template<typename _CharT, typename _InIter> + locale::id money_get<_CharT, _InIter>::id; + + /** + * @brief Facet for outputting monetary amounts. + * + * This facet encapsulates the code to format and output a monetary + * amount. + * + * The money_put template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_put facet. + */ + template<typename _CharT, typename _OutIter> + class money_put : public locale::facet + { + public: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + typedef basic_string<_CharT> string_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_put(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, bool __intl, ios_base& __io, + char_type __fill, long double __units) const + { return this->do_put(__s, __intl, __io, __fill, __units); } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, bool __intl, ios_base& __io, + char_type __fill, const string_type& __digits) const + { return this->do_put(__s, __intl, __io, __fill, __digits); } + + protected: + /// Destructor. + virtual + ~money_put() { } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + double __units) const; +#else + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const; +#endif + + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + const string_type& __digits) const; + + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const; +#endif + + template<bool _Intl> + iter_type + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const; + }; + + template<typename _CharT, typename _OutIter> + locale::id money_put<_CharT, _OutIter>::id; + +_GLIBCXX_END_LDBL_NAMESPACE + + /** + * @brief Messages facet base class providing catalog typedef. + */ + struct messages_base + { + typedef int catalog; + }; + + /** + * @brief Facet for handling message catalogs + * + * This facet encapsulates the code to retrieve messages from + * message catalogs. The only thing defined by the standard for this facet + * is the interface. All underlying functionality is + * implementation-defined. + * + * This library currently implements 3 versions of the message facet. The + * first version (gnu) is a wrapper around gettext, provided by libintl. + * The second version (ieee) is a wrapper around catgets. The final + * version (default) does no actual translation. These implementations are + * only provided for char and wchar_t instantiations. + * + * The messages template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the messages facet. + */ + template<typename _CharT> + class messages : public locale::facet, public messages_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + protected: + // Underlying "C" library locale information saved from + // initialization, needed by messages_byname as well. + __c_locale _M_c_locale_messages; + const char* _M_name_messages; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + messages(size_t __refs = 0); + + // Non-standard. + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Refcount to pass to the base class. + */ + explicit + messages(__c_locale __cloc, const char* __s, size_t __refs = 0); + + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog by + * returning do_open(s, loc). + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog + open(const basic_string<char>& __s, const locale& __loc) const + { return this->do_open(__s, __loc); } + + // Non-standard and unorthodox, yet effective. + /* + * @brief Open a message catalog. + * + * This non-standard function opens and returns a handle to a message + * catalog by returning do_open(s, loc). The third argument provides a + * message catalog root directory for gnu gettext and is ignored + * otherwise. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @param dir Message catalog root directory. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog + open(const basic_string<char>&, const locale&, const char*) const; + + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog by + * returning do_get(c, set, msgid, s). + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + string_type + get(catalog __c, int __set, int __msgid, const string_type& __s) const + { return this->do_get(__c, __set, __msgid, __s); } + + /* + * @brief Close a message catalog. + * + * Closes catalog @a c by calling do_close(c). + * + * @param c The catalog to close. + */ + void + close(catalog __c) const + { return this->do_close(__c); } + + protected: + /// Destructor. + virtual + ~messages(); + + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the opened catalog, value < 0 if open failed. + */ + virtual catalog + do_open(const basic_string<char>&, const locale&) const; + + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + virtual string_type + do_get(catalog, int, int, const string_type& __dfault) const; + + /* + * @brief Close a message catalog. + * + * @param c The catalog to close. + */ + virtual void + do_close(catalog) const; + + // Returns a locale and codeset-converted string, given a char* message. + char* + _M_convert_to_char(const string_type& __msg) const + { + // XXX + return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str())); + } + + // Returns a locale and codeset-converted string, given a char* message. + string_type + _M_convert_from_char(char*) const + { +#if 0 + // Length of message string without terminating null. + size_t __len = char_traits<char>::length(__msg) - 1; + + // "everybody can easily convert the string using + // mbsrtowcs/wcsrtombs or with iconv()" + + // Convert char* to _CharT in locale used to open catalog. + // XXX need additional template parameter on messages class for this.. + // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type; + typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type; + + __codecvt_type::state_type __state; + // XXX may need to initialize state. + //initialize_state(__state._M_init()); + + char* __from_next; + // XXX what size for this string? + _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1)); + const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv); + __cvt.out(__state, __msg, __msg + __len, __from_next, + __to, __to + __len + 1, __to_next); + return string_type(__to); +#endif +#if 0 + typedef ctype<_CharT> __ctype_type; + // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg); + const __ctype_type& __cvt = use_facet<__ctype_type>(locale()); + // XXX Again, proper length of converted string an issue here. + // For now, assume the converted length is not larger. + _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1)); + __cvt.widen(__msg, __msg + __len, __dest); + return basic_string<_CharT>(__dest); +#endif + return string_type(); + } + }; + + template<typename _CharT> + locale::id messages<_CharT>::id; + + // Specializations for required instantiations. + template<> + string + messages<char>::do_get(catalog, int, int, const string&) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + wstring + messages<wchar_t>::do_get(catalog, int, int, const wstring&) const; +#endif + + /// @brief class messages_byname [22.2.7.2]. + template<typename _CharT> + class messages_byname : public messages<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + messages_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~messages_byname() + { } + }; + +_GLIBCXX_END_NAMESPACE + + // Include host and configuration specific messages functions. + #include <bits/messages_members.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Subclause convenience interfaces, inlines. + // NB: These are inline because, when used in a loop, some compilers + // can hoist the body out of the loop; then it's just as fast as the + // C is*() function. + + /// Convenience interface to ctype.is(ctype_base::space, __c). + template<typename _CharT> + inline bool + isspace(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); } + + /// Convenience interface to ctype.is(ctype_base::print, __c). + template<typename _CharT> + inline bool + isprint(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); } + + /// Convenience interface to ctype.is(ctype_base::cntrl, __c). + template<typename _CharT> + inline bool + iscntrl(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); } + + /// Convenience interface to ctype.is(ctype_base::upper, __c). + template<typename _CharT> + inline bool + isupper(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); } + + /// Convenience interface to ctype.is(ctype_base::lower, __c). + template<typename _CharT> + inline bool + islower(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); } + + /// Convenience interface to ctype.is(ctype_base::alpha, __c). + template<typename _CharT> + inline bool + isalpha(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); } + + /// Convenience interface to ctype.is(ctype_base::digit, __c). + template<typename _CharT> + inline bool + isdigit(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); } + + /// Convenience interface to ctype.is(ctype_base::punct, __c). + template<typename _CharT> + inline bool + ispunct(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); } + + /// Convenience interface to ctype.is(ctype_base::xdigit, __c). + template<typename _CharT> + inline bool + isxdigit(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); } + + /// Convenience interface to ctype.is(ctype_base::alnum, __c). + template<typename _CharT> + inline bool + isalnum(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); } + + /// Convenience interface to ctype.is(ctype_base::graph, __c). + template<typename _CharT> + inline bool + isgraph(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); } + + /// Convenience interface to ctype.toupper(__c). + template<typename _CharT> + inline _CharT + toupper(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).toupper(__c); } + + /// Convenience interface to ctype.tolower(__c). + template<typename _CharT> + inline _CharT + tolower(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).tolower(__c); } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/locale_facets.tcc b/libstdc++/include/bits/locale_facets.tcc new file mode 100644 index 0000000..d3c47ff --- /dev/null +++ b/libstdc++/include/bits/locale_facets.tcc @@ -0,0 +1,2877 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file locale_facets.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LOCALE_FACETS_TCC +#define _LOCALE_FACETS_TCC 1 + +#pragma GCC system_header + +#include <limits> // For numeric_limits +#include <typeinfo> // For bad_cast. +#include <bits/streambuf_iterator.h> +#include <ext/type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _Facet> + locale + locale::combine(const locale& __other) const + { + _Impl* __tmp = new _Impl(*_M_impl, 1); + try + { + __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); + } + catch(...) + { + __tmp->_M_remove_reference(); + __throw_exception_again; + } + return locale(__tmp); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + bool + locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, + const basic_string<_CharT, _Traits, _Alloc>& __s2) const + { + typedef std::collate<_CharT> __collate_type; + const __collate_type& __collate = use_facet<__collate_type>(*this); + return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), + __s2.data(), __s2.data() + __s2.length()) < 0); + } + + /** + * @brief Test for the presence of a facet. + * + * has_facet tests the locale argument for the presence of the facet type + * provided as the template parameter. Facets derived from the facet + * parameter will also return true. + * + * @param Facet The facet type to test the presence of. + * @param locale The locale to test. + * @return true if locale contains a facet of type Facet, else false. + */ + template<typename _Facet> + inline bool + has_facet(const locale& __loc) throw() + { + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; + return (__i < __loc._M_impl->_M_facets_size && __facets[__i]); + } + + /** + * @brief Return a facet. + * + * use_facet looks for and returns a reference to a facet of type Facet + * where Facet is the template parameter. If has_facet(locale) is true, + * there is a suitable facet to return. It throws std::bad_cast if the + * locale doesn't contain a facet of type Facet. + * + * @param Facet The facet type to access. + * @param locale The locale to use. + * @return Reference to facet of type Facet. + * @throw std::bad_cast if locale doesn't contain a facet of type Facet. + */ + template<typename _Facet> + inline const _Facet& + use_facet(const locale& __loc) + { + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; + if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i])) + __throw_bad_cast(); + return static_cast<const _Facet&>(*__facets[__i]); + } + + // Routine to access a cache for the facet. If the cache didn't + // exist before, it gets constructed on the fly. + template<typename _Facet> + struct __use_cache + { + const _Facet* + operator() (const locale& __loc) const; + }; + + // Specializations. + template<typename _CharT> + struct __use_cache<__numpunct_cache<_CharT> > + { + const __numpunct_cache<_CharT>* + operator() (const locale& __loc) const + { + const size_t __i = numpunct<_CharT>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __numpunct_cache<_CharT>* __tmp = NULL; + try + { + __tmp = new __numpunct_cache<_CharT>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]); + } + }; + + template<typename _CharT, bool _Intl> + struct __use_cache<__moneypunct_cache<_CharT, _Intl> > + { + const __moneypunct_cache<_CharT, _Intl>* + operator() (const locale& __loc) const + { + const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __moneypunct_cache<_CharT, _Intl>* __tmp = NULL; + try + { + __tmp = new __moneypunct_cache<_CharT, _Intl>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast< + const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); + } + }; + + template<typename _CharT> + void + __numpunct_cache<_CharT>::_M_cache(const locale& __loc) + { + _M_allocated = true; + + const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); + + _M_grouping_size = __np.grouping().size(); + char* __grouping = new char[_M_grouping_size]; + __np.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = (_M_grouping_size + && static_cast<signed char>(__np.grouping()[0]) > 0); + + _M_truename_size = __np.truename().size(); + _CharT* __truename = new _CharT[_M_truename_size]; + __np.truename().copy(__truename, _M_truename_size); + _M_truename = __truename; + + _M_falsename_size = __np.falsename().size(); + _CharT* __falsename = new _CharT[_M_falsename_size]; + __np.falsename().copy(__falsename, _M_falsename_size); + _M_falsename = __falsename; + + _M_decimal_point = __np.decimal_point(); + _M_thousands_sep = __np.thousands_sep(); + + const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); + __ct.widen(__num_base::_S_atoms_out, + __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out); + __ct.widen(__num_base::_S_atoms_in, + __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in); + } + + template<typename _CharT, bool _Intl> + void + __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) + { + _M_allocated = true; + + const moneypunct<_CharT, _Intl>& __mp = + use_facet<moneypunct<_CharT, _Intl> >(__loc); + + _M_grouping_size = __mp.grouping().size(); + char* __grouping = new char[_M_grouping_size]; + __mp.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = (_M_grouping_size + && static_cast<signed char>(__mp.grouping()[0]) > 0); + + _M_decimal_point = __mp.decimal_point(); + _M_thousands_sep = __mp.thousands_sep(); + _M_frac_digits = __mp.frac_digits(); + + _M_curr_symbol_size = __mp.curr_symbol().size(); + _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size]; + __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); + _M_curr_symbol = __curr_symbol; + + _M_positive_sign_size = __mp.positive_sign().size(); + _CharT* __positive_sign = new _CharT[_M_positive_sign_size]; + __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); + _M_positive_sign = __positive_sign; + + _M_negative_sign_size = __mp.negative_sign().size(); + _CharT* __negative_sign = new _CharT[_M_negative_sign_size]; + __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); + _M_negative_sign = __negative_sign; + + _M_pos_format = __mp.pos_format(); + _M_neg_format = __mp.neg_format(); + + const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); + __ct.widen(money_base::_S_atoms, + money_base::_S_atoms + money_base::_S_end, _M_atoms); + } + + + // Used by both numeric and monetary facets. + // Check to make sure that the __grouping_tmp string constructed in + // money_get or num_get matches the canonical grouping for a given + // locale. + // __grouping_tmp is parsed L to R + // 1,222,444 == __grouping_tmp of "\1\3\3" + // __grouping is parsed R to L + // 1,222,444 == __grouping of "\3" == "\3\3\3" + static bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp); + +_GLIBCXX_BEGIN_LDBL_NAMESPACE + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, string& __xtrc) const + { + typedef char_traits<_CharT> __traits_type; + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + char_type __c = char_type(); + + // True if __beg becomes equal to __end. + bool __testeof = __beg == __end; + + // First check for sign. + if (!__testeof) + { + __c = *__beg; + const bool __plus = __c == __lit[__num_base::_S_iplus]; + if ((__plus || __c == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + { + __xtrc += __plus ? '+' : '-'; + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + } + + // Next, look for leading zeros. + bool __found_mantissa = false; + int __sep_pos = 0; + while (!__testeof) + { + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero]) + { + if (!__found_mantissa) + { + __xtrc += '0'; + __found_mantissa = true; + } + ++__sep_pos; + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + else + break; + } + + // Only need acceptable digits for floating point numbers. + bool __found_dec = false; + bool __found_sci = false; + string __found_grouping; + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); + const char_type* __lit_zero = __lit + __num_base::_S_izero; + + if (!__lc->_M_allocated) + // "C" locale + while (!__testeof) + { + const int __digit = _M_find(__lit_zero, 10, __c); + if (__digit != -1) + { + __xtrc += '0' + __digit; + __found_mantissa = true; + } + else if (__c == __lc->_M_decimal_point + && !__found_dec && !__found_sci) + { + __xtrc += '.'; + __found_dec = true; + } + else if ((__c == __lit[__num_base::_S_ie] + || __c == __lit[__num_base::_S_iE]) + && !__found_sci && __found_mantissa) + { + // Scientific notation. + __xtrc += 'e'; + __found_sci = true; + + // Remove optional plus or minus sign, if they exist. + if (++__beg != __end) + { + __c = *__beg; + const bool __plus = __c == __lit[__num_base::_S_iplus]; + if (__plus || __c == __lit[__num_base::_S_iminus]) + __xtrc += __plus ? '+' : '-'; + else + continue; + } + else + { + __testeof = true; + break; + } + } + else + break; + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + else + while (!__testeof) + { + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + if (!__found_dec && !__found_sci) + { + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast<char>(__sep_pos); + __sep_pos = 0; + } + else + { + // NB: __convert_to_v will not assign __v and will + // set the failbit. + __xtrc.clear(); + break; + } + } + else + break; + } + else if (__c == __lc->_M_decimal_point) + { + if (!__found_dec && !__found_sci) + { + // If no grouping chars are seen, no grouping check + // is applied. Therefore __found_grouping is adjusted + // only if decimal_point comes after some thousands_sep. + if (__found_grouping.size()) + __found_grouping += static_cast<char>(__sep_pos); + __xtrc += '.'; + __found_dec = true; + } + else + break; + } + else + { + const char_type* __q = + __traits_type::find(__lit_zero, 10, __c); + if (__q) + { + __xtrc += '0' + (__q - __lit_zero); + __found_mantissa = true; + ++__sep_pos; + } + else if ((__c == __lit[__num_base::_S_ie] + || __c == __lit[__num_base::_S_iE]) + && !__found_sci && __found_mantissa) + { + // Scientific notation. + if (__found_grouping.size() && !__found_dec) + __found_grouping += static_cast<char>(__sep_pos); + __xtrc += 'e'; + __found_sci = true; + + // Remove optional plus or minus sign, if they exist. + if (++__beg != __end) + { + __c = *__beg; + const bool __plus = __c == __lit[__num_base::_S_iplus]; + if ((__plus || __c == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping + && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + __xtrc += __plus ? '+' : '-'; + else + continue; + } + else + { + __testeof = true; + break; + } + } + else + break; + } + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + + // Digit grouping is checked. If grouping and found_grouping don't + // match, then get very very upset, and set failbit. + if (__found_grouping.size()) + { + // Add the ending grouping if a decimal or 'e'/'E' wasn't found. + if (!__found_dec && !__found_sci) + __found_grouping += static_cast<char>(__sep_pos); + + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) + __err |= ios_base::failbit; + } + + // Finish up. + if (__testeof) + __err |= ios_base::eofbit; + return __beg; + } + +_GLIBCXX_END_LDBL_NAMESPACE + +_GLIBCXX_BEGIN_LDBL_NAMESPACE + + template<typename _CharT, typename _InIter> + template<typename _ValueT> + _InIter + num_get<_CharT, _InIter>:: + _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, _ValueT& __v) const + { + typedef char_traits<_CharT> __traits_type; + using __gnu_cxx::__add_unsigned; + typedef typename __add_unsigned<_ValueT>::__type __unsigned_type; + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + char_type __c = char_type(); + + // NB: Iff __basefield == 0, __base can change based on contents. + const ios_base::fmtflags __basefield = __io.flags() + & ios_base::basefield; + const bool __oct = __basefield == ios_base::oct; + int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); + + // True if __beg becomes equal to __end. + bool __testeof = __beg == __end; + + // First check for sign. + bool __negative = false; + if (!__testeof) + { + __c = *__beg; + if (numeric_limits<_ValueT>::is_signed) + __negative = __c == __lit[__num_base::_S_iminus]; + if ((__negative || __c == __lit[__num_base::_S_iplus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + { + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + } + + // Next, look for leading zeros and check required digits + // for base formats. + bool __found_zero = false; + int __sep_pos = 0; + while (!__testeof) + { + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero] + && (!__found_zero || __base == 10)) + { + __found_zero = true; + ++__sep_pos; + if (__basefield == 0) + __base = 8; + if (__base == 8) + __sep_pos = 0; + } + else if (__found_zero + && (__c == __lit[__num_base::_S_ix] + || __c == __lit[__num_base::_S_iX])) + { + if (__basefield == 0) + __base = 16; + if (__base == 16) + { + __found_zero = false; + __sep_pos = 0; + } + else + break; + } + else + break; + + if (++__beg != __end) + { + __c = *__beg; + if (!__found_zero) + break; + } + else + __testeof = true; + } + + // At this point, base is determined. If not hex, only allow + // base digits as valid input. + const size_t __len = (__base == 16 ? __num_base::_S_iend + - __num_base::_S_izero : __base); + + // Extract. + string __found_grouping; + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); + bool __testfail = false; + const __unsigned_type __max = __negative ? + -numeric_limits<_ValueT>::min() : numeric_limits<_ValueT>::max(); + const __unsigned_type __smax = __max / __base; + __unsigned_type __result = 0; + int __digit = 0; + const char_type* __lit_zero = __lit + __num_base::_S_izero; + + if (!__lc->_M_allocated) + // "C" locale + while (!__testeof) + { + __digit = _M_find(__lit_zero, __len, __c); + if (__digit == -1) + break; + + if (__result > __smax) + __testfail = true; + else + { + __result *= __base; + __testfail |= __result > __max - __digit; + __result += __digit; + ++__sep_pos; + } + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + else + while (!__testeof) + { + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast<char>(__sep_pos); + __sep_pos = 0; + } + else + { + __testfail = true; + break; + } + } + else if (__c == __lc->_M_decimal_point) + break; + else + { + const char_type* __q = + __traits_type::find(__lit_zero, __len, __c); + if (!__q) + break; + + __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result > __smax) + __testfail = true; + else + { + __result *= __base; + __testfail |= __result > __max - __digit; + __result += __digit; + ++__sep_pos; + } + } + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } + + // Digit grouping is checked. If grouping and found_grouping don't + // match, then get very very upset, and set failbit. + if (__found_grouping.size()) + { + // Add the ending grouping. + __found_grouping += static_cast<char>(__sep_pos); + + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) + __err |= ios_base::failbit; + } + + if (!__testfail && (__sep_pos || __found_zero + || __found_grouping.size())) + __v = __negative ? -__result : __result; + else + __err |= ios_base::failbit; + + if (__testeof) + __err |= ios_base::eofbit; + return __beg; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 17. Bad bool parsing + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { + if (!(__io.flags() & ios_base::boolalpha)) + { + // Parse bool values as long. + // NB: We can't just call do_get(long) here, as it might + // refer to a derived class. + long __l = -1; + __beg = _M_extract_int(__beg, __end, __io, __err, __l); + if (__l == 0 || __l == 1) + __v = __l; + else + __err |= ios_base::failbit; + } + else + { + // Parse bool values as alphanumeric. + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + bool __testf = true; + bool __testt = true; + size_t __n; + bool __testeof = __beg == __end; + for (__n = 0; !__testeof; ++__n) + { + const char_type __c = *__beg; + + if (__testf) + if (__n < __lc->_M_falsename_size) + __testf = __c == __lc->_M_falsename[__n]; + else + break; + + if (__testt) + if (__n < __lc->_M_truename_size) + __testt = __c == __lc->_M_truename[__n]; + else + break; + + if (!__testf && !__testt) + break; + + if (++__beg == __end) + __testeof = true; + } + if (__testf && __n == __lc->_M_falsename_size) + __v = 0; + else if (__testt && __n == __lc->_M_truename_size) + __v = 1; + else + __err |= ios_base::failbit; + + if (__testeof) + __err |= ios_base::eofbit; + } + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } +#endif + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } + +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + __do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } +#endif + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { + // Prepare for hex formatted input. + typedef ios_base::fmtflags fmtflags; + const fmtflags __fmt = __io.flags(); + __io.flags(__fmt & ~ios_base::basefield | ios_base::hex); + + unsigned long __ul; + __beg = _M_extract_int(__beg, __end, __io, __err, __ul); + + // Reset from hex formatted input. + __io.flags(__fmt); + + if (!(__err & ios_base::failbit)) + __v = reinterpret_cast<void*>(__ul); + return __beg; + } + + // For use by integer and floating-point types after they have been + // converted into a char_type string. + template<typename _CharT, typename _OutIter> + void + num_put<_CharT, _OutIter>:: + _M_pad(_CharT __fill, streamsize __w, ios_base& __io, + _CharT* __new, const _CharT* __cs, int& __len) const + { + // [22.2.2.2.2] Stage 3. + // If necessary, pad. + __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, + __w, __len, true); + __len = static_cast<int>(__w); + } + +_GLIBCXX_END_LDBL_NAMESPACE + + template<typename _CharT, typename _ValueT> + int + __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, + ios_base::fmtflags __flags, bool __dec) + { + _CharT* __buf = __bufend; + if (__builtin_expect(__dec, true)) + { + // Decimal. + do + { + *--__buf = __lit[(__v % 10) + __num_base::_S_odigits]; + __v /= 10; + } + while (__v != 0); + } + else if ((__flags & ios_base::basefield) == ios_base::oct) + { + // Octal. + do + { + *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits]; + __v >>= 3; + } + while (__v != 0); + } + else + { + // Hex. + const bool __uppercase = __flags & ios_base::uppercase; + const int __case_offset = __uppercase ? __num_base::_S_oudigits + : __num_base::_S_odigits; + do + { + *--__buf = __lit[(__v & 0xf) + __case_offset]; + __v >>= 4; + } + while (__v != 0); + } + return __bufend - __buf; + } + +_GLIBCXX_BEGIN_LDBL_NAMESPACE + + template<typename _CharT, typename _OutIter> + void + num_put<_CharT, _OutIter>:: + _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep, + ios_base&, _CharT* __new, _CharT* __cs, int& __len) const + { + _CharT* __p = std::__add_grouping(__new, __sep, __grouping, + __grouping_size, __cs, __cs + __len); + __len = __p - __new; + } + + template<typename _CharT, typename _OutIter> + template<typename _ValueT> + _OutIter + num_put<_CharT, _OutIter>:: + _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, + _ValueT __v) const + { + using __gnu_cxx::__add_unsigned; + typedef typename __add_unsigned<_ValueT>::__type __unsigned_type; + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_out; + const ios_base::fmtflags __flags = __io.flags(); + + // Long enough to hold hex, dec, and octal representations. + const int __ilen = 5 * sizeof(_ValueT); + _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __ilen)); + + // [22.2.2.2.2] Stage 1, numeric conversion to character. + // Result is returned right-justified in the buffer. + const ios_base::fmtflags __basefield = __flags & ios_base::basefield; + const bool __dec = (__basefield != ios_base::oct + && __basefield != ios_base::hex); + const __unsigned_type __u = (__v > 0 || !__dec) ? __v : -__v; + int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec); + __cs += __ilen - __len; + + // Add grouping, if necessary. + if (__lc->_M_use_grouping) + { + // Grouping can add (almost) as many separators as the number + // of digits + space is reserved for numeric base or sign. + _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * (__len + 1) + * 2)); + _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len); + __cs = __cs2 + 2; + } + + // Complete Stage 1, prepend numeric base or sign. + if (__builtin_expect(__dec, true)) + { + // Decimal. + if (__v > 0) + { + if (__flags & ios_base::showpos + && numeric_limits<_ValueT>::is_signed) + *--__cs = __lit[__num_base::_S_oplus], ++__len; + } + else if (__v) + *--__cs = __lit[__num_base::_S_ominus], ++__len; + } + else if (__flags & ios_base::showbase && __v) + { + if (__basefield == ios_base::oct) + *--__cs = __lit[__num_base::_S_odigits], ++__len; + else + { + // 'x' or 'X' + const bool __uppercase = __flags & ios_base::uppercase; + *--__cs = __lit[__num_base::_S_ox + __uppercase]; + // '0' + *--__cs = __lit[__num_base::_S_odigits]; + __len += 2; + } + } + + // Pad. + const streamsize __w = __io.width(); + if (__w > static_cast<streamsize>(__len)) + { + _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs3, __cs, __len); + __cs = __cs3; + } + __io.width(0); + + // [22.2.2.2.2] Stage 4. + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __cs, __len); + } + + template<typename _CharT, typename _OutIter> + void + num_put<_CharT, _OutIter>:: + _M_group_float(const char* __grouping, size_t __grouping_size, + _CharT __sep, const _CharT* __p, _CharT* __new, + _CharT* __cs, int& __len) const + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 282. What types does numpunct grouping refer to? + // Add grouping, if necessary. + const int __declen = __p ? __p - __cs : __len; + _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping, + __grouping_size, + __cs, __cs + __declen); + + // Tack on decimal part. + int __newlen = __p2 - __new; + if (__p) + { + char_traits<_CharT>::copy(__p2, __p, __len - __declen); + __newlen += __len - __declen; + } + __len = __newlen; + } + + // The following code uses vsnprintf (or vsprintf(), when + // _GLIBCXX_USE_C99 is not defined) to convert floating point values + // for insertion into a stream. An optimization would be to replace + // them with code that works directly on a wide buffer and then use + // __pad to do the padding. It would be good to replace them anyway + // to gain back the efficiency that C++ provides by knowing up front + // the type of the values to insert. Also, sprintf is dangerous + // since may lead to accidental buffer overruns. This + // implementation follows the C++ standard fairly directly as + // outlined in 22.2.2.2 [lib.locale.num.put] + template<typename _CharT, typename _OutIter> + template<typename _ValueT> + _OutIter + num_put<_CharT, _OutIter>:: + _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, + _ValueT __v) const + { + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + // Use default precision if out of range. + const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision(); + + const int __max_digits = numeric_limits<_ValueT>::digits10; + + // [22.2.2.2.2] Stage 1, numeric conversion to character. + int __len; + // Long enough for the max format spec. + char __fbuf[16]; + __num_base::_S_format_float(__io, __fbuf, __mod); + +#ifdef _GLIBCXX_USE_C99 + // First try a buffer perhaps big enough (most probably sufficient + // for non-ios_base::fixed outputs) + int __cs_size = __max_digits * 3; + char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + __fbuf, __prec, __v); + + // If the buffer was not large enough, try again with the correct size. + if (__len >= __cs_size) + { + __cs_size = __len + 1; + __cs = static_cast<char*>(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + __fbuf, __prec, __v); + } +#else + // Consider the possibility of long ios_base::fixed outputs + const bool __fixed = __io.flags() & ios_base::fixed; + const int __max_exp = numeric_limits<_ValueT>::max_exponent10; + + // The size of the output string is computed as follows. + // ios_base::fixed outputs may need up to __max_exp + 1 chars + // for the integer part + __prec chars for the fractional part + // + 3 chars for sign, decimal point, '\0'. On the other hand, + // for non-fixed outputs __max_digits * 2 + __prec chars are + // largely sufficient. + const int __cs_size = __fixed ? __max_exp + __prec + 4 + : __max_digits * 2 + __prec; + char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf, + __prec, __v); +#endif + + // [22.2.2.2.2] Stage 2, convert to char_type, using correct + // numpunct.decimal_point() values for '.' and adding grouping. + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len)); + __ctype.widen(__cs, __cs + __len, __ws); + + // Replace decimal point. + _CharT* __wp = 0; + const char* __p = char_traits<char>::find(__cs, __len, '.'); + if (__p) + { + __wp = __ws + (__p - __cs); + *__wp = __lc->_M_decimal_point; + } + + // Add grouping, if necessary. + // N.B. Make sure to not group things like 2e20, i.e., no decimal + // point, scientific notation. + if (__lc->_M_use_grouping + && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9' + && __cs[1] >= '0' && __cs[2] >= '0'))) + { + // Grouping can add (almost) as many separators as the + // number of digits, but no more. + _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + + streamsize __off = 0; + if (__cs[0] == '-' || __cs[0] == '+') + { + __off = 1; + __ws2[0] = __ws[0]; + __len -= 1; + } + + _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __wp, __ws2 + __off, + __ws + __off, __len); + __len += __off; + + __ws = __ws2; + } + + // Pad. + const streamsize __w = __io.width(); + if (__w > static_cast<streamsize>(__len)) + { + _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __ws3, __ws, __len); + __ws = __ws3; + } + __io.width(0); + + // [22.2.2.2.2] Stage 4. + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __ws, __len); + } + + template<typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const + { + const ios_base::fmtflags __flags = __io.flags(); + if ((__flags & ios_base::boolalpha) == 0) + { + const long __l = __v; + __s = _M_insert_int(__s, __io, __fill, __l); + } + else + { + typedef __numpunct_cache<_CharT> __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + const _CharT* __name = __v ? __lc->_M_truename + : __lc->_M_falsename; + int __len = __v ? __lc->_M_truename_size + : __lc->_M_falsename_size; + + const streamsize __w = __io.width(); + if (__w > static_cast<streamsize>(__len)) + { + _CharT* __cs + = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs, __name, __len); + __name = __cs; + } + __io.width(0); + __s = std::__write(__s, __name, __len); + } + return __s; + } + + template<typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + + template<typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + template<typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + + template<typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } +#endif + + template<typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const + { return _M_insert_float(__s, __io, __fill, char(), __v); } + +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + template<typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const + { return _M_insert_float(__s, __io, __fill, char(), __v); } +#endif + + template<typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + long double __v) const + { return _M_insert_float(__s, __io, __fill, 'L', __v); } + + template<typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + const void* __v) const + { + const ios_base::fmtflags __flags = __io.flags(); + const ios_base::fmtflags __fmt = ~(ios_base::basefield + | ios_base::uppercase + | ios_base::internal); + __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); + + __s = _M_insert_int(__s, __io, __fill, + reinterpret_cast<unsigned long>(__v)); + __io.flags(__flags); + return __s; + } + + template<typename _CharT, typename _InIter> + template<bool _Intl> + _InIter + money_get<_CharT, _InIter>:: + _M_extract(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __units) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef __moneypunct_cache<_CharT, _Intl> __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Deduced sign. + bool __negative = false; + // Sign size. + size_type __sign_size = 0; + // True if sign is mandatory. + const bool __mandatory_sign = (__lc->_M_positive_sign_size + && __lc->_M_negative_sign_size); + // String of grouping info from thousands_sep plucked from __units. + string __grouping_tmp; + if (__lc->_M_use_grouping) + __grouping_tmp.reserve(32); + // Last position before the decimal point. + int __last_pos = 0; + // Separator positions, then, possibly, fractional digits. + int __n = 0; + // If input iterator is in a valid state. + bool __testvalid = true; + // Flag marking when a decimal point is found. + bool __testdecfound = false; + + // The tentative returned string is stored here. + string __res; + __res.reserve(32); + + const char_type* __lit_zero = __lit + money_base::_S_zero; + const money_base::pattern __p = __lc->_M_neg_format; + for (int __i = 0; __i < 4 && __testvalid; ++__i) + { + const part __which = static_cast<part>(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + // According to 22.2.6.1.2, p2, symbol is required + // if (__io.flags() & ios_base::showbase), otherwise + // is optional and consumed only if other characters + // are needed to complete the format. + if (__io.flags() & ios_base::showbase || __sign_size > 1 + || __i == 0 + || (__i == 1 && (__mandatory_sign + || (static_cast<part>(__p.field[0]) + == money_base::sign) + || (static_cast<part>(__p.field[2]) + == money_base::space))) + || (__i == 2 && ((static_cast<part>(__p.field[3]) + == money_base::value) + || __mandatory_sign + && (static_cast<part>(__p.field[3]) + == money_base::sign)))) + { + const size_type __len = __lc->_M_curr_symbol_size; + size_type __j = 0; + for (; __beg != __end && __j < __len + && *__beg == __lc->_M_curr_symbol[__j]; + ++__beg, ++__j); + if (__j != __len + && (__j || __io.flags() & ios_base::showbase)) + __testvalid = false; + } + break; + case money_base::sign: + // Sign might not exist, or be more than one character long. + if (__lc->_M_positive_sign_size && __beg != __end + && *__beg == __lc->_M_positive_sign[0]) + { + __sign_size = __lc->_M_positive_sign_size; + ++__beg; + } + else if (__lc->_M_negative_sign_size && __beg != __end + && *__beg == __lc->_M_negative_sign[0]) + { + __negative = true; + __sign_size = __lc->_M_negative_sign_size; + ++__beg; + } + else if (__lc->_M_positive_sign_size + && !__lc->_M_negative_sign_size) + // "... if no sign is detected, the result is given the sign + // that corresponds to the source of the empty string" + __negative = true; + else if (__mandatory_sign) + __testvalid = false; + break; + case money_base::value: + // Extract digits, remove and stash away the + // grouping of found thousands separators. + for (; __beg != __end; ++__beg) + { + const char_type __c = *__beg; + const char_type* __q = __traits_type::find(__lit_zero, + 10, __c); + if (__q != 0) + { + __res += money_base::_S_atoms[__q - __lit]; + ++__n; + } + else if (__c == __lc->_M_decimal_point + && !__testdecfound) + { + __last_pos = __n; + __n = 0; + __testdecfound = true; + } + else if (__lc->_M_use_grouping + && __c == __lc->_M_thousands_sep + && !__testdecfound) + { + if (__n) + { + // Mark position for later analysis. + __grouping_tmp += static_cast<char>(__n); + __n = 0; + } + else + { + __testvalid = false; + break; + } + } + else + break; + } + if (__res.empty()) + __testvalid = false; + break; + case money_base::space: + // At least one space is required. + if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) + ++__beg; + else + __testvalid = false; + case money_base::none: + // Only if not at the end of the pattern. + if (__i != 3) + for (; __beg != __end + && __ctype.is(ctype_base::space, *__beg); ++__beg); + break; + } + } + + // Need to get the rest of the sign characters, if they exist. + if (__sign_size > 1 && __testvalid) + { + const char_type* __sign = __negative ? __lc->_M_negative_sign + : __lc->_M_positive_sign; + size_type __i = 1; + for (; __beg != __end && __i < __sign_size + && *__beg == __sign[__i]; ++__beg, ++__i); + + if (__i != __sign_size) + __testvalid = false; + } + + if (__testvalid) + { + // Strip leading zeros. + if (__res.size() > 1) + { + const size_type __first = __res.find_first_not_of('0'); + const bool __only_zeros = __first == string::npos; + if (__first) + __res.erase(0, __only_zeros ? __res.size() - 1 : __first); + } + + // 22.2.6.1.2, p4 + if (__negative && __res[0] != '0') + __res.insert(__res.begin(), '-'); + + // Test for grouping fidelity. + if (__grouping_tmp.size()) + { + // Add the ending grouping. + __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos + : __n); + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __grouping_tmp)) + __err |= ios_base::failbit; + } + + // Iff not enough digits were supplied after the decimal-point. + if (__testdecfound && __lc->_M_frac_digits > 0 + && __n != __lc->_M_frac_digits) + __testvalid = false; + } + + // Iff valid sequence is not recognized. + if (!__testvalid) + __err |= ios_base::failbit; + else + __units.swap(__res); + + // Iff no more characters are available. + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + template<typename _CharT, typename _InIter> + _InIter + money_get<_CharT, _InIter>:: + __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, double& __units) const + { + string __str; + __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) + : _M_extract<false>(__beg, __end, __io, __err, __str); + std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); + return __beg; + } +#endif + + template<typename _CharT, typename _InIter> + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const + { + string __str; + __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) + : _M_extract<false>(__beg, __end, __io, __err, __str); + std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const + { + typedef typename string::size_type size_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + string __str; + __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) + : _M_extract<false>(__beg, __end, __io, __err, __str); + const size_type __len = __str.size(); + if (__len) + { + __digits.resize(__len); + __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]); + } + return __beg; + } + + template<typename _CharT, typename _OutIter> + template<bool _Intl> + _OutIter + money_put<_CharT, _OutIter>:: + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const + { + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef __moneypunct_cache<_CharT, _Intl> __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Determine if negative or positive formats are to be used, and + // discard leading negative_sign if it is present. + const char_type* __beg = __digits.data(); + + money_base::pattern __p; + const char_type* __sign; + size_type __sign_size; + if (!(*__beg == __lit[money_base::_S_minus])) + { + __p = __lc->_M_pos_format; + __sign = __lc->_M_positive_sign; + __sign_size = __lc->_M_positive_sign_size; + } + else + { + __p = __lc->_M_neg_format; + __sign = __lc->_M_negative_sign; + __sign_size = __lc->_M_negative_sign_size; + if (__digits.size()) + ++__beg; + } + + // Look for valid numbers in the ctype facet within input digits. + size_type __len = __ctype.scan_not(ctype_base::digit, __beg, + __beg + __digits.size()) - __beg; + if (__len) + { + // Assume valid input, and attempt to format. + // Break down input numbers into base components, as follows: + // final_value = grouped units + (decimal point) + (digits) + string_type __value; + __value.reserve(2 * __len); + + // Add thousands separators to non-decimal digits, per + // grouping rules. + long __paddec = __len - __lc->_M_frac_digits; + if (__paddec > 0) + { + if (__lc->_M_frac_digits < 0) + __paddec = __len; + if (__lc->_M_grouping_size) + { + __value.assign(2 * __paddec, char_type()); + _CharT* __vend = + std::__add_grouping(&__value[0], __lc->_M_thousands_sep, + __lc->_M_grouping, + __lc->_M_grouping_size, + __beg, __beg + __paddec); + __value.erase(__vend - &__value[0]); + } + else + __value.assign(__beg, __paddec); + } + + // Deal with decimal point, decimal digits. + if (__lc->_M_frac_digits > 0) + { + __value += __lc->_M_decimal_point; + if (__paddec >= 0) + __value.append(__beg + __paddec, __lc->_M_frac_digits); + else + { + // Have to pad zeros in the decimal position. + __value.append(-__paddec, __lit[money_base::_S_zero]); + __value.append(__beg, __len); + } + } + + // Calculate length of resulting string. + const ios_base::fmtflags __f = __io.flags() + & ios_base::adjustfield; + __len = __value.size() + __sign_size; + __len += ((__io.flags() & ios_base::showbase) + ? __lc->_M_curr_symbol_size : 0); + + string_type __res; + __res.reserve(2 * __len); + + const size_type __width = static_cast<size_type>(__io.width()); + const bool __testipad = (__f == ios_base::internal + && __len < __width); + // Fit formatted digits into the required pattern. + for (int __i = 0; __i < 4; ++__i) + { + const part __which = static_cast<part>(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + if (__io.flags() & ios_base::showbase) + __res.append(__lc->_M_curr_symbol, + __lc->_M_curr_symbol_size); + break; + case money_base::sign: + // Sign might not exist, or be more than one + // charater long. In that case, add in the rest + // below. + if (__sign_size) + __res += __sign[0]; + break; + case money_base::value: + __res += __value; + break; + case money_base::space: + // At least one space is required, but if internal + // formatting is required, an arbitrary number of + // fill spaces will be necessary. + if (__testipad) + __res.append(__width - __len, __fill); + else + __res += __fill; + break; + case money_base::none: + if (__testipad) + __res.append(__width - __len, __fill); + break; + } + } + + // Special case of multi-part sign parts. + if (__sign_size > 1) + __res.append(__sign + 1, __sign_size - 1); + + // Pad, if still necessary. + __len = __res.size(); + if (__width > __len) + { + if (__f == ios_base::left) + // After. + __res.append(__width - __len, __fill); + else + // Before. + __res.insert(0, __width - __len, __fill); + __len = __width; + } + + // Write resulting, fully-formatted string to output iterator. + __s = std::__write(__s, __res.data(), __len); + } + __io.width(0); + return __s; + } + +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + template<typename _CharT, typename _OutIter> + _OutIter + money_put<_CharT, _OutIter>:: + __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + double __units) const + { return this->do_put(__s, __intl, __io, __fill, (long double) __units); } +#endif + + template<typename _CharT, typename _OutIter> + _OutIter + money_put<_CharT, _OutIter>:: + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const + { + const locale __loc = __io.getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); +#ifdef _GLIBCXX_USE_C99 + // First try a buffer perhaps big enough. + int __cs_size = 64; + char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 328. Bad sprintf format modifier in money_put<>::do_put() + int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + "%.*Lf", 0, __units); + // If the buffer was not large enough, try again with the correct size. + if (__len >= __cs_size) + { + __cs_size = __len + 1; + __cs = static_cast<char*>(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + "%.*Lf", 0, __units); + } +#else + // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. + const int __cs_size = numeric_limits<long double>::max_exponent10 + 3; + char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); + int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", + 0, __units); +#endif + string_type __digits(__len, char_type()); + __ctype.widen(__cs, __cs + __len, &__digits[0]); + return __intl ? _M_insert<true>(__s, __io, __fill, __digits) + : _M_insert<false>(__s, __io, __fill, __digits); + } + + template<typename _CharT, typename _OutIter> + _OutIter + money_put<_CharT, _OutIter>:: + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + const string_type& __digits) const + { return __intl ? _M_insert<true>(__s, __io, __fill, __digits) + : _M_insert<false>(__s, __io, __fill, __digits); } + +_GLIBCXX_END_LDBL_NAMESPACE + + // NB: Not especially useful. Without an ios_base object or some + // kind of locale reference, we are left clawing at the air where + // the side of the mountain used to be... + template<typename _CharT, typename _InIter> + time_base::dateorder + time_get<_CharT, _InIter>::do_date_order() const + { return time_base::no_order; } + + // Expand a strftime format string and parse it. E.g., do_get_date() may + // pass %m/%d/%Y => extracted characters. + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + const size_t __len = char_traits<_CharT>::length(__format); + + ios_base::iostate __tmperr = ios_base::goodbit; + for (size_t __i = 0; __beg != __end && __i < __len && !__tmperr; ++__i) + { + if (__ctype.narrow(__format[__i], 0) == '%') + { + // Verify valid formatting code, attempt to extract. + char __c = __ctype.narrow(__format[++__i], 0); + int __mem = 0; + if (__c == 'E' || __c == 'O') + __c = __ctype.narrow(__format[++__i], 0); + switch (__c) + { + const char* __cs; + _CharT __wcs[10]; + case 'a': + // Abbreviated weekday name [tm_wday] + const char_type* __days1[7]; + __tp._M_days_abbreviated(__days1); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, + 7, __io, __tmperr); + break; + case 'A': + // Weekday name [tm_wday]. + const char_type* __days2[7]; + __tp._M_days(__days2); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, + 7, __io, __tmperr); + break; + case 'h': + case 'b': + // Abbreviated month name [tm_mon] + const char_type* __months1[12]; + __tp._M_months_abbreviated(__months1); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months1, 12, __io, __tmperr); + break; + case 'B': + // Month name [tm_mon]. + const char_type* __months2[12]; + __tp._M_months(__months2); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months2, 12, __io, __tmperr); + break; + case 'c': + // Default time and date representation. + const char_type* __dt[2]; + __tp._M_date_time_formats(__dt); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __dt[0]); + break; + case 'd': + // Day [01, 31]. [tm_mday] + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, + __io, __tmperr); + break; + case 'e': + // Day [1, 31], with single digits preceded by + // space. [tm_mday] + if (__ctype.is(ctype_base::space, *__beg)) + __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, + 1, __io, __tmperr); + else + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, + 2, __io, __tmperr); + break; + case 'D': + // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] + __cs = "%m/%d/%y"; + __ctype.widen(__cs, __cs + 9, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __wcs); + break; + case 'H': + // Hour [00, 23]. [tm_hour] + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, + __io, __tmperr); + break; + case 'I': + // Hour [01, 12]. [tm_hour] + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, + __io, __tmperr); + break; + case 'm': + // Month [01, 12]. [tm_mon] + __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, + __io, __tmperr); + if (!__tmperr) + __tm->tm_mon = __mem - 1; + break; + case 'M': + // Minute [00, 59]. [tm_min] + __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, + __io, __tmperr); + break; + case 'n': + if (__ctype.narrow(*__beg, 0) == '\n') + ++__beg; + else + __tmperr |= ios_base::failbit; + break; + case 'R': + // Equivalent to (%H:%M). + __cs = "%H:%M"; + __ctype.widen(__cs, __cs + 6, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __wcs); + break; + case 'S': + // Seconds. [tm_sec] + // [00, 60] in C99 (one leap-second), [00, 61] in C89. +#ifdef _GLIBCXX_USE_C99 + __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2, +#else + __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2, +#endif + __io, __tmperr); + break; + case 't': + if (__ctype.narrow(*__beg, 0) == '\t') + ++__beg; + else + __tmperr |= ios_base::failbit; + break; + case 'T': + // Equivalent to (%H:%M:%S). + __cs = "%H:%M:%S"; + __ctype.widen(__cs, __cs + 9, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __wcs); + break; + case 'x': + // Locale's date. + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __dates[0]); + break; + case 'X': + // Locale's time. + const char_type* __times[2]; + __tp._M_time_formats(__times); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __times[0]); + break; + case 'y': + case 'C': // C99 + // Two digit year. [tm_year] + __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, + __io, __tmperr); + break; + case 'Y': + // Year [1900). [tm_year] + __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, + __io, __tmperr); + if (!__tmperr) + __tm->tm_year = __mem - 1900; + break; + case 'Z': + // Timezone info. + if (__ctype.is(ctype_base::upper, *__beg)) + { + int __tmp; + __beg = _M_extract_name(__beg, __end, __tmp, + __timepunct_cache<_CharT>::_S_timezones, + 14, __io, __tmperr); + + // GMT requires special effort. + if (__beg != __end && !__tmperr && __tmp == 0 + && (*__beg == __ctype.widen('-') + || *__beg == __ctype.widen('+'))) + { + __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, + __io, __tmperr); + __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, + __io, __tmperr); + } + } + else + __tmperr |= ios_base::failbit; + break; + default: + // Not recognized. + __tmperr |= ios_base::failbit; + } + } + else + { + // Verify format and input match, extract and discard. + if (__format[__i] == *__beg) + ++__beg; + else + __tmperr |= ios_base::failbit; + } + } + + if (__tmperr) + __err |= ios_base::failbit; + + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + _M_extract_num(iter_type __beg, iter_type __end, int& __member, + int __min, int __max, size_t __len, + ios_base& __io, ios_base::iostate& __err) const + { + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + // As-is works for __len = 1, 2, 4, the values actually used. + int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); + + ++__min; + size_t __i = 0; + int __value = 0; + for (; __beg != __end && __i < __len; ++__beg, ++__i) + { + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + { + __value = __value * 10 + (__c - '0'); + const int __valuec = __value * __mult; + if (__valuec > __max || __valuec + __mult < __min) + break; + __mult /= 10; + } + else + break; + } + if (__i == __len) + __member = __value; + else + __err |= ios_base::failbit; + + return __beg; + } + + // Assumptions: + // All elements in __names are unique. + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) + * __indexlen)); + size_t __nmatches = 0; + size_t __pos = 0; + bool __testvalid = true; + const char_type* __name; + + // Look for initial matches. + // NB: Some of the locale data is in the form of all lowercase + // names, and some is in the form of initially-capitalized + // names. Look for both. + if (__beg != __end) + { + const char_type __c = *__beg; + for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) + if (__c == __names[__i1][0] + || __c == __ctype.toupper(__names[__i1][0])) + __matches[__nmatches++] = __i1; + } + + while (__nmatches > 1) + { + // Find smallest matching string. + size_t __minlen = __traits_type::length(__names[__matches[0]]); + for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) + __minlen = std::min(__minlen, + __traits_type::length(__names[__matches[__i2]])); + ++__beg, ++__pos; + if (__pos < __minlen && __beg != __end) + for (size_t __i3 = 0; __i3 < __nmatches;) + { + __name = __names[__matches[__i3]]; + if (!(__name[__pos] == *__beg)) + __matches[__i3] = __matches[--__nmatches]; + else + ++__i3; + } + else + break; + } + + if (__nmatches == 1) + { + // Make sure found name is completely extracted. + ++__beg, ++__pos; + __name = __names[__matches[0]]; + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end && __name[__pos] == *__beg) + ++__beg, ++__pos; + + if (__len == __pos) + __member = __matches[0]; + else + __testvalid = false; + } + else + __testvalid = false; + if (!__testvalid) + __err |= ios_base::failbit; + + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + do_get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __times[2]; + __tp._M_time_formats(__times); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __times[0]); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + do_get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dates[0]); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + const char_type* __days[7]; + __tp._M_days_abbreviated(__days); + int __tmpwday; + ios_base::iostate __tmperr = ios_base::goodbit; + __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, + __io, __tmperr); + + // Check to see if non-abbreviated name exists, and extract. + // NB: Assumes both _M_days and _M_days_abbreviated organized in + // exact same order, first to last, such that the resulting + // __days array with the same index points to a day, and that + // day's abbreviated form. + // NB: Also assumes that an abbreviated name is a subset of the name. + if (!__tmperr && __beg != __end) + { + size_t __pos = __traits_type::length(__days[__tmpwday]); + __tp._M_days(__days); + const char_type* __name = __days[__tmpwday]; + if (__name[__pos] == *__beg) + { + // Extract the rest of it. + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end + && __name[__pos] == *__beg) + ++__beg, ++__pos; + if (__len != __pos) + __tmperr |= ios_base::failbit; + } + } + if (!__tmperr) + __tm->tm_wday = __tmpwday; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + do_get_monthname(iter_type __beg, iter_type __end, + ios_base& __io, ios_base::iostate& __err, tm* __tm) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + const char_type* __months[12]; + __tp._M_months_abbreviated(__months); + int __tmpmon; + ios_base::iostate __tmperr = ios_base::goodbit; + __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, + __io, __tmperr); + + // Check to see if non-abbreviated name exists, and extract. + // NB: Assumes both _M_months and _M_months_abbreviated organized in + // exact same order, first to last, such that the resulting + // __months array with the same index points to a month, and that + // month's abbreviated form. + // NB: Also assumes that an abbreviated name is a subset of the name. + if (!__tmperr && __beg != __end) + { + size_t __pos = __traits_type::length(__months[__tmpmon]); + __tp._M_months(__months); + const char_type* __name = __months[__tmpmon]; + if (__name[__pos] == *__beg) + { + // Extract the rest of it. + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end + && __name[__pos] == *__beg) + ++__beg, ++__pos; + if (__len != __pos) + __tmperr |= ios_base::failbit; + } + } + if (!__tmperr) + __tm->tm_mon = __tmpmon; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + do_get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + size_t __i = 0; + int __value = 0; + for (; __beg != __end && __i < 4; ++__beg, ++__i) + { + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + __value = __value * 10 + (__c - '0'); + else + break; + } + if (__i == 2 || __i == 4) + __tm->tm_year = __i == 2 ? __value : __value - 1900; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template<typename _CharT, typename _OutIter> + _OutIter + time_put<_CharT, _OutIter>:: + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + const _CharT* __beg, const _CharT* __end) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); + for (; __beg != __end; ++__beg) + if (__ctype.narrow(*__beg, 0) != '%') + { + *__s = *__beg; + ++__s; + } + else if (++__beg != __end) + { + char __format; + char __mod = 0; + const char __c = __ctype.narrow(*__beg, 0); + if (__c != 'E' && __c != 'O') + __format = __c; + else if (++__beg != __end) + { + __mod = __c; + __format = __ctype.narrow(*__beg, 0); + } + else + break; + __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); + } + else + break; + return __s; + } + + template<typename _CharT, typename _OutIter> + _OutIter + time_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, + char __format, char __mod) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); + __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + + // NB: This size is arbitrary. Should this be a data member, + // initialized at construction? + const size_t __maxlen = 128; + char_type* __res = + static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen)); + + // NB: In IEE 1003.1-200x, and perhaps other locale models, it + // is possible that the format character will be longer than one + // character. Possibilities include 'E' or 'O' followed by a + // format character: if __mod is not the default argument, assume + // it's a valid modifier. + char_type __fmt[4]; + __fmt[0] = __ctype.widen('%'); + if (!__mod) + { + __fmt[1] = __format; + __fmt[2] = char_type(); + } + else + { + __fmt[1] = __mod; + __fmt[2] = __format; + __fmt[3] = char_type(); + } + + __tp._M_put(__res, __maxlen, __fmt, __tm); + + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __res, char_traits<char_type>::length(__res)); + } + + // Generic version does nothing. + template<typename _CharT> + int + collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const + { return 0; } + + // Generic version does nothing. + template<typename _CharT> + size_t + collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const + { return 0; } + + template<typename _CharT> + int + collate<_CharT>:: + do_compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const + { + // strcoll assumes zero-terminated strings so we make a copy + // and then put a zero at the end. + const string_type __one(__lo1, __hi1); + const string_type __two(__lo2, __hi2); + + const _CharT* __p = __one.c_str(); + const _CharT* __pend = __one.data() + __one.length(); + const _CharT* __q = __two.c_str(); + const _CharT* __qend = __two.data() + __two.length(); + + // strcoll stops when it sees a nul character so we break + // the strings into zero-terminated substrings and pass those + // to strcoll. + for (;;) + { + const int __res = _M_compare(__p, __q); + if (__res) + return __res; + + __p += char_traits<_CharT>::length(__p); + __q += char_traits<_CharT>::length(__q); + if (__p == __pend && __q == __qend) + return 0; + else if (__p == __pend) + return -1; + else if (__q == __qend) + return 1; + + __p++; + __q++; + } + } + + template<typename _CharT> + typename collate<_CharT>::string_type + collate<_CharT>:: + do_transform(const _CharT* __lo, const _CharT* __hi) const + { + string_type __ret; + + // strxfrm assumes zero-terminated strings so we make a copy + const string_type __str(__lo, __hi); + + const _CharT* __p = __str.c_str(); + const _CharT* __pend = __str.data() + __str.length(); + + size_t __len = (__hi - __lo) * 2; + + _CharT* __c = new _CharT[__len]; + + try + { + // strxfrm stops when it sees a nul character so we break + // the string into zero-terminated substrings and pass those + // to strxfrm. + for (;;) + { + // First try a buffer perhaps big enough. + size_t __res = _M_transform(__c, __p, __len); + // If the buffer was not large enough, try again with the + // correct size. + if (__res >= __len) + { + __len = __res + 1; + delete [] __c, __c = 0; + __c = new _CharT[__len]; + __res = _M_transform(__c, __p, __len); + } + + __ret.append(__c, __res); + __p += char_traits<_CharT>::length(__p); + if (__p == __pend) + break; + + __p++; + __ret.push_back(_CharT()); + } + } + catch(...) + { + delete [] __c; + __throw_exception_again; + } + + delete [] __c; + + return __ret; + } + + template<typename _CharT> + long + collate<_CharT>:: + do_hash(const _CharT* __lo, const _CharT* __hi) const + { + unsigned long __val = 0; + for (; __lo < __hi; ++__lo) + __val = *__lo + ((__val << 7) | + (__val >> (numeric_limits<unsigned long>::digits - 7))); + return static_cast<long>(__val); + } + + // Construct correctly padded string, as per 22.2.2.2.2 + // Assumes + // __newlen > __oldlen + // __news is allocated for __newlen size + // Used by both num_put and ostream inserters: if __num, + // internal-adjusted objects are padded according to the rules below + // concerning 0[xX] and +-, otherwise, exactly as right-adjusted + // ones are. + + // NB: Of the two parameters, _CharT can be deduced from the + // function arguments. The other (_Traits) has to be explicitly specified. + template<typename _CharT, typename _Traits> + void + __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, + _CharT* __news, const _CharT* __olds, + const streamsize __newlen, + const streamsize __oldlen, const bool __num) + { + const size_t __plen = static_cast<size_t>(__newlen - __oldlen); + const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; + + // Padding last. + if (__adjust == ios_base::left) + { + _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen); + _Traits::assign(__news + __oldlen, __plen, __fill); + return; + } + + size_t __mod = 0; + if (__adjust == ios_base::internal && __num) + { + // Pad after the sign, if there is one. + // Pad after 0[xX], if there is one. + // Who came up with these rules, anyway? Jeeze. + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + const bool __testsign = (__ctype.widen('-') == __olds[0] + || __ctype.widen('+') == __olds[0]); + const bool __testhex = (__ctype.widen('0') == __olds[0] + && __oldlen > 1 + && (__ctype.widen('x') == __olds[1] + || __ctype.widen('X') == __olds[1])); + if (__testhex) + { + __news[0] = __olds[0]; + __news[1] = __olds[1]; + __mod = 2; + __news += 2; + } + else if (__testsign) + { + __news[0] = __olds[0]; + __mod = 1; + ++__news; + } + // else Padding first. + } + _Traits::assign(__news, __plen, __fill); + _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod), + __oldlen - __mod); + } + + bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp) + { + const size_t __n = __grouping_tmp.size() - 1; + const size_t __min = std::min(__n, size_t(__grouping_size - 1)); + size_t __i = __n; + bool __test = true; + + // Parsed number groupings have to match the + // numpunct::grouping string exactly, starting at the + // right-most point of the parsed sequence of elements ... + for (size_t __j = 0; __j < __min && __test; --__i, ++__j) + __test = __grouping_tmp[__i] == __grouping[__j]; + for (; __i && __test; --__i) + __test = __grouping_tmp[__i] == __grouping[__min]; + // ... but the first parsed grouping can be <= numpunct + // grouping (only do the check if the numpunct char is > 0 + // because <= 0 means any size is ok). + if (static_cast<signed char>(__grouping[__min]) > 0) + __test &= __grouping_tmp[0] <= __grouping[__min]; + return __test; + } + + template<typename _CharT> + _CharT* + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, + const _CharT* __first, const _CharT* __last) + { + size_t __idx = 0; + size_t __ctr = 0; + + while (__last - __first > __gbeg[__idx] + && static_cast<signed char>(__gbeg[__idx]) > 0) + { + __last -= __gbeg[__idx]; + __idx < __gsize - 1 ? ++__idx : ++__ctr; + } + + while (__first != __last) + *__s++ = *__first++; + + while (__ctr--) + { + *__s++ = __sep; + for (char __i = __gbeg[__idx]; __i > 0; --__i) + *__s++ = *__first++; + } + + while (__idx--) + { + *__s++ = __sep; + for (char __i = __gbeg[__idx]; __i > 0; --__i) + *__s++ = *__first++; + } + + return __s; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class moneypunct<char, false>; + extern template class moneypunct<char, true>; + extern template class moneypunct_byname<char, false>; + extern template class moneypunct_byname<char, true>; + extern template class _GLIBCXX_LDBL_NAMESPACE money_get<char>; + extern template class _GLIBCXX_LDBL_NAMESPACE money_put<char>; + extern template class numpunct<char>; + extern template class numpunct_byname<char>; + extern template class _GLIBCXX_LDBL_NAMESPACE num_get<char>; + extern template class _GLIBCXX_LDBL_NAMESPACE num_put<char>; + extern template class __timepunct<char>; + extern template class time_put<char>; + extern template class time_put_byname<char>; + extern template class time_get<char>; + extern template class time_get_byname<char>; + extern template class messages<char>; + extern template class messages_byname<char>; + extern template class ctype_byname<char>; + extern template class codecvt_byname<char, char, mbstate_t>; + extern template class collate<char>; + extern template class collate_byname<char>; + + extern template + const codecvt<char, char, mbstate_t>& + use_facet<codecvt<char, char, mbstate_t> >(const locale&); + + extern template + const collate<char>& + use_facet<collate<char> >(const locale&); + + extern template + const numpunct<char>& + use_facet<numpunct<char> >(const locale&); + + extern template + const num_put<char>& + use_facet<num_put<char> >(const locale&); + + extern template + const num_get<char>& + use_facet<num_get<char> >(const locale&); + + extern template + const moneypunct<char, true>& + use_facet<moneypunct<char, true> >(const locale&); + + extern template + const moneypunct<char, false>& + use_facet<moneypunct<char, false> >(const locale&); + + extern template + const money_put<char>& + use_facet<money_put<char> >(const locale&); + + extern template + const money_get<char>& + use_facet<money_get<char> >(const locale&); + + extern template + const __timepunct<char>& + use_facet<__timepunct<char> >(const locale&); + + extern template + const time_put<char>& + use_facet<time_put<char> >(const locale&); + + extern template + const time_get<char>& + use_facet<time_get<char> >(const locale&); + + extern template + const messages<char>& + use_facet<messages<char> >(const locale&); + + extern template + bool + has_facet<ctype<char> >(const locale&); + + extern template + bool + has_facet<codecvt<char, char, mbstate_t> >(const locale&); + + extern template + bool + has_facet<collate<char> >(const locale&); + + extern template + bool + has_facet<numpunct<char> >(const locale&); + + extern template + bool + has_facet<num_put<char> >(const locale&); + + extern template + bool + has_facet<num_get<char> >(const locale&); + + extern template + bool + has_facet<moneypunct<char> >(const locale&); + + extern template + bool + has_facet<money_put<char> >(const locale&); + + extern template + bool + has_facet<money_get<char> >(const locale&); + + extern template + bool + has_facet<__timepunct<char> >(const locale&); + + extern template + bool + has_facet<time_put<char> >(const locale&); + + extern template + bool + has_facet<time_get<char> >(const locale&); + + extern template + bool + has_facet<messages<char> >(const locale&); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class moneypunct<wchar_t, false>; + extern template class moneypunct<wchar_t, true>; + extern template class moneypunct_byname<wchar_t, false>; + extern template class moneypunct_byname<wchar_t, true>; + extern template class _GLIBCXX_LDBL_NAMESPACE money_get<wchar_t>; + extern template class _GLIBCXX_LDBL_NAMESPACE money_put<wchar_t>; + extern template class numpunct<wchar_t>; + extern template class numpunct_byname<wchar_t>; + extern template class _GLIBCXX_LDBL_NAMESPACE num_get<wchar_t>; + extern template class _GLIBCXX_LDBL_NAMESPACE num_put<wchar_t>; + extern template class __timepunct<wchar_t>; + extern template class time_put<wchar_t>; + extern template class time_put_byname<wchar_t>; + extern template class time_get<wchar_t>; + extern template class time_get_byname<wchar_t>; + extern template class messages<wchar_t>; + extern template class messages_byname<wchar_t>; + extern template class ctype_byname<wchar_t>; + extern template class codecvt_byname<wchar_t, char, mbstate_t>; + extern template class collate<wchar_t>; + extern template class collate_byname<wchar_t>; + + extern template + const codecvt<wchar_t, char, mbstate_t>& + use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&); + + extern template + const collate<wchar_t>& + use_facet<collate<wchar_t> >(const locale&); + + extern template + const numpunct<wchar_t>& + use_facet<numpunct<wchar_t> >(const locale&); + + extern template + const num_put<wchar_t>& + use_facet<num_put<wchar_t> >(const locale&); + + extern template + const num_get<wchar_t>& + use_facet<num_get<wchar_t> >(const locale&); + + extern template + const moneypunct<wchar_t, true>& + use_facet<moneypunct<wchar_t, true> >(const locale&); + + extern template + const moneypunct<wchar_t, false>& + use_facet<moneypunct<wchar_t, false> >(const locale&); + + extern template + const money_put<wchar_t>& + use_facet<money_put<wchar_t> >(const locale&); + + extern template + const money_get<wchar_t>& + use_facet<money_get<wchar_t> >(const locale&); + + extern template + const __timepunct<wchar_t>& + use_facet<__timepunct<wchar_t> >(const locale&); + + extern template + const time_put<wchar_t>& + use_facet<time_put<wchar_t> >(const locale&); + + extern template + const time_get<wchar_t>& + use_facet<time_get<wchar_t> >(const locale&); + + extern template + const messages<wchar_t>& + use_facet<messages<wchar_t> >(const locale&); + + extern template + bool + has_facet<ctype<wchar_t> >(const locale&); + + extern template + bool + has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&); + + extern template + bool + has_facet<collate<wchar_t> >(const locale&); + + extern template + bool + has_facet<numpunct<wchar_t> >(const locale&); + + extern template + bool + has_facet<num_put<wchar_t> >(const locale&); + + extern template + bool + has_facet<num_get<wchar_t> >(const locale&); + + extern template + bool + has_facet<moneypunct<wchar_t> >(const locale&); + + extern template + bool + has_facet<money_put<wchar_t> >(const locale&); + + extern template + bool + has_facet<money_get<wchar_t> >(const locale&); + + extern template + bool + has_facet<__timepunct<wchar_t> >(const locale&); + + extern template + bool + has_facet<time_put<wchar_t> >(const locale&); + + extern template + bool + has_facet<time_get<wchar_t> >(const locale&); + + extern template + bool + has_facet<messages<wchar_t> >(const locale&); +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/localefwd.h b/libstdc++/include/bits/localefwd.h new file mode 100644 index 0000000..b858668 --- /dev/null +++ b/libstdc++/include/bits/localefwd.h @@ -0,0 +1,197 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 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. + +/** @file localefwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 22.1 Locales +// + +#ifndef _LOCALE_FWD_H +#define _LOCALE_FWD_H 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/c++locale.h> // Defines __c_locale, config-specific includes +#include <iosfwd> // For ostreambuf_iterator, istreambuf_iterator +#include <bits/functexcept.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // 22.1.1 Locale + class locale; + + // 22.1.3 Convenience interfaces + template<typename _CharT> + inline bool + isspace(_CharT, const locale&); + + template<typename _CharT> + inline bool + isprint(_CharT, const locale&); + + template<typename _CharT> + inline bool + iscntrl(_CharT, const locale&); + + template<typename _CharT> + inline bool + isupper(_CharT, const locale&); + + template<typename _CharT> + inline bool + islower(_CharT, const locale&); + + template<typename _CharT> + inline bool + isalpha(_CharT, const locale&); + + template<typename _CharT> + inline bool + isdigit(_CharT, const locale&); + + template<typename _CharT> + inline bool + ispunct(_CharT, const locale&); + + template<typename _CharT> + inline bool + isxdigit(_CharT, const locale&); + + template<typename _CharT> + inline bool + isalnum(_CharT, const locale&); + + template<typename _CharT> + inline bool + isgraph(_CharT, const locale&); + + template<typename _CharT> + inline _CharT + toupper(_CharT, const locale&); + + template<typename _CharT> + inline _CharT + tolower(_CharT, const locale&); + + // 22.2.1 and 22.2.1.3 ctype + class ctype_base; + template<typename _CharT> + class ctype; + template<> class ctype<char>; +#ifdef _GLIBCXX_USE_WCHAR_T + template<> class ctype<wchar_t>; +#endif + template<typename _CharT> + class ctype_byname; + // NB: Specialized for char and wchar_t in locale_facets.h. + + class codecvt_base; + class __enc_traits; + template<typename _InternT, typename _ExternT, typename _StateT> + class codecvt; + template<> class codecvt<char, char, mbstate_t>; +#ifdef _GLIBCXX_USE_WCHAR_T + template<> class codecvt<wchar_t, char, mbstate_t>; +#endif + template<typename _InternT, typename _ExternT, typename _StateT> + class codecvt_byname; + + // 22.2.2 and 22.2.3 numeric +_GLIBCXX_BEGIN_LDBL_NAMESPACE + template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > + class num_get; + template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > + class num_put; +_GLIBCXX_END_LDBL_NAMESPACE + template<typename _CharT> class numpunct; + template<typename _CharT> class numpunct_byname; + + // 22.2.4 collation + template<typename _CharT> + class collate; + template<typename _CharT> class + collate_byname; + + // 22.2.5 date and time + class time_base; + template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > + class time_get; + template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > + class time_get_byname; + template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > + class time_put; + template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > + class time_put_byname; + + // 22.2.6 money + class money_base; +_GLIBCXX_BEGIN_LDBL_NAMESPACE + template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > + class money_get; + template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > + class money_put; +_GLIBCXX_END_LDBL_NAMESPACE + template<typename _CharT, bool _Intl = false> + class moneypunct; + template<typename _CharT, bool _Intl = false> + class moneypunct_byname; + + // 22.2.7 message retrieval + class messages_base; + template<typename _CharT> + class messages; + template<typename _CharT> + class messages_byname; + + template<typename _Facet> + bool + has_facet(const locale& __loc) throw(); + + template<typename _Facet> + const _Facet& + use_facet(const locale& __loc); + + template<typename _Facet> + inline const _Facet& + __check_facet(const _Facet* __f) + { + if (!__f) + __throw_bad_cast(); + return *__f; + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/mask_array.h b/libstdc++/include/bits/mask_array.h new file mode 100644 index 0000000..98c8bfb --- /dev/null +++ b/libstdc++/include/bits/mask_array.h @@ -0,0 +1,204 @@ +// The template and inlines for the -*- C++ -*- mask_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 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. + +/** @file mask_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _MASK_ARRAY_H +#define _MASK_ARRAY_H 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Reference to selected subset of an array. + * + * A mask_array is a reference to the actual elements of an array specified + * by a bitmask in the form of an array of bool. The way to get a + * mask_array is to call operator[](valarray<bool>) on a valarray. The + * returned mask_array then permits carrying operations out on the + * referenced subset of elements in the original valarray. + * + * For example, if a mask_array is obtained using the array (false, true, + * false, true) as an argument, the mask array has two elements referring + * to array[1] and array[3] in the underlying array. + * + * @param Tp Element type. + */ + template <class _Tp> + class mask_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + mask_array (const mask_array&); + + /// Assignment operator. Assigns elements to corresponding elements + /// of @a a. + mask_array& operator=(const mask_array&); + + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator=(const _Tp&) const; + + // ~mask_array (); + + template<class _Dom> + void operator=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator*=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator/=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator%=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator+=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator-=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator^=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator&=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator|=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator<<=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator>>=(const _Expr<_Dom,_Tp>&) const; + + private: + mask_array(_Array<_Tp>, size_t, _Array<bool>); + friend class valarray<_Tp>; + + const size_t _M_sz; + const _Array<bool> _M_mask; + const _Array<_Tp> _M_array; + + // not implemented + mask_array(); + }; + + template<typename _Tp> + inline mask_array<_Tp>::mask_array(const mask_array<_Tp>& a) + : _M_sz(a._M_sz), _M_mask(a._M_mask), _M_array(a._M_array) {} + + template<typename _Tp> + inline + mask_array<_Tp>::mask_array(_Array<_Tp> __a, size_t __s, _Array<bool> __m) + : _M_sz(__s), _M_mask(__m), _M_array(__a) {} + + template<typename _Tp> + inline mask_array<_Tp>& + mask_array<_Tp>::operator=(const mask_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, __a._M_mask, + _M_sz, _M_array, _M_mask); + return *this; + } + + template<typename _Tp> + inline void + mask_array<_Tp>::operator=(const _Tp& __t) const + { std::__valarray_fill(_M_array, _M_sz, _M_mask, __t); } + + template<typename _Tp> + inline void + mask_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { std::__valarray_copy(_Array<_Tp>(__v), __v.size(), _M_array, _M_mask); } + + template<typename _Tp> + template<class _Ex> + inline void + mask_array<_Tp>::operator=(const _Expr<_Ex, _Tp>& __e) const + { std::__valarray_copy(__e, __e.size(), _M_array, _M_mask); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline void \ + mask_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ + { \ + _Array_augmented_##_Name(_M_array, _M_mask, \ + _Array<_Tp>(__v), __v.size()); \ + } \ + \ + template<typename _Tp> \ + template<class _Dom> \ + inline void \ + mask_array<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_mask, __e, __e.size()); \ + } + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +_GLIBCXX_END_NAMESPACE + +#endif /* _MASK_ARRAY_H */ diff --git a/libstdc++/include/bits/ostream.tcc b/libstdc++/include/bits/ostream.tcc new file mode 100644 index 0000000..c7a2e91 --- /dev/null +++ b/libstdc++/include/bits/ostream.tcc @@ -0,0 +1,374 @@ +// ostream classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, +// 2006, 2007 +// 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. + +/** @file ostream.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 27.6.2 Output streams +// + +#ifndef _OSTREAM_TCC +#define _OSTREAM_TCC 1 + +#pragma GCC system_header + +#include <locale> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>::sentry:: + sentry(basic_ostream<_CharT, _Traits>& __os) + : _M_ok(false), _M_os(__os) + { + // XXX MT + if (__os.tie() && __os.good()) + __os.tie()->flush(); + + if (__os.good()) + _M_ok = true; + else + __os.setstate(ios_base::failbit); + } + + template<typename _CharT, typename _Traits> + template<typename _ValueT> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + _M_insert(_ValueT __v) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __v).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(short __n) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt == ios_base::oct || __fmt == ios_base::hex) + return _M_insert(static_cast<long>(static_cast<unsigned short>(__n))); + else + return _M_insert(static_cast<long>(__n)); + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(int __n) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt == ios_base::oct || __fmt == ios_base::hex) + return _M_insert(static_cast<long>(static_cast<unsigned int>(__n))); + else + return _M_insert(static_cast<long>(__n)); + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__streambuf_type* __sbin) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this); + if (__cerb && __sbin) + { + try + { + if (!__copy_streambufs(__sbin, this->rdbuf())) + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::failbit); } + } + else if (!__sbin) + __err |= ios_base::badbit; + if (__err) + this->setstate(__err); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + put(char_type __c) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::put(char_type) is an unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __put = this->rdbuf()->sputc(__c); + if (traits_type::eq_int_type(__put, traits_type::eof())) + __err |= ios_base::badbit; + } + catch (...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + write(const _CharT* __s, streamsize __n) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::write(const char_type*, streamsize) is an + // unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. + sentry __cerb(*this); + if (__cerb) + { + try + { _M_write(__s, __n); } + catch (...) + { this->_M_setstate(ios_base::badbit); } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + flush() + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::flush() is *not* an unformatted output function. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (this->rdbuf() && this->rdbuf()->pubsync() == -1) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template<typename _CharT, typename _Traits> + typename basic_ostream<_CharT, _Traits>::pos_type + basic_ostream<_CharT, _Traits>:: + tellp() + { + pos_type __ret = pos_type(-1); + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + seekp(pos_type __pos) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::out); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + seekp(off_type __off, ios_base::seekdir __dir) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::out); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) + { + if (!__s) + __out.setstate(ios_base::badbit); + else + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 167. Improper use of traits_type::length() + const size_t __clen = char_traits<char>::length(__s); + _CharT* __ws = 0; + try + { + __ws = new _CharT[__clen]; + for (size_t __i = 0; __i < __clen; ++__i) + __ws[__i] = __out.widen(__s[__i]); + } + catch(...) + { + delete [] __ws; + __out._M_setstate(ios_base::badbit); + return __out; + } + + try + { + __ostream_insert(__out, __ws, __clen); + delete [] __ws; + } + catch(...) + { + delete [] __ws; + __throw_exception_again; + } + } + return __out; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_ostream<char>; + extern template ostream& endl(ostream&); + extern template ostream& ends(ostream&); + extern template ostream& flush(ostream&); + extern template ostream& operator<<(ostream&, char); + extern template ostream& operator<<(ostream&, unsigned char); + extern template ostream& operator<<(ostream&, signed char); + extern template ostream& operator<<(ostream&, const char*); + extern template ostream& operator<<(ostream&, const unsigned char*); + extern template ostream& operator<<(ostream&, const signed char*); + + extern template ostream& ostream::_M_insert(long); + extern template ostream& ostream::_M_insert(unsigned long); + extern template ostream& ostream::_M_insert(bool); +#ifdef _GLIBCXX_USE_LONG_LONG + extern template ostream& ostream::_M_insert(long long); + extern template ostream& ostream::_M_insert(unsigned long long); +#endif + extern template ostream& ostream::_M_insert(double); + extern template ostream& ostream::_M_insert(long double); + extern template ostream& ostream::_M_insert(const void*); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_ostream<wchar_t>; + extern template wostream& endl(wostream&); + extern template wostream& ends(wostream&); + extern template wostream& flush(wostream&); + extern template wostream& operator<<(wostream&, wchar_t); + extern template wostream& operator<<(wostream&, char); + extern template wostream& operator<<(wostream&, const wchar_t*); + extern template wostream& operator<<(wostream&, const char*); + + extern template wostream& wostream::_M_insert(long); + extern template wostream& wostream::_M_insert(unsigned long); + extern template wostream& wostream::_M_insert(bool); +#ifdef _GLIBCXX_USE_LONG_LONG + extern template wostream& wostream::_M_insert(long long); + extern template wostream& wostream::_M_insert(unsigned long long); +#endif + extern template wostream& wostream::_M_insert(double); + extern template wostream& wostream::_M_insert(long double); + extern template wostream& wostream::_M_insert(const void*); +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/ostream_insert.h b/libstdc++/include/bits/ostream_insert.h new file mode 100644 index 0000000..e9e83fb --- /dev/null +++ b/libstdc++/include/bits/ostream_insert.h @@ -0,0 +1,126 @@ +// Helpers for ostream inserters -*- C++ -*- + +// Copyright (C) 2007 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. + +/** @file ostream_insert.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _OSTREAM_INSERT_H +#define _OSTREAM_INSERT_H 1 + +#pragma GCC system_header + +#include <iosfwd> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _CharT, typename _Traits> + inline void + __ostream_write(basic_ostream<_CharT, _Traits>& __out, + const _CharT* __s, streamsize __n) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const streamsize __put = __out.rdbuf()->sputn(__s, __n); + if (__put != __n) + __out.setstate(__ios_base::badbit); + } + + template<typename _CharT, typename _Traits> + inline void + __ostream_fill(basic_ostream<_CharT, _Traits>& __out, streamsize __n) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const _CharT __c = __out.fill(); + for (; __n > 0; --__n) + { + const typename _Traits::int_type __put = __out.rdbuf()->sputc(__c); + if (_Traits::eq_int_type(__put, _Traits::eof())) + { + __out.setstate(__ios_base::badbit); + break; + } + } + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + __ostream_insert(basic_ostream<_CharT, _Traits>& __out, + const _CharT* __s, streamsize __n) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + typename __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try + { + const streamsize __w = __out.width(); + if (__w > __n) + { + const bool __left = ((__out.flags() + & __ios_base::adjustfield) + == __ios_base::left); + if (!__left) + __ostream_fill(__out, __w - __n); + if (__out.good()) + __ostream_write(__out, __s, __n); + if (__left && __out.good()) + __ostream_fill(__out, __w - __n); + } + else + __ostream_write(__out, __s, __n); + __out.width(0); + } + catch(...) + { __out._M_setstate(__ios_base::badbit); } + } + return __out; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template ostream& __ostream_insert(ostream&, const char*, streamsize); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template wostream& __ostream_insert(wostream&, const wchar_t*, + streamsize); +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _OSTREAM_INSERT_H */ diff --git a/libstdc++/include/bits/postypes.h b/libstdc++/include/bits/postypes.h new file mode 100644 index 0000000..40570d9 --- /dev/null +++ b/libstdc++/include/bits/postypes.h @@ -0,0 +1,217 @@ +// Position types -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file postypes.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 27.4.1 - Types +// ISO C++ 14882: 27.4.3 - Template class fpos +// + +#ifndef _GLIBCXX_POSTYPES_H +#define _GLIBCXX_POSTYPES_H 1 + +#pragma GCC system_header + +#include <cwchar> // For mbstate_t + +#ifdef _GLIBCXX_HAVE_STDINT_H +#include <stdint.h> // For int64_t +#endif + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // The types streamoff, streampos and wstreampos and the class + // template fpos<> are described in clauses 21.1.2, 21.1.3, 27.1.2, + // 27.2, 27.4.1, 27.4.3 and D.6. Despite all this verbage, the + // behaviour of these types is mostly implementation defined or + // unspecified. The behaviour in this implementation is as noted + // below. + + /** + * @brief Type used by fpos, char_traits<char>, and char_traits<wchar_t>. + * + * @if maint + * In clauses 21.1.3.1 and 27.4.1 streamoff is described as an + * implementation defined type. + * Note: In versions of GCC up to and including GCC 3.3, streamoff + * was typedef long. + * @endif + */ +#ifdef _GLIBCXX_HAVE_INT64_T + typedef int64_t streamoff; +#else + typedef long long streamoff; +#endif + + /// Integral type for I/O operation counts and buffer sizes. + typedef ptrdiff_t streamsize; // Signed integral type + + template<typename _StateT> + class fpos; + + /** + * @brief Class representing stream positions. + * + * The standard places no requirements upon the template parameter StateT. + * In this implementation StateT must be DefaultConstructible, + * CopyConstructible and Assignable. The standard only requires that fpos + * should contain a member of type StateT. In this implementation it also + * contains an offset stored as a signed integer. + * + * @param StateT Type passed to and returned from state(). + */ + template<typename _StateT> + class fpos + { + private: + streamoff _M_off; + _StateT _M_state; + + public: + // The standard doesn't require that fpos objects can be default + // constructed. This implementation provides a default + // constructor that initializes the offset to 0 and default + // constructs the state. + fpos() + : _M_off(0), _M_state() { } + + // The standard requires that fpos objects can be constructed + // from streamoff objects using the constructor syntax, and + // fails to give any meaningful semantics. In this + // implementation implicit conversion is also allowed, and this + // constructor stores the streamoff as the offset and default + // constructs the state. + /// Construct position from offset. + fpos(streamoff __off) + : _M_off(__off), _M_state() { } + + /// Convert to streamoff. + operator streamoff() const { return _M_off; } + + /// Remember the value of @a st. + void + state(_StateT __st) + { _M_state = __st; } + + /// Return the last set value of @a st. + _StateT + state() const + { return _M_state; } + + // The standard requires that this operator must be defined, but + // gives no semantics. In this implemenation it just adds it's + // argument to the stored offset and returns *this. + /// Add offset to this position. + fpos& + operator+=(streamoff __off) + { + _M_off += __off; + return *this; + } + + // The standard requires that this operator must be defined, but + // gives no semantics. In this implemenation it just subtracts + // it's argument from the stored offset and returns *this. + /// Subtract offset from this position. + fpos& + operator-=(streamoff __off) + { + _M_off -= __off; + return *this; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator-. In this + // implementation it constructs a copy of *this, adds the + // argument to that copy using operator+= and then returns the + // copy. + /// Add position and offset. + fpos + operator+(streamoff __off) const + { + fpos __pos(*this); + __pos += __off; + return __pos; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator+. In this + // implementation it constructs a copy of *this, subtracts the + // argument from that copy using operator-= and then returns the + // copy. + /// Subtract offset from position. + fpos + operator-(streamoff __off) const + { + fpos __pos(*this); + __pos -= __off; + return __pos; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator+. In this + // implementation it returns the difference between the offset + // stored in *this and in the argument. + /// Subtract position to return offset. + streamoff + operator-(const fpos& __other) const + { return _M_off - __other._M_off; } + }; + + // The standard only requires that operator== must be an + // equivalence relation. In this implementation two fpos<StateT> + // objects belong to the same equivalence class if the contained + // offsets compare equal. + /// Test if equivalent to another position. + template<typename _StateT> + inline bool + operator==(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs) + { return streamoff(__lhs) == streamoff(__rhs); } + + template<typename _StateT> + inline bool + operator!=(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs) + { return streamoff(__lhs) != streamoff(__rhs); } + + // Clauses 21.1.3.1 and 21.1.3.2 describe streampos and wstreampos + // as implementation defined types, but clause 27.2 requires that + // they must both be typedefs for fpos<mbstate_t> + /// File position for char streams. + typedef fpos<mbstate_t> streampos; + /// File position for wchar_t streams. + typedef fpos<mbstate_t> wstreampos; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/slice_array.h b/libstdc++/include/bits/slice_array.h new file mode 100644 index 0000000..8eaf90d --- /dev/null +++ b/libstdc++/include/bits/slice_array.h @@ -0,0 +1,269 @@ +// The template and inlines for the -*- C++ -*- slice_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 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. + +/** @file slice_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _SLICE_ARRAY_H +#define _SLICE_ARRAY_H 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Class defining one-dimensional subset of an array. + * + * The slice class represents a one-dimensional subset of an array, + * specified by three parameters: start offset, size, and stride. The + * start offset is the index of the first element of the array that is part + * of the subset. The size is the total number of elements in the subset. + * Stride is the distance between each successive array element to include + * in the subset. + * + * For example, with an array of size 10, and a slice with offset 1, size 3 + * and stride 2, the subset consists of array elements 1, 3, and 5. + */ + class slice + { + public: + /// Construct an empty slice. + slice(); + + /** + * @brief Construct a slice. + * + * @param o Offset in array of first element. + * @param d Number of elements in slice. + * @param s Stride between array elements. + */ + slice(size_t, size_t, size_t); + + /// Return array offset of first slice element. + size_t start() const; + /// Return size of slice. + size_t size() const; + /// Return array stride of slice. + size_t stride() const; + + private: + size_t _M_off; // offset + size_t _M_sz; // size + size_t _M_st; // stride unit + }; + + // The default constructor constructor is not required to initialize + // data members with any meaningful values, so we choose to do nothing. + inline + slice::slice() {} + + inline + slice::slice(size_t __o, size_t __d, size_t __s) + : _M_off(__o), _M_sz(__d), _M_st(__s) {} + + inline size_t + slice::start() const + { return _M_off; } + + inline size_t + slice::size() const + { return _M_sz; } + + inline size_t + slice::stride() const + { return _M_st; } + + /** + * @brief Reference to one-dimensional subset of an array. + * + * A slice_array is a reference to the actual elements of an array + * specified by a slice. The way to get a slice_array is to call + * operator[](slice) on a valarray. The returned slice_array then permits + * carrying operations out on the referenced subset of elements in the + * original valarray. For example, operator+=(valarray) will add values + * to the subset of elements in the underlying valarray this slice_array + * refers to. + * + * @param Tp Element type. + */ + template<typename _Tp> + class slice_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + slice_array(const slice_array&); + + /// Assignment operator. Assigns slice elements to corresponding + /// elements of @a a. + slice_array& operator=(const slice_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator=(const _Tp &) const; + // ~slice_array (); + + template<class _Dom> + void operator=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator*=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator/=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator%=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator+=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator-=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator^=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator&=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator|=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator<<=(const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator>>=(const _Expr<_Dom, _Tp>&) const; + + private: + friend class valarray<_Tp>; + slice_array(_Array<_Tp>, const slice&); + + const size_t _M_sz; + const size_t _M_stride; + const _Array<_Tp> _M_array; + + // not implemented + slice_array(); + }; + + template<typename _Tp> + inline + slice_array<_Tp>::slice_array(_Array<_Tp> __a, const slice& __s) + : _M_sz(__s.size()), _M_stride(__s.stride()), + _M_array(__a.begin() + __s.start()) {} + + template<typename _Tp> + inline + slice_array<_Tp>::slice_array(const slice_array<_Tp>& a) + : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {} + + // template<typename _Tp> + // inline slice_array<_Tp>::~slice_array () {} + + template<typename _Tp> + inline slice_array<_Tp>& + slice_array<_Tp>::operator=(const slice_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, __a._M_sz, __a._M_stride, + _M_array, _M_stride); + return *this; + } + + template<typename _Tp> + inline void + slice_array<_Tp>::operator=(const _Tp& __t) const + { std::__valarray_fill(_M_array, _M_sz, _M_stride, __t); } + + template<typename _Tp> + inline void + slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { std::__valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); } + + template<typename _Tp> + template<class _Dom> + inline void + slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const + { std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op,_Name) \ + template<typename _Tp> \ + inline void \ + slice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ + { \ + _Array_augmented_##_Name(_M_array, _M_sz, _M_stride, _Array<_Tp>(__v));\ + } \ + \ + template<typename _Tp> \ + template<class _Dom> \ + inline void \ + slice_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_stride, __e, _M_sz); \ + } + + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +_GLIBCXX_END_NAMESPACE + +#endif /* _SLICE_ARRAY_H */ diff --git a/libstdc++/include/bits/sstream.tcc b/libstdc++/include/bits/sstream.tcc new file mode 100644 index 0000000..4de1c81 --- /dev/null +++ b/libstdc++/include/bits/sstream.tcc @@ -0,0 +1,279 @@ +// String based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file sstream.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 27.7 String-based streams +// + +#ifndef _SSTREAM_TCC +#define _SSTREAM_TCC 1 + +#pragma GCC system_header + +#include <sstream> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template <class _CharT, class _Traits, class _Alloc> + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + pbackfail(int_type __c) + { + int_type __ret = traits_type::eof(); + if (this->eback() < this->gptr()) + { + // Try to put back __c into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + const bool __testeof = traits_type::eq_int_type(__c, __ret); + if (!__testeof) + { + const bool __testeq = traits_type::eq(traits_type:: + to_char_type(__c), + this->gptr()[-1]); + const bool __testout = this->_M_mode & ios_base::out; + if (__testeq || __testout) + { + this->gbump(-1); + if (!__testeq) + *this->gptr() = traits_type::to_char_type(__c); + __ret = __c; + } + } + else + { + this->gbump(-1); + __ret = traits_type::not_eof(__c); + } + } + return __ret; + } + + template <class _CharT, class _Traits, class _Alloc> + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + overflow(int_type __c) + { + const bool __testout = this->_M_mode & ios_base::out; + if (__builtin_expect(!__testout, false)) + return traits_type::eof(); + + const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); + if (__builtin_expect(__testeof, false)) + return traits_type::not_eof(__c); + + const __size_type __capacity = _M_string.capacity(); + const __size_type __max_size = _M_string.max_size(); + const bool __testput = this->pptr() < this->epptr(); + if (__builtin_expect(!__testput && __capacity == __max_size, false)) + return traits_type::eof(); + + // Try to append __c into output sequence in one of two ways. + // Order these tests done in is unspecified by the standard. + const char_type __conv = traits_type::to_char_type(__c); + if (!__testput) + { + // NB: Start ostringstream buffers at 512 chars. This is an + // experimental value (pronounced "arbitrary" in some of the + // hipper english-speaking countries), and can be changed to + // suit particular needs. + // + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 169. Bad efficiency of overflow() mandated + // 432. stringbuf::overflow() makes only one write position + // available + const __size_type __opt_len = std::max(__size_type(2 * __capacity), + __size_type(512)); + const __size_type __len = std::min(__opt_len, __max_size); + __string_type __tmp; + __tmp.reserve(__len); + if (this->pbase()) + __tmp.assign(this->pbase(), this->epptr() - this->pbase()); + __tmp.push_back(__conv); + _M_string.swap(__tmp); + _M_sync(const_cast<char_type*>(_M_string.data()), + this->gptr() - this->eback(), this->pptr() - this->pbase()); + } + else + *this->pptr() = __conv; + this->pbump(1); + return __c; + } + + template <class _CharT, class _Traits, class _Alloc> + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + underflow() + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin) + { + // Update egptr() to match the actual string end. + _M_update_egptr(); + + if (this->gptr() < this->egptr()) + __ret = traits_type::to_int_type(*this->gptr()); + } + return __ret; + } + + template <class _CharT, class _Traits, class _Alloc> + typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) + { + pos_type __ret = pos_type(off_type(-1)); + bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + const bool __testboth = __testin && __testout && __way != ios_base::cur; + __testin &= !(__mode & ios_base::out); + __testout &= !(__mode & ios_base::in); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 453. basic_stringbuf::seekoff need not always fail for an empty stream. + const char_type* __beg = __testin ? this->eback() : this->pbase(); + if ((__beg || !__off) && (__testin || __testout || __testboth)) + { + _M_update_egptr(); + + off_type __newoffi = __off; + off_type __newoffo = __newoffi; + if (__way == ios_base::cur) + { + __newoffi += this->gptr() - __beg; + __newoffo += this->pptr() - __beg; + } + else if (__way == ios_base::end) + __newoffo = __newoffi += this->egptr() - __beg; + + if ((__testin || __testboth) + && __newoffi >= 0 + && this->egptr() - __beg >= __newoffi) + { + this->gbump((__beg + __newoffi) - this->gptr()); + __ret = pos_type(__newoffi); + } + if ((__testout || __testboth) + && __newoffo >= 0 + && this->egptr() - __beg >= __newoffo) + { + this->pbump((__beg + __newoffo) - this->pptr()); + __ret = pos_type(__newoffo); + } + } + return __ret; + } + + template <class _CharT, class _Traits, class _Alloc> + typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + seekpos(pos_type __sp, ios_base::openmode __mode) + { + pos_type __ret = pos_type(off_type(-1)); + const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + + const char_type* __beg = __testin ? this->eback() : this->pbase(); + if ((__beg || !off_type(__sp)) && (__testin || __testout)) + { + _M_update_egptr(); + + const off_type __pos(__sp); + const bool __testpos = (0 <= __pos + && __pos <= this->egptr() - __beg); + if (__testpos) + { + if (__testin) + this->gbump((__beg + __pos) - this->gptr()); + if (__testout) + this->pbump((__beg + __pos) - this->pptr()); + __ret = __sp; + } + } + return __ret; + } + + template <class _CharT, class _Traits, class _Alloc> + void + basic_stringbuf<_CharT, _Traits, _Alloc>:: + _M_sync(char_type* __base, __size_type __i, __size_type __o) + { + const bool __testin = _M_mode & ios_base::in; + const bool __testout = _M_mode & ios_base::out; + char_type* __endg = __base + _M_string.size(); + char_type* __endp = __base + _M_string.capacity(); + + if (__base != _M_string.data()) + { + // setbuf: __i == size of buffer area (_M_string.size() == 0). + __endg += __i; + __i = 0; + __endp = __endg; + } + + if (__testin) + this->setg(__base, __base + __i, __endg); + if (__testout) + { + this->setp(__base, __endp); + this->pbump(__o); + // egptr() always tracks the string end. When !__testin, + // for the correct functioning of the streambuf inlines + // the other get area pointers are identical. + if (!__testin) + this->setg(__endg, __endg, __endg); + } + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_stringbuf<char>; + extern template class basic_istringstream<char>; + extern template class basic_ostringstream<char>; + extern template class basic_stringstream<char>; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_stringbuf<wchar_t>; + extern template class basic_istringstream<wchar_t>; + extern template class basic_ostringstream<wchar_t>; + extern template class basic_stringstream<wchar_t>; +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/stl_algo.h b/libstdc++/include/bits/stl_algo.h new file mode 100644 index 0000000..cf3cd71 --- /dev/null +++ b/libstdc++/include/bits/stl_algo.h @@ -0,0 +1,5504 @@ +// Algorithm implementation -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_algo.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALGO_H +#define _ALGO_H 1 + +#include <bits/stl_heap.h> +#include <bits/stl_tempbuf.h> // for _Temporary_buffer +#include <debug/debug.h> + +// See concept_check.h for the __glibcxx_*_requires macros. + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Find the median of three values. + * @param a A value. + * @param b A value. + * @param c A value. + * @return One of @p a, @p b or @p c. + * + * If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n + * then the value returned will be @c m. + * This is an SGI extension. + * @ingroup SGIextensions + */ + template<typename _Tp> + inline const _Tp& + __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) + { + // concept requirements + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + if (__a < __b) + if (__b < __c) + return __b; + else if (__a < __c) + return __c; + else + return __a; + else if (__a < __c) + return __a; + else if (__b < __c) + return __c; + else + return __b; + } + + /** + * @brief Find the median of three values using a predicate for comparison. + * @param a A value. + * @param b A value. + * @param c A value. + * @param comp A binary predicate. + * @return One of @p a, @p b or @p c. + * + * If @c {l,m,n} is some convolution of @p {a,b,c} such that @p comp(l,m) + * and @p comp(m,n) are both true then the value returned will be @c m. + * This is an SGI extension. + * @ingroup SGIextensions + */ + template<typename _Tp, typename _Compare> + inline const _Tp& + __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_BinaryFunctionConcept<_Compare,bool,_Tp,_Tp>) + if (__comp(__a, __b)) + if (__comp(__b, __c)) + return __b; + else if (__comp(__a, __c)) + return __c; + else + return __a; + else if (__comp(__a, __c)) + return __a; + else if (__comp(__b, __c)) + return __c; + else + return __b; + } + + /** + * @brief Apply a function to every element of a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param f A unary function object. + * @return @p f. + * + * Applies the function object @p f to each element in the range + * @p [first,last). @p f must not modify the order of the sequence. + * If @p f has a return value it is ignored. + */ + template<typename _InputIterator, typename _Function> + _Function + for_each(_InputIterator __first, _InputIterator __last, _Function __f) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); + for ( ; __first != __last; ++__first) + __f(*__first); + return __f; + } + + /** + * @if maint + * This is an overload used by find() for the Input Iterator case. + * @endif + */ + template<typename _InputIterator, typename _Tp> + inline _InputIterator + __find(_InputIterator __first, _InputIterator __last, + const _Tp& __val, input_iterator_tag) + { + while (__first != __last && !(*__first == __val)) + ++__first; + return __first; + } + + /** + * @if maint + * This is an overload used by find_if() for the Input Iterator case. + * @endif + */ + template<typename _InputIterator, typename _Predicate> + inline _InputIterator + __find_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred, input_iterator_tag) + { + while (__first != __last && !__pred(*__first)) + ++__first; + return __first; + } + + /** + * @if maint + * This is an overload used by find() for the RAI case. + * @endif + */ + template<typename _RandomAccessIterator, typename _Tp> + _RandomAccessIterator + __find(_RandomAccessIterator __first, _RandomAccessIterator __last, + const _Tp& __val, random_access_iterator_tag) + { + typename iterator_traits<_RandomAccessIterator>::difference_type + __trip_count = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) + { + if (*__first == __val) + return __first; + ++__first; + + if (*__first == __val) + return __first; + ++__first; + + if (*__first == __val) + return __first; + ++__first; + + if (*__first == __val) + return __first; + ++__first; + } + + switch (__last - __first) + { + case 3: + if (*__first == __val) + return __first; + ++__first; + case 2: + if (*__first == __val) + return __first; + ++__first; + case 1: + if (*__first == __val) + return __first; + ++__first; + case 0: + default: + return __last; + } + } + + /** + * @if maint + * This is an overload used by find_if() for the RAI case. + * @endif + */ + template<typename _RandomAccessIterator, typename _Predicate> + _RandomAccessIterator + __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Predicate __pred, random_access_iterator_tag) + { + typename iterator_traits<_RandomAccessIterator>::difference_type + __trip_count = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) + { + if (__pred(*__first)) + return __first; + ++__first; + + if (__pred(*__first)) + return __first; + ++__first; + + if (__pred(*__first)) + return __first; + ++__first; + + if (__pred(*__first)) + return __first; + ++__first; + } + + switch (__last - __first) + { + case 3: + if (__pred(*__first)) + return __first; + ++__first; + case 2: + if (__pred(*__first)) + return __first; + ++__first; + case 1: + if (__pred(*__first)) + return __first; + ++__first; + case 0: + default: + return __last; + } + } + + /** + * @if maint + * This is an overload of find() for streambuf iterators. + * @endif + */ + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + istreambuf_iterator<_CharT> >::__type + find(istreambuf_iterator<_CharT>, istreambuf_iterator<_CharT>, + const _CharT&); + + /** + * @brief Find the first occurrence of a value in a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param val The value to find. + * @return The first iterator @c i in the range @p [first,last) + * such that @c *i == @p val, or @p last if no such iterator exists. + */ + template<typename _InputIterator, typename _Tp> + inline _InputIterator + find(_InputIterator __first, _InputIterator __last, + const _Tp& __val) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + return std::__find(__first, __last, __val, + std::__iterator_category(__first)); + } + + /** + * @brief Find the first element in a sequence for which a predicate is true. + * @param first An input iterator. + * @param last An input iterator. + * @param pred A predicate. + * @return The first iterator @c i in the range @p [first,last) + * such that @p pred(*i) is true, or @p last if no such iterator exists. + */ + template<typename _InputIterator, typename _Predicate> + inline _InputIterator + find_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + return std::__find_if(__first, __last, __pred, + std::__iterator_category(__first)); + } + + /** + * @brief Find two adjacent values in a sequence that are equal. + * @param first A forward iterator. + * @param last A forward iterator. + * @return The first iterator @c i such that @c i and @c i+1 are both + * valid iterators in @p [first,last) and such that @c *i == @c *(i+1), + * or @p last if no such iterator exists. + */ + template<typename _ForwardIterator> + _ForwardIterator + adjacent_find(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + if (__first == __last) + return __last; + _ForwardIterator __next = __first; + while(++__next != __last) + { + if (*__first == *__next) + return __first; + __first = __next; + } + return __last; + } + + /** + * @brief Find two adjacent values in a sequence using a predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param binary_pred A binary predicate. + * @return The first iterator @c i such that @c i and @c i+1 are both + * valid iterators in @p [first,last) and such that + * @p binary_pred(*i,*(i+1)) is true, or @p last if no such iterator + * exists. + */ + template<typename _ForwardIterator, typename _BinaryPredicate> + _ForwardIterator + adjacent_find(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + if (__first == __last) + return __last; + _ForwardIterator __next = __first; + while(++__next != __last) + { + if (__binary_pred(*__first, *__next)) + return __first; + __first = __next; + } + return __last; + } + + /** + * @brief Count the number of copies of a value in a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param value The value to be counted. + * @return The number of iterators @c i in the range @p [first,last) + * for which @c *i == @p value + */ + template<typename _InputIterator, typename _Tp> + typename iterator_traits<_InputIterator>::difference_type + count(_InputIterator __first, _InputIterator __last, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + typename iterator_traits<_InputIterator>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + return __n; + } + + /** + * @brief Count the elements of a sequence for which a predicate is true. + * @param first An input iterator. + * @param last An input iterator. + * @param pred A predicate. + * @return The number of iterators @c i in the range @p [first,last) + * for which @p pred(*i) is true. + */ + template<typename _InputIterator, typename _Predicate> + typename iterator_traits<_InputIterator>::difference_type + count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + typename iterator_traits<_InputIterator>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + return __n; + } + + /** + * @brief Search a sequence for a matching sub-sequence. + * @param first1 A forward iterator. + * @param last1 A forward iterator. + * @param first2 A forward iterator. + * @param last2 A forward iterator. + * @return The first iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) + * for each @c N in the range @p [0,last2-first2), or @p last1 if no + * such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) and + * returns an iterator to the first element of the sub-sequence, or + * @p last1 if the sub-sequence is not found. + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template<typename _ForwardIterator1, typename _ForwardIterator2> + _ForwardIterator1 + search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIterator2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return std::find(__first1, __last1, *__first2); + + // General case. + _ForwardIterator2 __p1, __p; + __p1 = __first2; ++__p1; + _ForwardIterator1 __current = __first1; + + while (__first1 != __last1) + { + __first1 = std::find(__first1, __last1, *__first2); + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (*__current == *__p) + { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + ++__first1; + } + return __first1; + } + + /** + * @brief Search a sequence for a matching sub-sequence using a predicate. + * @param first1 A forward iterator. + * @param last1 A forward iterator. + * @param first2 A forward iterator. + * @param last2 A forward iterator. + * @param predicate A binary predicate. + * @return The first iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that + * @p predicate(*(i+N),*(first2+N)) is true for each @c N in the range + * @p [0,last2-first2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2), + * using @p predicate to determine equality, and returns an iterator + * to the first element of the sub-sequence, or @p last1 if no such + * iterator exists. + * + * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) + */ + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + _ForwardIterator1 + search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __predicate) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIterator2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + { + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + return __first1; + } + + // General case. + _ForwardIterator2 __p1, __p; + __p1 = __first2; ++__p1; + _ForwardIterator1 __current = __first1; + + while (__first1 != __last1) + { + while (__first1 != __last1) + { + if (__predicate(*__first1, *__first2)) + break; + ++__first1; + } + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (__predicate(*__current, *__p)) + { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + ++__first1; + } + return __first1; + } + + /** + * @if maint + * This is an uglified + * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) + * overloaded for forward iterators. + * @endif + */ + template<typename _ForwardIterator, typename _Integer, typename _Tp> + _ForwardIterator + __search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, const _Tp& __val, + std::forward_iterator_tag) + { + __first = std::find(__first, __last, __val); + while (__first != __last) + { + typename iterator_traits<_ForwardIterator>::difference_type + __n = __count; + _ForwardIterator __i = __first; + ++__i; + while (__i != __last && __n != 1 && *__i == __val) + { + ++__i; + --__n; + } + if (__n == 1) + return __first; + if (__i == __last) + return __last; + __first = std::find(++__i, __last, __val); + } + return __last; + } + + /** + * @if maint + * This is an uglified + * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) + * overloaded for random access iterators. + * @endif + */ + template<typename _RandomAccessIter, typename _Integer, typename _Tp> + _RandomAccessIter + __search_n(_RandomAccessIter __first, _RandomAccessIter __last, + _Integer __count, const _Tp& __val, + std::random_access_iterator_tag) + { + + typedef typename std::iterator_traits<_RandomAccessIter>::difference_type + _DistanceType; + + _DistanceType __tailSize = __last - __first; + const _DistanceType __pattSize = __count; + + if (__tailSize < __pattSize) + return __last; + + const _DistanceType __skipOffset = __pattSize - 1; + _RandomAccessIter __lookAhead = __first + __skipOffset; + __tailSize -= __pattSize; + + while (1) // the main loop... + { + // __lookAhead here is always pointing to the last element of next + // possible match. + while (!(*__lookAhead == __val)) // the skip loop... + { + if (__tailSize < __pattSize) + return __last; // Failure + __lookAhead += __pattSize; + __tailSize -= __pattSize; + } + _DistanceType __remainder = __skipOffset; + for (_RandomAccessIter __backTrack = __lookAhead - 1; + *__backTrack == __val; --__backTrack) + { + if (--__remainder == 0) + return (__lookAhead - __skipOffset); // Success + } + if (__remainder > __tailSize) + return __last; // Failure + __lookAhead += __remainder; + __tailSize -= __remainder; + } + } + + /** + * @brief Search a sequence for a number of consecutive values. + * @param first A forward iterator. + * @param last A forward iterator. + * @param count The number of consecutive values. + * @param val The value to find. + * @return The first iterator @c i in the range @p [first,last-count) + * such that @c *(i+N) == @p val for each @c N in the range @p [0,count), + * or @p last if no such iterator exists. + * + * Searches the range @p [first,last) for @p count consecutive elements + * equal to @p val. + */ + template<typename _ForwardIterator, typename _Integer, typename _Tp> + _ForwardIterator + search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, const _Tp& __val) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + if (__count <= 0) + return __first; + if (__count == 1) + return std::find(__first, __last, __val); + return std::__search_n(__first, __last, __count, __val, + std::__iterator_category(__first)); + } + + /** + * @if maint + * This is an uglified + * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, + * _BinaryPredicate) + * overloaded for forward iterators. + * @endif + */ + template<typename _ForwardIterator, typename _Integer, typename _Tp, + typename _BinaryPredicate> + _ForwardIterator + __search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, const _Tp& __val, + _BinaryPredicate __binary_pred, std::forward_iterator_tag) + { + while (__first != __last && !__binary_pred(*__first, __val)) + ++__first; + + while (__first != __last) + { + typename iterator_traits<_ForwardIterator>::difference_type + __n = __count; + _ForwardIterator __i = __first; + ++__i; + while (__i != __last && __n != 1 && __binary_pred(*__i, __val)) + { + ++__i; + --__n; + } + if (__n == 1) + return __first; + if (__i == __last) + return __last; + __first = ++__i; + while (__first != __last && !__binary_pred(*__first, __val)) + ++__first; + } + return __last; + } + + /** + * @if maint + * This is an uglified + * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, + * _BinaryPredicate) + * overloaded for random access iterators. + * @endif + */ + template<typename _RandomAccessIter, typename _Integer, typename _Tp, + typename _BinaryPredicate> + _RandomAccessIter + __search_n(_RandomAccessIter __first, _RandomAccessIter __last, + _Integer __count, const _Tp& __val, + _BinaryPredicate __binary_pred, std::random_access_iterator_tag) + { + + typedef typename std::iterator_traits<_RandomAccessIter>::difference_type + _DistanceType; + + _DistanceType __tailSize = __last - __first; + const _DistanceType __pattSize = __count; + + if (__tailSize < __pattSize) + return __last; + + const _DistanceType __skipOffset = __pattSize - 1; + _RandomAccessIter __lookAhead = __first + __skipOffset; + __tailSize -= __pattSize; + + while (1) // the main loop... + { + // __lookAhead here is always pointing to the last element of next + // possible match. + while (!__binary_pred(*__lookAhead, __val)) // the skip loop... + { + if (__tailSize < __pattSize) + return __last; // Failure + __lookAhead += __pattSize; + __tailSize -= __pattSize; + } + _DistanceType __remainder = __skipOffset; + for (_RandomAccessIter __backTrack = __lookAhead - 1; + __binary_pred(*__backTrack, __val); --__backTrack) + { + if (--__remainder == 0) + return (__lookAhead - __skipOffset); // Success + } + if (__remainder > __tailSize) + return __last; // Failure + __lookAhead += __remainder; + __tailSize -= __remainder; + } + } + + /** + * @brief Search a sequence for a number of consecutive values using a + * predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param count The number of consecutive values. + * @param val The value to find. + * @param binary_pred A binary predicate. + * @return The first iterator @c i in the range @p [first,last-count) + * such that @p binary_pred(*(i+N),val) is true for each @c N in the + * range @p [0,count), or @p last if no such iterator exists. + * + * Searches the range @p [first,last) for @p count consecutive elements + * for which the predicate returns true. + */ + template<typename _ForwardIterator, typename _Integer, typename _Tp, + typename _BinaryPredicate> + _ForwardIterator + search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, const _Tp& __val, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + if (__count <= 0) + return __first; + if (__count == 1) + { + while (__first != __last && !__binary_pred(*__first, __val)) + ++__first; + return __first; + } + return std::__search_n(__first, __last, __count, __val, __binary_pred, + std::__iterator_category(__first)); + } + + /** + * @brief Swap the elements of two sequences. + * @param first1 A forward iterator. + * @param last1 A forward iterator. + * @param first2 A forward iterator. + * @return An iterator equal to @p first2+(last1-first1). + * + * Swaps each element in the range @p [first1,last1) with the + * corresponding element in the range @p [first2,(last1-first1)). + * The ranges must not overlap. + */ + template<typename _ForwardIterator1, typename _ForwardIterator2> + _ForwardIterator2 + swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator1>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator2>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_ForwardIterator2>::value_type, + typename iterator_traits<_ForwardIterator1>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + std::iter_swap(__first1, __first2); + return __first2; + } + + /** + * @brief Perform an operation on a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param unary_op A unary operator. + * @return An output iterator equal to @p result+(last-first). + * + * Applies the operator to each element in the input range and assigns + * the results to successive elements of the output sequence. + * Evaluates @p *(result+N)=unary_op(*(first+N)) for each @c N in the + * range @p [0,last-first). + * + * @p unary_op must not alter its argument. + */ + template<typename _InputIterator, typename _OutputIterator, + typename _UnaryOperation> + _OutputIterator + transform(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _UnaryOperation __unary_op) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + // "the type returned by a _UnaryOperation" + __typeof__(__unary_op(*__first))>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first, ++__result) + *__result = __unary_op(*__first); + return __result; + } + + /** + * @brief Perform an operation on corresponding elements of two sequences. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param result An output iterator. + * @param binary_op A binary operator. + * @return An output iterator equal to @p result+(last-first). + * + * Applies the operator to the corresponding elements in the two + * input ranges and assigns the results to successive elements of the + * output sequence. + * Evaluates @p *(result+N)=binary_op(*(first1+N),*(first2+N)) for each + * @c N in the range @p [0,last1-first1). + * + * @p binary_op must not alter either of its arguments. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _BinaryOperation> + _OutputIterator + transform(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _OutputIterator __result, + _BinaryOperation __binary_op) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + // "the type returned by a _BinaryOperation" + __typeof__(__binary_op(*__first1,*__first2))>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; + } + + /** + * @brief Replace each occurrence of one value in a sequence with another + * value. + * @param first A forward iterator. + * @param last A forward iterator. + * @param old_value The value to be replaced. + * @param new_value The replacement value. + * @return replace() returns no value. + * + * For each iterator @c i in the range @p [first,last) if @c *i == + * @p old_value then the assignment @c *i = @p new_value is performed. + */ + template<typename _ForwardIterator, typename _Tp> + void + replace(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __old_value, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; + } + + /** + * @brief Replace each value in a sequence for which a predicate returns + * true with another value. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate. + * @param new_value The replacement value. + * @return replace_if() returns no value. + * + * For each iterator @c i in the range @p [first,last) if @p pred(*i) + * is true then the assignment @c *i = @p new_value is performed. + */ + template<typename _ForwardIterator, typename _Predicate, typename _Tp> + void + replace_if(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; + } + + /** + * @brief Copy a sequence, replacing each element of one value with another + * value. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param old_value The value to be replaced. + * @param new_value The replacement value. + * @return The end of the output sequence, @p result+(last-first). + * + * Copies each element in the input range @p [first,last) to the + * output range @p [result,result+(last-first)) replacing elements + * equal to @p old_value with @p new_value. + */ + template<typename _InputIterator, typename _OutputIterator, typename _Tp> + _OutputIterator + replace_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + const _Tp& __old_value, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first, ++__result) + if (*__first == __old_value) + *__result = __new_value; + else + *__result = *__first; + return __result; + } + + /** + * @brief Copy a sequence, replacing each value for which a predicate + * returns true with another value. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param pred A predicate. + * @param new_value The replacement value. + * @return The end of the output sequence, @p result+(last-first). + * + * Copies each element in the range @p [first,last) to the range + * @p [result,result+(last-first)) replacing elements for which + * @p pred returns true with @p new_value. + */ + template<typename _InputIterator, typename _OutputIterator, + typename _Predicate, typename _Tp> + _OutputIterator + replace_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _Predicate __pred, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first, ++__result) + if (__pred(*__first)) + *__result = __new_value; + else + *__result = *__first; + return __result; + } + + /** + * @brief Assign the result of a function object to each value in a + * sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @param gen A function object taking no arguments. + * @return generate() returns no value. + * + * Performs the assignment @c *i = @p gen() for each @c i in the range + * @p [first,last). + */ + template<typename _ForwardIterator, typename _Generator> + void + generate(_ForwardIterator __first, _ForwardIterator __last, + _Generator __gen) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_GeneratorConcept<_Generator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + *__first = __gen(); + } + + /** + * @brief Assign the result of a function object to each value in a + * sequence. + * @param first A forward iterator. + * @param n The length of the sequence. + * @param gen A function object taking no arguments. + * @return The end of the sequence, @p first+n + * + * Performs the assignment @c *i = @p gen() for each @c i in the range + * @p [first,first+n). + */ + template<typename _OutputIterator, typename _Size, typename _Generator> + _OutputIterator + generate_n(_OutputIterator __first, _Size __n, _Generator __gen) + { + // concept requirements + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + // "the type returned by a _Generator" + __typeof__(__gen())>) + + for ( ; __n > 0; --__n, ++__first) + *__first = __gen(); + return __first; + } + + /** + * @brief Copy a sequence, removing elements of a given value. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param value The value to be removed. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) not equal to @p value + * to the range beginning at @p result. + * remove_copy() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template<typename _InputIterator, typename _OutputIterator, typename _Tp> + _OutputIterator + remove_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (!(*__first == __value)) + { + *__result = *__first; + ++__result; + } + return __result; + } + + /** + * @brief Copy a sequence, removing elements for which a predicate is true. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param pred A predicate. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) for which + * @p pred returns true to the range beginning at @p result. + * + * remove_copy_if() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template<typename _InputIterator, typename _OutputIterator, + typename _Predicate> + _OutputIterator + remove_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (!__pred(*__first)) + { + *__result = *__first; + ++__result; + } + return __result; + } + + /** + * @brief Remove elements from a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param value The value to be removed. + * @return An iterator designating the end of the resulting sequence. + * + * All elements equal to @p value are removed from the range + * @p [first,last). + * + * remove() is stable, so the relative order of elements that are + * not removed is unchanged. + * + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template<typename _ForwardIterator, typename _Tp> + _ForwardIterator + remove(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + __first = std::find(__first, __last, __value); + _ForwardIterator __i = __first; + return __first == __last ? __first + : std::remove_copy(++__i, __last, + __first, __value); + } + + /** + * @brief Remove elements from a sequence using a predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate. + * @return An iterator designating the end of the resulting sequence. + * + * All elements for which @p pred returns true are removed from the range + * @p [first,last). + * + * remove_if() is stable, so the relative order of elements that are + * not removed is unchanged. + * + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + remove_if(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + __first = std::find_if(__first, __last, __pred); + _ForwardIterator __i = __first; + return __first == __last ? __first + : std::remove_copy_if(++__i, __last, + __first, __pred); + } + + /** + * @if maint + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) + * overloaded for forward iterators and output iterator as result. + * @endif + */ + template<typename _ForwardIterator, typename _OutputIterator> + _OutputIterator + __unique_copy(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __result, + forward_iterator_tag, output_iterator_tag) + { + // concept requirements -- taken care of in dispatching function + _ForwardIterator __next = __first; + *__result = *__first; + while (++__next != __last) + if (!(*__first == *__next)) + { + __first = __next; + *++__result = *__first; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) + * overloaded for input iterators and output iterator as result. + * @endif + */ + template<typename _InputIterator, typename _OutputIterator> + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + input_iterator_tag, output_iterator_tag) + { + // concept requirements -- taken care of in dispatching function + typename iterator_traits<_InputIterator>::value_type __value = *__first; + *__result = __value; + while (++__first != __last) + if (!(__value == *__first)) + { + __value = *__first; + *++__result = __value; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) + * overloaded for input iterators and forward iterator as result. + * @endif + */ + template<typename _InputIterator, typename _ForwardIterator> + _ForwardIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + input_iterator_tag, forward_iterator_tag) + { + // concept requirements -- taken care of in dispatching function + *__result = *__first; + while (++__first != __last) + if (!(*__result == *__first)) + *++__result = *__first; + return ++__result; + } + + /** + * @if maint + * This is an uglified + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) + * overloaded for forward iterators and output iterator as result. + * @endif + */ + template<typename _ForwardIterator, typename _OutputIterator, + typename _BinaryPredicate> + _OutputIterator + __unique_copy(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __result, _BinaryPredicate __binary_pred, + forward_iterator_tag, output_iterator_tag) + { + // concept requirements -- iterators already checked + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + + _ForwardIterator __next = __first; + *__result = *__first; + while (++__next != __last) + if (!__binary_pred(*__first, *__next)) + { + __first = __next; + *++__result = *__first; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) + * overloaded for input iterators and output iterator as result. + * @endif + */ + template<typename _InputIterator, typename _OutputIterator, + typename _BinaryPredicate> + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryPredicate __binary_pred, + input_iterator_tag, output_iterator_tag) + { + // concept requirements -- iterators already checked + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) + + typename iterator_traits<_InputIterator>::value_type __value = *__first; + *__result = __value; + while (++__first != __last) + if (!__binary_pred(__value, *__first)) + { + __value = *__first; + *++__result = __value; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) + * overloaded for input iterators and forward iterator as result. + * @endif + */ + template<typename _InputIterator, typename _ForwardIterator, + typename _BinaryPredicate> + _ForwardIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, _BinaryPredicate __binary_pred, + input_iterator_tag, forward_iterator_tag) + { + // concept requirements -- iterators already checked + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) + + *__result = *__first; + while (++__first != __last) + if (!__binary_pred(*__result, *__first)) + *++__result = *__first; + return ++__result; + } + + /** + * @brief Copy a sequence, removing consecutive duplicate values. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) to the range + * beginning at @p result, except that only the first element is copied + * from groups of consecutive elements that compare equal. + * unique_copy() is stable, so the relative order of elements that are + * copied is unchanged. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * DR 241. Does unique_copy() require CopyConstructible and Assignable? + * + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * DR 538. 241 again: Does unique_copy() require CopyConstructible and + * Assignable? + * @endif + */ + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __result; + return std::__unique_copy(__first, __last, __result, + std::__iterator_category(__first), + std::__iterator_category(__result)); + } + + /** + * @brief Copy a sequence, removing consecutive values using a predicate. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param binary_pred A binary predicate. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) to the range + * beginning at @p result, except that only the first element is copied + * from groups of consecutive elements for which @p binary_pred returns + * true. + * unique_copy() is stable, so the relative order of elements that are + * copied is unchanged. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * DR 241. Does unique_copy() require CopyConstructible and Assignable? + * @endif + */ + template<typename _InputIterator, typename _OutputIterator, + typename _BinaryPredicate> + inline _OutputIterator + unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _BinaryPredicate __binary_pred) + { + // concept requirements -- predicates checked later + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __result; + return std::__unique_copy(__first, __last, __result, __binary_pred, + std::__iterator_category(__first), + std::__iterator_category(__result)); + } + + /** + * @brief Remove consecutive duplicate values from a sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Removes all but the first element from each group of consecutive + * values that compare equal. + * unique() is stable, so the relative order of elements that are + * not removed is unchanged. + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template<typename _ForwardIterator> + _ForwardIterator + unique(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + // Skip the beginning, if already unique. + __first = std::adjacent_find(__first, __last); + if (__first == __last) + return __last; + + // Do the real copy work. + _ForwardIterator __dest = __first; + ++__first; + while (++__first != __last) + if (!(*__dest == *__first)) + *++__dest = *__first; + return ++__dest; + } + + /** + * @brief Remove consecutive values from a sequence using a predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param binary_pred A binary predicate. + * @return An iterator designating the end of the resulting sequence. + * + * Removes all but the first element from each group of consecutive + * values for which @p binary_pred returns true. + * unique() is stable, so the relative order of elements that are + * not removed is unchanged. + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template<typename _ForwardIterator, typename _BinaryPredicate> + _ForwardIterator + unique(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + // Skip the beginning, if already unique. + __first = std::adjacent_find(__first, __last, __binary_pred); + if (__first == __last) + return __last; + + // Do the real copy work. + _ForwardIterator __dest = __first; + ++__first; + while (++__first != __last) + if (!__binary_pred(*__dest, *__first)) + *++__dest = *__first; + return ++__dest; + } + + /** + * @if maint + * This is an uglified reverse(_BidirectionalIterator, + * _BidirectionalIterator) + * overloaded for bidirectional iterators. + * @endif + */ + template<typename _BidirectionalIterator> + void + __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, + bidirectional_iterator_tag) + { + while (true) + if (__first == __last || __first == --__last) + return; + else + { + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @if maint + * This is an uglified reverse(_BidirectionalIterator, + * _BidirectionalIterator) + * overloaded for random access iterators. + * @endif + */ + template<typename _RandomAccessIterator> + void + __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) + { + if (__first == __last) + return; + --__last; + while (__first < __last) + { + std::iter_swap(__first, __last); + ++__first; + --__last; + } + } + + /** + * @brief Reverse a sequence. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @return reverse() returns no value. + * + * Reverses the order of the elements in the range @p [first,last), + * so that the first element becomes the last etc. + * For every @c i such that @p 0<=i<=(last-first)/2), @p reverse() + * swaps @p *(first+i) and @p *(last-(i+1)) + */ + template<typename _BidirectionalIterator> + inline void + reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_requires_valid_range(__first, __last); + std::__reverse(__first, __last, std::__iterator_category(__first)); + } + + /** + * @brief Copy a sequence, reversing its elements. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies the elements in the range @p [first,last) to the range + * @p [result,result+(last-first)) such that the order of the + * elements is reversed. + * For every @c i such that @p 0<=i<=(last-first), @p reverse_copy() + * performs the assignment @p *(result+(last-first)-i) = *(first+i). + * The ranges @p [first,last) and @p [result,result+(last-first)) + * must not overlap. + */ + template<typename _BidirectionalIterator, typename _OutputIterator> + _OutputIterator + reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + while (__first != __last) + { + --__last; + *__result = *__last; + ++__result; + } + return __result; + } + + + /** + * @if maint + * This is a helper function for the rotate algorithm specialized on RAIs. + * It returns the greatest common divisor of two integer values. + * @endif + */ + template<typename _EuclideanRingElement> + _EuclideanRingElement + __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) + { + while (__n != 0) + { + _EuclideanRingElement __t = __m % __n; + __m = __n; + __n = __t; + } + return __m; + } + + /** + * @if maint + * This is a helper function for the rotate algorithm. + * @endif + */ + template<typename _ForwardIterator> + void + __rotate(_ForwardIterator __first, + _ForwardIterator __middle, + _ForwardIterator __last, + forward_iterator_tag) + { + if (__first == __middle || __last == __middle) + return; + + _ForwardIterator __first2 = __middle; + do + { + swap(*__first, *__first2); + ++__first; + ++__first2; + if (__first == __middle) + __middle = __first2; + } + while (__first2 != __last); + + __first2 = __middle; + + while (__first2 != __last) + { + swap(*__first, *__first2); + ++__first; + ++__first2; + if (__first == __middle) + __middle = __first2; + else if (__first2 == __last) + __first2 = __middle; + } + } + + /** + * @if maint + * This is a helper function for the rotate algorithm. + * @endif + */ + template<typename _BidirectionalIterator> + void + __rotate(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + bidirectional_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + + if (__first == __middle || __last == __middle) + return; + + std::__reverse(__first, __middle, bidirectional_iterator_tag()); + std::__reverse(__middle, __last, bidirectional_iterator_tag()); + + while (__first != __middle && __middle != __last) + { + swap(*__first, *--__last); + ++__first; + } + + if (__first == __middle) + std::__reverse(__middle, __last, bidirectional_iterator_tag()); + else + std::__reverse(__first, __middle, bidirectional_iterator_tag()); + } + + /** + * @if maint + * This is a helper function for the rotate algorithm. + * @endif + */ + template<typename _RandomAccessIterator> + void + __rotate(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + + if (__first == __middle || __last == __middle) + return; + + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + const _Distance __n = __last - __first; + const _Distance __k = __middle - __first; + const _Distance __l = __n - __k; + + if (__k == __l) + { + std::swap_ranges(__first, __middle, __middle); + return; + } + + const _Distance __d = __gcd(__n, __k); + + for (_Distance __i = 0; __i < __d; __i++) + { + _ValueType __tmp = *__first; + _RandomAccessIterator __p = __first; + + if (__k < __l) + { + for (_Distance __j = 0; __j < __l / __d; __j++) + { + if (__p > __first + __l) + { + *__p = *(__p - __l); + __p -= __l; + } + + *__p = *(__p + __k); + __p += __k; + } + } + else + { + for (_Distance __j = 0; __j < __k / __d - 1; __j ++) + { + if (__p < __last - __k) + { + *__p = *(__p + __k); + __p += __k; + } + *__p = * (__p - __l); + __p -= __l; + } + } + + *__p = __tmp; + ++__first; + } + } + + /** + * @brief Rotate the elements of a sequence. + * @param first A forward iterator. + * @param middle A forward iterator. + * @param last A forward iterator. + * @return Nothing. + * + * Rotates the elements of the range @p [first,last) by @p (middle-first) + * positions so that the element at @p middle is moved to @p first, the + * element at @p middle+1 is moved to @first+1 and so on for each element + * in the range @p [first,last). + * + * This effectively swaps the ranges @p [first,middle) and + * @p [middle,last). + * + * Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for + * each @p n in the range @p [0,last-first). + */ + template<typename _ForwardIterator> + inline void + rotate(_ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + typedef typename iterator_traits<_ForwardIterator>::iterator_category + _IterType; + std::__rotate(__first, __middle, __last, _IterType()); + } + + /** + * @brief Copy a sequence, rotating its elements. + * @param first A forward iterator. + * @param middle A forward iterator. + * @param last A forward iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies the elements of the range @p [first,last) to the range + * beginning at @result, rotating the copied elements by @p (middle-first) + * positions so that the element at @p middle is moved to @p result, the + * element at @p middle+1 is moved to @result+1 and so on for each element + * in the range @p [first,last). + * + * Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for + * each @p n in the range @p [0,last-first). + */ + template<typename _ForwardIterator, typename _OutputIterator> + _OutputIterator + rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last, _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + return std::copy(__first, __middle, + std::copy(__middle, __last, __result)); + } + + /** + * @brief Randomly shuffle the elements of a sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @return Nothing. + * + * Reorder the elements in the range @p [first,last) using a random + * distribution, so that every possible ordering of the sequence is + * equally likely. + */ + template<typename _RandomAccessIterator> + inline void + random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1))); + } + + /** + * @brief Shuffle the elements of a sequence using a random number + * generator. + * @param first A forward iterator. + * @param last A forward iterator. + * @param rand The RNG functor or function. + * @return Nothing. + * + * Reorders the elements in the range @p [first,last) using @p rand to + * provide a random distribution. Calling @p rand(N) for a positive + * integer @p N should return a randomly chosen integer from the + * range [0,N). + */ + template<typename _RandomAccessIterator, typename _RandomNumberGenerator> + void + random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomNumberGenerator& __rand) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return; + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + std::iter_swap(__i, __first + __rand((__i - __first) + 1)); + } + + + /** + * @if maint + * This is a helper function... + * @endif + */ + template<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + __partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, + forward_iterator_tag) + { + if (__first == __last) + return __first; + + while (__pred(*__first)) + if (++__first == __last) + return __first; + + _ForwardIterator __next = __first; + + while (++__next != __last) + if (__pred(*__next)) + { + swap(*__first, *__next); + ++__first; + } + + return __first; + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template<typename _BidirectionalIterator, typename _Predicate> + _BidirectionalIterator + __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, + _Predicate __pred, + bidirectional_iterator_tag) + { + while (true) + { + while (true) + if (__first == __last) + return __first; + else if (__pred(*__first)) + ++__first; + else + break; + --__last; + while (true) + if (__first == __last) + return __first; + else if (!__pred(*__last)) + --__last; + else + break; + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @brief Move elements for which a predicate is true to the beginning + * of a sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate functor. + * @return An iterator @p middle such that @p pred(i) is true for each + * iterator @p i in the range @p [first,middle) and false for each @p i + * in the range @p [middle,last). + * + * @p pred must not modify its operand. @p partition() does not preserve + * the relative ordering of elements in each group, use + * @p stable_partition() if this is needed. + */ + template<typename _ForwardIterator, typename _Predicate> + inline _ForwardIterator + partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__partition(__first, __last, __pred, + std::__iterator_category(__first)); + } + + + /** + * @if maint + * This is a helper function... + * @endif + */ + template<typename _ForwardIterator, typename _Predicate, typename _Distance> + _ForwardIterator + __inplace_stable_partition(_ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, _Distance __len) + { + if (__len == 1) + return __pred(*__first) ? __last : __first; + _ForwardIterator __middle = __first; + std::advance(__middle, __len / 2); + _ForwardIterator __begin = std::__inplace_stable_partition(__first, + __middle, + __pred, + __len / 2); + _ForwardIterator __end = std::__inplace_stable_partition(__middle, __last, + __pred, + __len + - __len / 2); + std::rotate(__begin, __middle, __end); + std::advance(__begin, std::distance(__middle, __end)); + return __begin; + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template<typename _ForwardIterator, typename _Pointer, typename _Predicate, + typename _Distance> + _ForwardIterator + __stable_partition_adaptive(_ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, _Distance __len, + _Pointer __buffer, + _Distance __buffer_size) + { + if (__len <= __buffer_size) + { + _ForwardIterator __result1 = __first; + _Pointer __result2 = __buffer; + for ( ; __first != __last ; ++__first) + if (__pred(*__first)) + { + *__result1 = *__first; + ++__result1; + } + else + { + *__result2 = *__first; + ++__result2; + } + std::copy(__buffer, __result2, __result1); + return __result1; + } + else + { + _ForwardIterator __middle = __first; + std::advance(__middle, __len / 2); + _ForwardIterator __begin = + std::__stable_partition_adaptive(__first, __middle, __pred, + __len / 2, __buffer, + __buffer_size); + _ForwardIterator __end = + std::__stable_partition_adaptive(__middle, __last, __pred, + __len - __len / 2, + __buffer, __buffer_size); + std::rotate(__begin, __middle, __end); + std::advance(__begin, std::distance(__middle, __end)); + return __begin; + } + } + + /** + * @brief Move elements for which a predicate is true to the beginning + * of a sequence, preserving relative ordering. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate functor. + * @return An iterator @p middle such that @p pred(i) is true for each + * iterator @p i in the range @p [first,middle) and false for each @p i + * in the range @p [middle,last). + * + * Performs the same function as @p partition() with the additional + * guarantee that the relative ordering of elements in each group is + * preserved, so any two elements @p x and @p y in the range + * @p [first,last) such that @p pred(x)==pred(y) will have the same + * relative ordering after calling @p stable_partition(). + */ + template<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + stable_partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + else + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, + __last); + if (__buf.size() > 0) + return + std::__stable_partition_adaptive(__first, __last, __pred, + _DistanceType(__buf.requested_size()), + __buf.begin(), __buf.size()); + else + return + std::__inplace_stable_partition(__first, __last, __pred, + _DistanceType(__buf.requested_size())); + } + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template<typename _RandomAccessIterator, typename _Tp> + _RandomAccessIterator + __unguarded_partition(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp __pivot) + { + while (true) + { + while (*__first < __pivot) + ++__first; + --__last; + while (__pivot < *__last) + --__last; + if (!(__first < __last)) + return __first; + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template<typename _RandomAccessIterator, typename _Tp, typename _Compare> + _RandomAccessIterator + __unguarded_partition(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Tp __pivot, _Compare __comp) + { + while (true) + { + while (__comp(*__first, __pivot)) + ++__first; + --__last; + while (__comp(__pivot, *__last)) + --__last; + if (!(__first < __last)) + return __first; + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @if maint + * @doctodo + * This controls some aspect of the sort routines. + * @endif + */ + enum { _S_threshold = 16 }; + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator, typename _Tp> + void + __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val) + { + _RandomAccessIterator __next = __last; + --__next; + while (__val < *__next) + { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator, typename _Tp, typename _Compare> + void + __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val, + _Compare __comp) + { + _RandomAccessIterator __next = __last; + --__next; + while (__comp(__val, *__next)) + { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator> + void + __insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + if (__first == __last) + return; + + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + { + typename iterator_traits<_RandomAccessIterator>::value_type + __val = *__i; + if (__val < *__first) + { + std::copy_backward(__first, __i, __i + 1); + *__first = __val; + } + else + std::__unguarded_linear_insert(__i, __val); + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator, typename _Compare> + void + __insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__first == __last) return; + + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + { + typename iterator_traits<_RandomAccessIterator>::value_type + __val = *__i; + if (__comp(__val, *__first)) + { + std::copy_backward(__first, __i, __i + 1); + *__first = __val; + } + else + std::__unguarded_linear_insert(__i, __val, __comp); + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator> + inline void + __unguarded_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + for (_RandomAccessIterator __i = __first; __i != __last; ++__i) + std::__unguarded_linear_insert(__i, _ValueType(*__i)); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator, typename _Compare> + inline void + __unguarded_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + for (_RandomAccessIterator __i = __first; __i != __last; ++__i) + std::__unguarded_linear_insert(__i, _ValueType(*__i), __comp); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator> + void + __final_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + if (__last - __first > int(_S_threshold)) + { + std::__insertion_sort(__first, __first + int(_S_threshold)); + std::__unguarded_insertion_sort(__first + int(_S_threshold), __last); + } + else + std::__insertion_sort(__first, __last); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator, typename _Compare> + void + __final_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__last - __first > int(_S_threshold)) + { + std::__insertion_sort(__first, __first + int(_S_threshold), __comp); + std::__unguarded_insertion_sort(__first + int(_S_threshold), __last, + __comp); + } + else + std::__insertion_sort(__first, __last, __comp); + } + + /** + * @if maint + * This is a helper function for the sort routines. + * @endif + */ + template<typename _RandomAccessIterator> + void + __heap_select(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + std::make_heap(__first, __middle); + for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) + if (*__i < *__first) + std::__pop_heap(__first, __middle, __i, _ValueType(*__i)); + } + + /** + * @if maint + * This is a helper function for the sort routines. + * @endif + */ + template<typename _RandomAccessIterator, typename _Compare> + void + __heap_select(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + std::make_heap(__first, __middle, __comp); + for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) + if (__comp(*__i, *__first)) + std::__pop_heap(__first, __middle, __i, _ValueType(*__i), __comp); + } + + /** + * @if maint + * This is a helper function for the sort routines. + * @endif + */ + template<typename _Size> + inline _Size + __lg(_Size __n) + { + _Size __k; + for (__k = 0; __n != 1; __n >>= 1) + ++__k; + return __k; + } + + /** + * @brief Sort the smallest elements of a sequence. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the smallest @p (middle-first) elements in the range + * @p [first,last) and moves them to the range @p [first,middle). The + * order of the remaining elements in the range @p [middle,last) is + * undefined. + * After the sort if @p i and @j are iterators in the range + * @p [first,middle) such that @i precedes @j and @k is an iterator in + * the range @p [middle,last) then @p *j<*i and @p *k<*i are both false. + */ + template<typename _RandomAccessIterator> + inline void + partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + std::__heap_select(__first, __middle, __last); + std::sort_heap(__first, __middle); + } + + /** + * @brief Sort the smallest elements of a sequence using a predicate + * for comparison. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the smallest @p (middle-first) elements in the range + * @p [first,last) and moves them to the range @p [first,middle). The + * order of the remaining elements in the range @p [middle,last) is + * undefined. + * After the sort if @p i and @j are iterators in the range + * @p [first,middle) such that @i precedes @j and @k is an iterator in + * the range @p [middle,last) then @p *comp(j,*i) and @p comp(*k,*i) + * are both false. + */ + template<typename _RandomAccessIterator, typename _Compare> + inline void + partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + std::__heap_select(__first, __middle, __last, __comp); + std::sort_heap(__first, __middle, __comp); + } + + /** + * @brief Copy the smallest elements of a sequence. + * @param first An iterator. + * @param last Another iterator. + * @param result_first A random-access iterator. + * @param result_last Another random-access iterator. + * @return An iterator indicating the end of the resulting sequence. + * + * Copies and sorts the smallest N values from the range @p [first,last) + * to the range beginning at @p result_first, where the number of + * elements to be copied, @p N, is the smaller of @p (last-first) and + * @p (result_last-result_first). + * After the sort if @p i and @j are iterators in the range + * @p [result_first,result_first+N) such that @i precedes @j then + * @p *j<*i is false. + * The value returned is @p result_first+N. + */ + template<typename _InputIterator, typename _RandomAccessIterator> + _RandomAccessIterator + partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last) + { + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _OutputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, + _OutputValueType>) + __glibcxx_function_requires(_LessThanOpConcept<_InputValueType, + _OutputValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); + + if (__result_first == __result_last) + return __result_last; + _RandomAccessIterator __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) + { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + std::make_heap(__result_first, __result_real_last); + while (__first != __last) + { + if (*__first < *__result_first) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first)); + ++__first; + } + std::sort_heap(__result_first, __result_real_last); + return __result_real_last; + } + + /** + * @brief Copy the smallest elements of a sequence using a predicate for + * comparison. + * @param first An input iterator. + * @param last Another input iterator. + * @param result_first A random-access iterator. + * @param result_last Another random-access iterator. + * @param comp A comparison functor. + * @return An iterator indicating the end of the resulting sequence. + * + * Copies and sorts the smallest N values from the range @p [first,last) + * to the range beginning at @p result_first, where the number of + * elements to be copied, @p N, is the smaller of @p (last-first) and + * @p (result_last-result_first). + * After the sort if @p i and @j are iterators in the range + * @p [result_first,result_first+N) such that @i precedes @j then + * @p comp(*j,*i) is false. + * The value returned is @p result_first+N. + */ + template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare> + _RandomAccessIterator + partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last, + _Compare __comp) + { + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _OutputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, + _OutputValueType>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _InputValueType, _OutputValueType>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _OutputValueType, _OutputValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); + + if (__result_first == __result_last) + return __result_last; + _RandomAccessIterator __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) + { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + std::make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) + { + if (__comp(*__first, *__result_first)) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first), + __comp); + ++__first; + } + std::sort_heap(__result_first, __result_real_last, __comp); + return __result_real_last; + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator, typename _Size> + void + __introsort_loop(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __depth_limit) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > int(_S_threshold)) + { + if (__depth_limit == 0) + { + std::partial_sort(__first, __last, __last); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last + - 1)))); + std::__introsort_loop(__cut, __last, __depth_limit); + __last = __cut; + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator, typename _Size, typename _Compare> + void + __introsort_loop(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __depth_limit, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > int(_S_threshold)) + { + if (__depth_limit == 0) + { + std::partial_sort(__first, __last, __last, __comp); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last - 1), + __comp)), + __comp); + std::__introsort_loop(__cut, __last, __depth_limit, __comp); + __last = __cut; + } + } + + /** + * @brief Sort the elements of a sequence. + * @param first An iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p *(i+1)<*i is false for each iterator @p i in the range + * @p [first,last-1). + * + * The relative ordering of equivalent elements is not preserved, use + * @p stable_sort() if this is needed. + */ + template<typename _RandomAccessIterator> + inline void + sort(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + { + std::__introsort_loop(__first, __last, + std::__lg(__last - __first) * 2); + std::__final_insertion_sort(__first, __last); + } + } + + /** + * @brief Sort the elements of a sequence using a predicate for comparison. + * @param first An iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p comp(*(i+1),*i) is false for every iterator @p i in the + * range @p [first,last-1). + * + * The relative ordering of equivalent elements is not preserved, use + * @p stable_sort() if this is needed. + */ + template<typename _RandomAccessIterator, typename _Compare> + inline void + sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + { + std::__introsort_loop(__first, __last, + std::__lg(__last - __first) * 2, __comp); + std::__final_insertion_sort(__first, __last, __comp); + } + } + + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An iterator pointing to the first element "not less than" @a val, + * or end() if every element is less than @a val. + * @ingroup binarysearch + */ + template<typename _ForwardIterator, typename _Tp> + _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (*__middle < __val) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; + } + + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element "not less than" @a val, + * or end() if every element is less than @a val. + * @ingroup binarysearch + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template<typename _ForwardIterator, typename _Tp, typename _Compare> + _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _Tp>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(*__middle, __val)) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; + } + + /** + * @brief Finds the last position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An iterator pointing to the first element greater than @a val, + * or end() if no elements are greater than @a val. + * @ingroup binarysearch + */ + template<typename _ForwardIterator, typename _Tp> + _ForwardIterator + upper_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__val < *__middle) + __len = __half; + else + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; + } + + /** + * @brief Finds the last position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element greater than @a val, + * or end() if no elements are greater than @a val. + * @ingroup binarysearch + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template<typename _ForwardIterator, typename _Tp, typename _Compare> + _ForwardIterator + upper_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(__val, *__middle)) + __len = __half; + else + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template<typename _BidirectionalIterator, typename _Distance> + void + __merge_without_buffer(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2) + { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) + { + if (*__middle < *__first) + std::iter_swap(__first, __middle); + return; + } + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut); + __len11 = std::distance(__first, __first_cut); + } + std::rotate(__first_cut, __middle, __second_cut); + _BidirectionalIterator __new_middle = __first_cut; + std::advance(__new_middle, std::distance(__middle, __second_cut)); + std::__merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22); + std::__merge_without_buffer(__new_middle, __second_cut, __last, + __len1 - __len11, __len2 - __len22); + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template<typename _BidirectionalIterator, typename _Distance, + typename _Compare> + void + __merge_without_buffer(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Compare __comp) + { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) + { + if (__comp(*__middle, *__first)) + std::iter_swap(__first, __middle); + return; + } + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut, + __comp); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut, + __comp); + __len11 = std::distance(__first, __first_cut); + } + std::rotate(__first_cut, __middle, __second_cut); + _BidirectionalIterator __new_middle = __first_cut; + std::advance(__new_middle, std::distance(__middle, __second_cut)); + std::__merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22, __comp); + std::__merge_without_buffer(__new_middle, __second_cut, __last, + __len1 - __len11, __len2 - __len22, __comp); + } + + /** + * @if maint + * This is a helper function for the stable sorting routines. + * @endif + */ + template<typename _RandomAccessIterator> + void + __inplace_stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + if (__last - __first < 15) + { + std::__insertion_sort(__first, __last); + return; + } + _RandomAccessIterator __middle = __first + (__last - __first) / 2; + std::__inplace_stable_sort(__first, __middle); + std::__inplace_stable_sort(__middle, __last); + std::__merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle); + } + + /** + * @if maint + * This is a helper function for the stable sorting routines. + * @endif + */ + template<typename _RandomAccessIterator, typename _Compare> + void + __inplace_stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__last - __first < 15) + { + std::__insertion_sort(__first, __last, __comp); + return; + } + _RandomAccessIterator __middle = __first + (__last - __first) / 2; + std::__inplace_stable_sort(__first, __middle, __comp); + std::__inplace_stable_sort(__middle, __last, __comp); + std::__merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle, + __comp); + } + + /** + * @brief Merges two sorted ranges. + * @param first1 An iterator. + * @param first2 Another iterator. + * @param last1 Another iterator. + * @param last2 Another iterator. + * @param result An iterator pointing to the end of the merged range. + * @return An iterator pointing to the first element "not less than" @a val. + * + * Merges the ranges [first1,last1) and [first2,last2) into the sorted range + * [result, result + (last1-first1) + (last2-first2)). Both input ranges + * must be sorted, and the output range must not overlap with either of + * the input ranges. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType2>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + /** + * @brief Merges two sorted ranges. + * @param first1 An iterator. + * @param first2 Another iterator. + * @param last1 Another iterator. + * @param last2 Another iterator. + * @param result An iterator pointing to the end of the merged range. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element "not less than" @a val. + * + * Merges the ranges [first1,last1) and [first2,last2) into the sorted range + * [result, result + (last1-first1) + (last2-first2)). Both input ranges + * must be sorted, and the output range must not overlap with either of + * the input ranges. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType2, _ValueType1>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, + typename _Distance> + void + __merge_sort_loop(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + _Distance __step_size) + { + const _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) + { + __result = std::merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result); + __first += __two_step; + } + + __step_size = std::min(_Distance(__last - __first), __step_size); + std::merge(__first, __first + __step_size, __first + __step_size, __last, + __result); + } + + template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, + typename _Distance, typename _Compare> + void + __merge_sort_loop(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, _Distance __step_size, + _Compare __comp) + { + const _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) + { + __result = std::merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result, + __comp); + __first += __two_step; + } + __step_size = std::min(_Distance(__last - __first), __step_size); + + std::merge(__first, __first + __step_size, + __first + __step_size, __last, + __result, + __comp); + } + + enum { _S_chunk_size = 7 }; + + template<typename _RandomAccessIterator, typename _Distance> + void + __chunk_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance __chunk_size) + { + while (__last - __first >= __chunk_size) + { + std::__insertion_sort(__first, __first + __chunk_size); + __first += __chunk_size; + } + std::__insertion_sort(__first, __last); + } + + template<typename _RandomAccessIterator, typename _Distance, typename _Compare> + void + __chunk_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance __chunk_size, _Compare __comp) + { + while (__last - __first >= __chunk_size) + { + std::__insertion_sort(__first, __first + __chunk_size, __comp); + __first += __chunk_size; + } + std::__insertion_sort(__first, __last, __comp); + } + + template<typename _RandomAccessIterator, typename _Pointer> + void + __merge_sort_with_buffer(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + + const _Distance __len = __last - __first; + const _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = _S_chunk_size; + std::__chunk_insertion_sort(__first, __last, __step_size); + + while (__step_size < __len) + { + std::__merge_sort_loop(__first, __last, __buffer, __step_size); + __step_size *= 2; + std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size); + __step_size *= 2; + } + } + + template<typename _RandomAccessIterator, typename _Pointer, typename _Compare> + void + __merge_sort_with_buffer(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + + const _Distance __len = __last - __first; + const _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = _S_chunk_size; + std::__chunk_insertion_sort(__first, __last, __step_size, __comp); + + while (__step_size < __len) + { + std::__merge_sort_loop(__first, __last, __buffer, + __step_size, __comp); + __step_size *= 2; + std::__merge_sort_loop(__buffer, __buffer_last, __first, + __step_size, __comp); + __step_size *= 2; + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, + typename _BidirectionalIterator3> + _BidirectionalIterator3 + __merge_backward(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + _BidirectionalIterator3 __result) + { + if (__first1 == __last1) + return std::copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return std::copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) + { + if (*__last2 < *__last1) + { + *--__result = *__last1; + if (__first1 == __last1) + return std::copy_backward(__first2, ++__last2, __result); + --__last1; + } + else + { + *--__result = *__last2; + if (__first2 == __last2) + return std::copy_backward(__first1, ++__last1, __result); + --__last2; + } + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, + typename _BidirectionalIterator3, typename _Compare> + _BidirectionalIterator3 + __merge_backward(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + _BidirectionalIterator3 __result, + _Compare __comp) + { + if (__first1 == __last1) + return std::copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return std::copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) + { + if (__comp(*__last2, *__last1)) + { + *--__result = *__last1; + if (__first1 == __last1) + return std::copy_backward(__first2, ++__last2, __result); + --__last1; + } + else + { + *--__result = *__last2; + if (__first2 == __last2) + return std::copy_backward(__first1, ++__last1, __result); + --__last2; + } + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, + typename _Distance> + _BidirectionalIterator1 + __rotate_adaptive(_BidirectionalIterator1 __first, + _BidirectionalIterator1 __middle, + _BidirectionalIterator1 __last, + _Distance __len1, _Distance __len2, + _BidirectionalIterator2 __buffer, + _Distance __buffer_size) + { + _BidirectionalIterator2 __buffer_end; + if (__len1 > __len2 && __len2 <= __buffer_size) + { + __buffer_end = std::copy(__middle, __last, __buffer); + std::copy_backward(__first, __middle, __last); + return std::copy(__buffer, __buffer_end, __first); + } + else if (__len1 <= __buffer_size) + { + __buffer_end = std::copy(__first, __middle, __buffer); + std::copy(__middle, __last, __first); + return std::copy_backward(__buffer, __buffer_end, __last); + } + else + { + std::rotate(__first, __middle, __last); + std::advance(__first, std::distance(__middle, __last)); + return __first; + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template<typename _BidirectionalIterator, typename _Distance, + typename _Pointer> + void + __merge_adaptive(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size) + { + if (__len1 <= __len2 && __len1 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__first, __middle, __buffer); + std::merge(__buffer, __buffer_end, __middle, __last, __first); + } + else if (__len2 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__middle, __last, __buffer); + std::__merge_backward(__first, __middle, __buffer, + __buffer_end, __last); + } + else + { + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, + *__first_cut); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, + *__second_cut); + __len11 = std::distance(__first, __first_cut); + } + _BidirectionalIterator __new_middle = + std::__rotate_adaptive(__first_cut, __middle, __second_cut, + __len1 - __len11, __len22, __buffer, + __buffer_size); + std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size); + std::__merge_adaptive(__new_middle, __second_cut, __last, + __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size); + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template<typename _BidirectionalIterator, typename _Distance, typename _Pointer, + typename _Compare> + void + __merge_adaptive(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) + { + if (__len1 <= __len2 && __len1 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__first, __middle, __buffer); + std::merge(__buffer, __buffer_end, __middle, __last, __first, __comp); + } + else if (__len2 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__middle, __last, __buffer); + std::__merge_backward(__first, __middle, __buffer, __buffer_end, + __last, __comp); + } + else + { + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut, + __comp); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut, + __comp); + __len11 = std::distance(__first, __first_cut); + } + _BidirectionalIterator __new_middle = + std::__rotate_adaptive(__first_cut, __middle, __second_cut, + __len1 - __len11, __len22, __buffer, + __buffer_size); + std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size, __comp); + std::__merge_adaptive(__new_middle, __second_cut, __last, + __len1 - __len11, + __len2 - __len22, __buffer, + __buffer_size, __comp); + } + } + + /** + * @brief Merges two sorted ranges in place. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Merges two sorted and consecutive ranges, [first,middle) and + * [middle,last), and puts the result in [first,last). The output will + * be sorted. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * If enough additional memory is available, this takes (last-first)-1 + * comparisons. Otherwise an NlogN algorithm is used, where N is + * distance(first,last). + */ + template<typename _BidirectionalIterator> + void + inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last) + { + typedef typename iterator_traits<_BidirectionalIterator>::value_type + _ValueType; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_sorted(__first, __middle); + __glibcxx_requires_sorted(__middle, __last); + + if (__first == __middle || __middle == __last) + return; + + _DistanceType __len1 = std::distance(__first, __middle); + _DistanceType __len2 = std::distance(__middle, __last); + + _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, + __last); + if (__buf.begin() == 0) + std::__merge_without_buffer(__first, __middle, __last, __len1, __len2); + else + std::__merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _DistanceType(__buf.size())); + } + + /** + * @brief Merges two sorted ranges in place. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @param comp A functor to use for comparisons. + * @return Nothing. + * + * Merges two sorted and consecutive ranges, [first,middle) and + * [middle,last), and puts the result in [first,last). The output will + * be sorted. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * If enough additional memory is available, this takes (last-first)-1 + * comparisons. Otherwise an NlogN algorithm is used, where N is + * distance(first,last). + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template<typename _BidirectionalIterator, typename _Compare> + void + inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_BidirectionalIterator>::value_type + _ValueType; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_sorted_pred(__first, __middle, __comp); + __glibcxx_requires_sorted_pred(__middle, __last, __comp); + + if (__first == __middle || __middle == __last) + return; + + const _DistanceType __len1 = std::distance(__first, __middle); + const _DistanceType __len2 = std::distance(__middle, __last); + + _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, + __last); + if (__buf.begin() == 0) + std::__merge_without_buffer(__first, __middle, __last, __len1, + __len2, __comp); + else + std::__merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _DistanceType(__buf.size()), + __comp); + } + + template<typename _RandomAccessIterator, typename _Pointer, + typename _Distance> + void + __stable_sort_adaptive(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Distance __buffer_size) + { + const _Distance __len = (__last - __first + 1) / 2; + const _RandomAccessIterator __middle = __first + __len; + if (__len > __buffer_size) + { + std::__stable_sort_adaptive(__first, __middle, + __buffer, __buffer_size); + std::__stable_sort_adaptive(__middle, __last, + __buffer, __buffer_size); + } + else + { + std::__merge_sort_with_buffer(__first, __middle, __buffer); + std::__merge_sort_with_buffer(__middle, __last, __buffer); + } + std::__merge_adaptive(__first, __middle, __last, + _Distance(__middle - __first), + _Distance(__last - __middle), + __buffer, __buffer_size); + } + + template<typename _RandomAccessIterator, typename _Pointer, + typename _Distance, typename _Compare> + void + __stable_sort_adaptive(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) + { + const _Distance __len = (__last - __first + 1) / 2; + const _RandomAccessIterator __middle = __first + __len; + if (__len > __buffer_size) + { + std::__stable_sort_adaptive(__first, __middle, __buffer, + __buffer_size, __comp); + std::__stable_sort_adaptive(__middle, __last, __buffer, + __buffer_size, __comp); + } + else + { + std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); + std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); + } + std::__merge_adaptive(__first, __middle, __last, + _Distance(__middle - __first), + _Distance(__last - __middle), + __buffer, __buffer_size, + __comp); + } + + /** + * @brief Sort the elements of a sequence, preserving the relative order + * of equivalent elements. + * @param first An iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p *(i+1)<*i is false for each iterator @p i in the range + * @p [first,last-1). + * + * The relative ordering of equivalent elements is preserved, so any two + * elements @p x and @p y in the range @p [first,last) such that + * @p x<y is false and @p y<x is false will have the same relative + * ordering after calling @p stable_sort(). + */ + template<typename _RandomAccessIterator> + inline void + stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first, + __last); + if (__buf.begin() == 0) + std::__inplace_stable_sort(__first, __last); + else + std::__stable_sort_adaptive(__first, __last, __buf.begin(), + _DistanceType(__buf.size())); + } + + /** + * @brief Sort the elements of a sequence using a predicate for comparison, + * preserving the relative order of equivalent elements. + * @param first An iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p comp(*(i+1),*i) is false for each iterator @p i in the + * range @p [first,last-1). + * + * The relative ordering of equivalent elements is preserved, so any two + * elements @p x and @p y in the range @p [first,last) such that + * @p comp(x,y) is false and @p comp(y,x) is false will have the same + * relative ordering after calling @p stable_sort(). + */ + template<typename _RandomAccessIterator, typename _Compare> + inline void + stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first, + __last); + if (__buf.begin() == 0) + std::__inplace_stable_sort(__first, __last, __comp); + else + std::__stable_sort_adaptive(__first, __last, __buf.begin(), + _DistanceType(__buf.size()), __comp); + } + + + template<typename _RandomAccessIterator, typename _Size> + void + __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, + _RandomAccessIterator __last, _Size __depth_limit) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > 3) + { + if (__depth_limit == 0) + { + std::__heap_select(__first, __nth + 1, __last); + // Place the nth largest element in its final position. + std::iter_swap(__first, __nth); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last + - 1)))); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + std::__insertion_sort(__first, __last); + } + + template<typename _RandomAccessIterator, typename _Size, typename _Compare> + void + __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, + _RandomAccessIterator __last, _Size __depth_limit, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > 3) + { + if (__depth_limit == 0) + { + std::__heap_select(__first, __nth + 1, __last, __comp); + // Place the nth largest element in its final position. + std::iter_swap(__first, __nth); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last - 1), + __comp)), + __comp); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + std::__insertion_sort(__first, __last, __comp); + } + + /** + * @brief Sort a sequence just enough to find a particular position. + * @param first An iterator. + * @param nth Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Rearranges the elements in the range @p [first,last) so that @p *nth + * is the same element that would have been in that position had the + * whole sequence been sorted. + * whole sequence been sorted. The elements either side of @p *nth are + * not completely sorted, but for any iterator @i in the range + * @p [first,nth) and any iterator @j in the range @p [nth,last) it + * holds that @p *j<*i is false. + */ + template<typename _RandomAccessIterator> + inline void + nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); + + if (__first == __last || __nth == __last) + return; + + std::__introselect(__first, __nth, __last, + std::__lg(__last - __first) * 2); + } + + /** + * @brief Sort a sequence just enough to find a particular position + * using a predicate for comparison. + * @param first An iterator. + * @param nth Another iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Rearranges the elements in the range @p [first,last) so that @p *nth + * is the same element that would have been in that position had the + * whole sequence been sorted. The elements either side of @p *nth are + * not completely sorted, but for any iterator @i in the range + * @p [first,nth) and any iterator @j in the range @p [nth,last) it + * holds that @p comp(*j,*i) is false. + */ + template<typename _RandomAccessIterator, typename _Compare> + inline void + nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, + _RandomAccessIterator __last, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); + + if (__first == __last || __nth == __last) + return; + + std::__introselect(__first, __nth, __last, + std::__lg(__last - __first) * 2, __comp); + } + + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val), + * upper_bound(first, last, val)) + * @endcode + * but does not actually call those functions. + */ + template<typename _ForwardIterator, typename _Tp> + pair<_ForwardIterator, _ForwardIterator> + equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>) + __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle, __left, __right; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (*__middle < __val) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__val < *__middle) + __len = __half; + else + { + __left = std::lower_bound(__first, __middle, __val); + std::advance(__first, __len); + __right = std::upper_bound(++__middle, __first, __val); + return pair<_ForwardIterator, _ForwardIterator>(__left, __right); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val, comp), + * upper_bound(first, last, val, comp)) + * @endcode + * but does not actually call those functions. + */ + template<typename _ForwardIterator, typename _Tp, typename _Compare> + pair<_ForwardIterator, _ForwardIterator> + equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, + _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _Tp>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle, __left, __right; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(*__middle, __val)) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__comp(__val, *__middle)) + __len = __half; + else + { + __left = std::lower_bound(__first, __middle, __val, __comp); + std::advance(__first, __len); + __right = std::upper_bound(++__middle, __first, __val, __comp); + return pair<_ForwardIterator, _ForwardIterator>(__left, __right); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + */ + template<typename _ForwardIterator, typename _Tp> + bool + binary_search(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _ForwardIterator __i = std::lower_bound(__first, __last, __val); + return __i != __last && !(__val < *__i); + } + + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template<typename _ForwardIterator, typename _Tp, typename _Compare> + bool + binary_search(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp); + return __i != __last && !__comp(__val, *__i); + } + + // Set algorithms: includes, set_union, set_intersection, set_difference, + // set_symmetric_difference. All of these algorithms have the precondition + // that their input ranges are sorted and the postcondition that their output + // ranges are sorted. + + /** + * @brief Determines whether all elements of a sequence exists in a range. + * @param first1 Start of search range. + * @param last1 End of search range. + * @param first2 Start of sequence + * @param last2 End of sequence. + * @return True if each element in [first2,last2) is contained in order + * within [first1,last1). False otherwise. + * @ingroup setoperations + * + * This operation expects both [first1,last1) and [first2,last2) to be + * sorted. Searches for the presence of each element in [first2,last2) + * within [first1,last1). The iterators over each range only move forward, + * so this is a linear algorithm. If an element in [first2,last2) is not + * found before the search iterator reaches @a last2, false is returned. + */ + template<typename _InputIterator1, typename _InputIterator2> + bool + includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) + return false; + else if(*__first1 < *__first2) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; + } + + /** + * @brief Determines whether all elements of a sequence exists in a range + * using comparison. + * @param first1 Start of search range. + * @param last1 End of search range. + * @param first2 Start of sequence + * @param last2 End of sequence. + * @param comp Comparison function to use. + * @return True if each element in [first2,last2) is contained in order + * within [first1,last1) according to comp. False otherwise. + * @ingroup setoperations + * + * This operation expects both [first1,last1) and [first2,last2) to be + * sorted. Searches for the presence of each element in [first2,last2) + * within [first1,last1), using comp to decide. The iterators over each + * range only move forward, so this is a linear algorithm. If an element + * in [first2,last2) is not found before the search iterator reaches @a + * last2, false is returned. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _Compare> + bool + includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType1, _ValueType2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType2, _ValueType1>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) + return false; + else if(__comp(*__first1, *__first2)) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; + } + + /** + * @brief Return the union of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * each range in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other, + * that element is copied and the iterator advanced. If an element is + * contained in both ranges, the element from the first range is copied and + * both ranges advance. The output range may not overlap either input + * range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType2>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + } + else if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + /** + * @brief Return the union of two sorted ranges using a comparison functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * each range in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other + * according to @a comp, that element is copied and the iterator advanced. + * If an equivalent element according to @a comp is contained in both + * ranges, the element from the first range is copied and both ranges + * advance. The output range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType1, _ValueType2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType2, _ValueType1>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + } + else if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + /** + * @brief Return the intersection of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * both ranges in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other, + * that iterator advances. If an element is contained in both ranges, the + * element from the first range is copied and both ranges advance. The + * output range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + ++__first1; + else if (*__first2 < *__first1) + ++__first2; + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; + } + + /** + * @brief Return the intersection of two sorted ranges using comparison + * functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * both ranges in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other + * according to @a comp, that iterator advances. If an element is + * contained in both ranges according to @a comp, the element from the + * first range is copied and both ranges advance. The output range may not + * overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType1, _ValueType2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType2, _ValueType1>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + ++__first1; + else if (__comp(*__first2, *__first1)) + ++__first2; + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; + } + + /** + * @brief Return the difference of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * the first range but not the second in order to the output range. + * Iterators increment for each range. When the current element of the + * first range is less than the second, that element is copied and the + * iterator advances. If the current element of the second range is less, + * the iterator advances, but no element is copied. If an element is + * contained in both ranges, no elements are copied and both ranges + * advance. The output range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + ++__first2; + else + { + ++__first1; + ++__first2; + } + return std::copy(__first1, __last1, __result); + } + + /** + * @brief Return the difference of two sorted ranges using comparison + * functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * the first range but not the second in order to the output range. + * Iterators increment for each range. When the current element of the + * first range is less than the second according to @a comp, that element + * is copied and the iterator advances. If the current element of the + * second range is less, no element is copied and the iterator advances. + * If an element is contained in both ranges according to @a comp, no + * elements are copied and both ranges advance. The output range may not + * overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType1, _ValueType2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType2, _ValueType1>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) + ++__first2; + else + { + ++__first1; + ++__first2; + } + return std::copy(__first1, __last1, __result); + } + + /** + * @brief Return the symmetric difference of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * one range but not the other in order to the output range. Iterators + * increment for each range. When the current element of one range is less + * than the other, that element is copied and the iterator advances. If an + * element is contained in both ranges, no elements are copied and both + * ranges advance. The output range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType2>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) + __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + ++__result; + } + else + { + ++__first1; + ++__first2; + } + return std::copy(__first2, __last2, std::copy(__first1, + __last1, __result)); + } + + /** + * @brief Return the symmetric difference of two sorted ranges using + * comparison functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * one range but not the other in order to the output range. Iterators + * increment for each range. When the current element of one range is less + * than the other according to @a comp, that element is copied and the + * iterator advances. If an element is contained in both ranges according + * to @a comp, no elements are copied and both ranges advance. The output + * range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) + { + typedef typename iterator_traits<_InputIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_InputIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType1>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType1, _ValueType2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType2, _ValueType1>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + ++__result; + } + else + { + ++__first1; + ++__first2; + } + return std::copy(__first2, __last2, std::copy(__first1, + __last1, __result)); + } + + // min_element and max_element, with and without an explicitly supplied + // comparison function. + + /** + * @brief Return the maximum element in a range. + * @param first Start of range. + * @param last End of range. + * @return Iterator referencing the first instance of the largest value. + */ + template<typename _ForwardIterator> + _ForwardIterator + max_element(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (*__result < *__first) + __result = __first; + return __result; + } + + /** + * @brief Return the maximum element in a range using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor. + * @return Iterator referencing the first instance of the largest value + * according to comp. + */ + template<typename _ForwardIterator, typename _Compare> + _ForwardIterator + max_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (__comp(*__result, *__first)) __result = __first; + return __result; + } + + /** + * @brief Return the minimum element in a range. + * @param first Start of range. + * @param last End of range. + * @return Iterator referencing the first instance of the smallest value. + */ + template<typename _ForwardIterator> + _ForwardIterator + min_element(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (*__first < *__result) + __result = __first; + return __result; + } + + /** + * @brief Return the minimum element in a range using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor. + * @return Iterator referencing the first instance of the smallest value + * according to comp. + */ + template<typename _ForwardIterator, typename _Compare> + _ForwardIterator + min_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (__comp(*__first, *__result)) + __result = __first; + return __result; + } + + // next_permutation and prev_permutation, with and without an explicitly + // supplied comparison function. + + /** + * @brief Permute range into the next "dictionary" ordering. + * @param first Start of range. + * @param last End of range. + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range as a set of "dictionary" sorted + * sequences. Permutes the current sequence into the next one of this set. + * Returns true if there are more sequences to generate. If the sequence + * is the largest of the set, the smallest is generated and false returned. + */ + template<typename _BidirectionalIterator> + bool + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (*__i < *__ii) + { + _BidirectionalIterator __j = __last; + while (!(*__i < *--__j)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + /** + * @brief Permute range into the next "dictionary" ordering using + * comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range [first,last) as a set of + * "dictionary" sorted sequences ordered by @a comp. Permutes the current + * sequence into the next one of this set. Returns true if there are more + * sequences to generate. If the sequence is the largest of the set, the + * smallest is generated and false returned. + */ + template<typename _BidirectionalIterator, typename _Compare> + bool + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_BidirectionalIterator>::value_type, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (__comp(*__i, *__ii)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*__i, *--__j)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + /** + * @brief Permute range into the previous "dictionary" ordering. + * @param first Start of range. + * @param last End of range. + * @return False if wrapped to last permutation, true otherwise. + * + * Treats all permutations of the range as a set of "dictionary" sorted + * sequences. Permutes the current sequence into the previous one of this + * set. Returns true if there are more sequences to generate. If the + * sequence is the smallest of the set, the largest is generated and false + * returned. + */ + template<typename _BidirectionalIterator> + bool + prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (*__ii < *__i) + { + _BidirectionalIterator __j = __last; + while (!(*--__j < *__i)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + /** + * @brief Permute range into the previous "dictionary" ordering using + * comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp + * @return False if wrapped to last permutation, true otherwise. + * + * Treats all permutations of the range [first,last) as a set of + * "dictionary" sorted sequences ordered by @a comp. Permutes the current + * sequence into the previous one of this set. Returns true if there are + * more sequences to generate. If the sequence is the smallest of the set, + * the largest is generated and false returned. + */ + template<typename _BidirectionalIterator, typename _Compare> + bool + prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_BidirectionalIterator>::value_type, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (__comp(*__ii, *__i)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*--__j, *__i)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + // find_first_of, with and without an explicitly supplied comparison function. + + /** + * @brief Find element from a set in a sequence. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of match candidates. + * @param last2 End of match candidates. + * @return The first iterator @c i in the range + * @p [first1,last1) such that @c *i == @p *(i2) such that i2 is an + * interator in [first2,last2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for an element that is equal to + * some element in the range [first2,last2). If found, returns an iterator + * in the range [first1,last1), otherwise returns @p last1. + */ + template<typename _InputIterator, typename _ForwardIterator> + _InputIterator + find_first_of(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, _ForwardIterator __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) + if (*__first1 == *__iter) + return __first1; + return __last1; + } + + /** + * @brief Find element from a set in a sequence using a predicate. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of match candidates. + * @param last2 End of match candidates. + * @param comp Predicate to use. + * @return The first iterator @c i in the range + * @p [first1,last1) such that @c comp(*i, @p *(i2)) is true and i2 is an + * interator in [first2,last2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for an element that is equal to + * some element in the range [first2,last2). If found, returns an iterator in + * the range [first1,last1), otherwise returns @p last1. + */ + template<typename _InputIterator, typename _ForwardIterator, + typename _BinaryPredicate> + _InputIterator + find_first_of(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, _ForwardIterator __last2, + _BinaryPredicate __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) + if (__comp(*__first1, *__iter)) + return __first1; + return __last1; + } + + + // find_end, with and without an explicitly supplied comparison function. + // Search [first2, last2) as a subsequence in [first1, last1), and return + // the *last* possible match. Note that find_end for bidirectional iterators + // is much faster than for forward iterators. + + // find_end for forward iterators. + template<typename _ForwardIterator1, typename _ForwardIterator2> + _ForwardIterator1 + __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + forward_iterator_tag, forward_iterator_tag) + { + if (__first2 == __last2) + return __last1; + else + { + _ForwardIterator1 __result = __last1; + while (1) + { + _ForwardIterator1 __new_result + = std::search(__first1, __last1, __first2, __last2); + if (__new_result == __last1) + return __result; + else + { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } + } + + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + _ForwardIterator1 + __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + forward_iterator_tag, forward_iterator_tag, + _BinaryPredicate __comp) + { + if (__first2 == __last2) + return __last1; + else + { + _ForwardIterator1 __result = __last1; + while (1) + { + _ForwardIterator1 __new_result + = std::search(__first1, __last1, __first2, __last2, __comp); + if (__new_result == __last1) + return __result; + else + { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } + } + + // find_end for bidirectional iterators. Requires partial specialization. + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2> + _BidirectionalIterator1 + __find_end(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator1>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator2>) + + typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; + typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; + + _RevIterator1 __rlast1(__first1); + _RevIterator2 __rlast2(__first2); + _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, + _RevIterator2(__last2), __rlast2); + + if (__rresult == __rlast1) + return __last1; + else + { + _BidirectionalIterator1 __result = __rresult.base(); + std::advance(__result, -std::distance(__first2, __last2)); + return __result; + } + } + + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, + typename _BinaryPredicate> + _BidirectionalIterator1 + __find_end(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag, + _BinaryPredicate __comp) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator1>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator2>) + + typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; + typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; + + _RevIterator1 __rlast1(__first1); + _RevIterator2 __rlast2(__first2); + _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, + _RevIterator2(__last2), __rlast2, + __comp); + + if (__rresult == __rlast1) + return __last1; + else + { + _BidirectionalIterator1 __result = __rresult.base(); + std::advance(__result, -std::distance(__first2, __last2)); + return __result; + } + } + + // Dispatching functions for find_end. + + /** + * @brief Find last matching subsequence in a sequence. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of sequence to match. + * @param last2 End of sequence to match. + * @return The last iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) + * for each @c N in the range @p [0,last2-first2), or @p last1 if no + * such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) and + * returns an iterator to the first element of the sub-sequence, or + * @p last1 if the sub-sequence is not found. The sub-sequence will be the + * last such subsequence contained in [first,last1). + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template<typename _ForwardIterator1, typename _ForwardIterator2> + inline _ForwardIterator1 + find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return std::__find_end(__first1, __last1, __first2, __last2, + std::__iterator_category(__first1), + std::__iterator_category(__first2)); + } + + /** + * @brief Find last matching subsequence in a sequence using a predicate. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of sequence to match. + * @param last2 End of sequence to match. + * @param comp The predicate to use. + * @return The last iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c predicate(*(i+N), @p + * (first2+N)) is true for each @c N in the range @p [0,last2-first2), or + * @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) using + * comp as a predicate and returns an iterator to the first element of the + * sub-sequence, or @p last1 if the sub-sequence is not found. The + * sub-sequence will be the last such subsequence contained in + * [first,last1). + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + inline _ForwardIterator1 + find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return std::__find_end(__first1, __last1, __first2, __last2, + std::__iterator_category(__first1), + std::__iterator_category(__first2), + __comp); + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _ALGO_H */ diff --git a/libstdc++/include/bits/stl_algobase.h b/libstdc++/include/bits/stl_algobase.h new file mode 100644 index 0000000..6f19feb --- /dev/null +++ b/libstdc++/include/bits/stl_algobase.h @@ -0,0 +1,935 @@ +// Bits and pieces used in algorithms -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +// 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_algobase.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALGOBASE_H +#define _ALGOBASE_H 1 + +#include <bits/c++config.h> +#include <cstring> +#include <climits> +#include <cstdlib> +#include <cstddef> +#include <iosfwd> +#include <bits/stl_pair.h> +#include <bits/cpp_type_traits.h> +#include <ext/type_traits.h> +#include <bits/stl_iterator_base_types.h> +#include <bits/stl_iterator_base_funcs.h> +#include <bits/stl_iterator.h> +#include <bits/concept_check.h> +#include <debug/debug.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Swaps two values. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @return Nothing. + * + * This is the simple classic generic implementation. It will work on + * any type which has a copy constructor and an assignment operator. + */ + template<typename _Tp> + inline void + swap(_Tp& __a, _Tp& __b) + { + // concept requirements + __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) + + _Tp __tmp = __a; + __a = __b; + __b = __tmp; + } + + // See http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html: in a + // nutshell, we are partially implementing the resolution of DR 187, + // when it's safe, i.e., the value_types are equal. + template<bool _BoolType> + struct __iter_swap + { + template<typename _ForwardIterator1, typename _ForwardIterator2> + static void + iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) + { + typedef typename iterator_traits<_ForwardIterator1>::value_type + _ValueType1; + _ValueType1 __tmp = *__a; + *__a = *__b; + *__b = __tmp; + } + }; + + template<> + struct __iter_swap<true> + { + template<typename _ForwardIterator1, typename _ForwardIterator2> + static void + iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) + { + swap(*__a, *__b); + } + }; + + /** + * @brief Swaps the contents of two iterators. + * @param a An iterator. + * @param b Another iterator. + * @return Nothing. + * + * This function swaps the values pointed to by two iterators, not the + * iterators themselves. + */ + template<typename _ForwardIterator1, typename _ForwardIterator2> + inline void + iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) + { + typedef typename iterator_traits<_ForwardIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_ForwardIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator1>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator2>) + __glibcxx_function_requires(_ConvertibleConcept<_ValueType1, + _ValueType2>) + __glibcxx_function_requires(_ConvertibleConcept<_ValueType2, + _ValueType1>) + + typedef typename iterator_traits<_ForwardIterator1>::reference + _ReferenceType1; + typedef typename iterator_traits<_ForwardIterator2>::reference + _ReferenceType2; + std::__iter_swap<__are_same<_ValueType1, _ValueType2>::__value && + __are_same<_ValueType1 &, _ReferenceType1>::__value && + __are_same<_ValueType2 &, _ReferenceType2>::__value>:: + iter_swap(__a, __b); + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @return The lesser of the parameters. + * + * This is the simple classic generic implementation. It will work on + * temporary expressions, since they are only evaluated once, unlike a + * preprocessor macro. + */ + template<typename _Tp> + inline const _Tp& + min(const _Tp& __a, const _Tp& __b) + { + // concept requirements + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + //return __b < __a ? __b : __a; + if (__b < __a) + return __b; + return __a; + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @return The greater of the parameters. + * + * This is the simple classic generic implementation. It will work on + * temporary expressions, since they are only evaluated once, unlike a + * preprocessor macro. + */ + template<typename _Tp> + inline const _Tp& + max(const _Tp& __a, const _Tp& __b) + { + // concept requirements + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + //return __a < __b ? __b : __a; + if (__a < __b) + return __b; + return __a; + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @param comp A @link s20_3_3_comparisons comparison functor@endlink. + * @return The lesser of the parameters. + * + * This will work on temporary expressions, since they are only evaluated + * once, unlike a preprocessor macro. + */ + template<typename _Tp, typename _Compare> + inline const _Tp& + min(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + //return __comp(__b, __a) ? __b : __a; + if (__comp(__b, __a)) + return __b; + return __a; + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @param comp A @link s20_3_3_comparisons comparison functor@endlink. + * @return The greater of the parameters. + * + * This will work on temporary expressions, since they are only evaluated + * once, unlike a preprocessor macro. + */ + template<typename _Tp, typename _Compare> + inline const _Tp& + max(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + //return __comp(__a, __b) ? __b : __a; + if (__comp(__a, __b)) + return __b; + return __a; + } + + // All of these auxiliary structs serve two purposes. (1) Replace + // calls to copy with memmove whenever possible. (Memmove, not memcpy, + // because the input and output ranges are permitted to overlap.) + // (2) If we're using random access iterators, then write the loop as + // a for loop with an explicit count. + + template<bool, typename> + struct __copy + { + template<typename _II, typename _OI> + static _OI + copy(_II __first, _II __last, _OI __result) + { + for (; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; + } + }; + + template<bool _BoolType> + struct __copy<_BoolType, random_access_iterator_tag> + { + template<typename _II, typename _OI> + static _OI + copy(_II __first, _II __last, _OI __result) + { + typedef typename iterator_traits<_II>::difference_type _Distance; + for(_Distance __n = __last - __first; __n > 0; --__n) + { + *__result = *__first; + ++__first; + ++__result; + } + return __result; + } + }; + + template<> + struct __copy<true, random_access_iterator_tag> + { + template<typename _Tp> + static _Tp* + copy(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + std::memmove(__result, __first, sizeof(_Tp) * (__last - __first)); + return __result + (__last - __first); + } + }; + + template<typename _II, typename _OI> + inline _OI + __copy_aux(_II __first, _II __last, _OI __result) + { + typedef typename iterator_traits<_II>::value_type _ValueTypeI; + typedef typename iterator_traits<_OI>::value_type _ValueTypeO; + typedef typename iterator_traits<_II>::iterator_category _Category; + const bool __simple = (__is_scalar<_ValueTypeI>::__value + && __is_pointer<_II>::__value + && __is_pointer<_OI>::__value + && __are_same<_ValueTypeI, _ValueTypeO>::__value); + + return std::__copy<__simple, _Category>::copy(__first, __last, __result); + } + + // Helpers for streambuf iterators (either istream or ostream). + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT> >::__type + __copy_aux(_CharT*, _CharT*, ostreambuf_iterator<_CharT>); + + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT> >::__type + __copy_aux(const _CharT*, const _CharT*, ostreambuf_iterator<_CharT>); + + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, _CharT*>::__type + __copy_aux(istreambuf_iterator<_CharT>, istreambuf_iterator<_CharT>, + _CharT*); + + template<bool, bool> + struct __copy_normal + { + template<typename _II, typename _OI> + static _OI + __copy_n(_II __first, _II __last, _OI __result) + { return std::__copy_aux(__first, __last, __result); } + }; + + template<> + struct __copy_normal<true, false> + { + template<typename _II, typename _OI> + static _OI + __copy_n(_II __first, _II __last, _OI __result) + { return std::__copy_aux(__first.base(), __last.base(), __result); } + }; + + template<> + struct __copy_normal<false, true> + { + template<typename _II, typename _OI> + static _OI + __copy_n(_II __first, _II __last, _OI __result) + { return _OI(std::__copy_aux(__first, __last, __result.base())); } + }; + + template<> + struct __copy_normal<true, true> + { + template<typename _II, typename _OI> + static _OI + __copy_n(_II __first, _II __last, _OI __result) + { return _OI(std::__copy_aux(__first.base(), __last.base(), + __result.base())); } + }; + + /** + * @brief Copies the range [first,last) into result. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return result + (first - last) + * + * This inline function will boil down to a call to @c memmove whenever + * possible. Failing that, if random access iterators are passed, then the + * loop count will be known (and therefore a candidate for compiler + * optimizations such as unrolling). Result may not be contained within + * [first,last); the copy_backward function should be used instead. + * + * Note that the end of the output range is permitted to be contained + * within [first,last). + */ + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + const bool __in = __is_normal_iterator<_InputIterator>::__value; + const bool __out = __is_normal_iterator<_OutputIterator>::__value; + return std::__copy_normal<__in, __out>::__copy_n(__first, __last, + __result); + } + + // Overload for streambuf iterators. + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT> >::__type + copy(istreambuf_iterator<_CharT>, istreambuf_iterator<_CharT>, + ostreambuf_iterator<_CharT>); + + template<bool, typename> + struct __copy_backward + { + template<typename _BI1, typename _BI2> + static _BI2 + __copy_b(_BI1 __first, _BI1 __last, _BI2 __result) + { + while (__first != __last) + *--__result = *--__last; + return __result; + } + }; + + template<bool _BoolType> + struct __copy_backward<_BoolType, random_access_iterator_tag> + { + template<typename _BI1, typename _BI2> + static _BI2 + __copy_b(_BI1 __first, _BI1 __last, _BI2 __result) + { + typename iterator_traits<_BI1>::difference_type __n; + for (__n = __last - __first; __n > 0; --__n) + *--__result = *--__last; + return __result; + } + }; + + template<> + struct __copy_backward<true, random_access_iterator_tag> + { + template<typename _Tp> + static _Tp* + __copy_b(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + const ptrdiff_t _Num = __last - __first; + std::memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + return __result - _Num; + } + }; + + template<typename _BI1, typename _BI2> + inline _BI2 + __copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result) + { + typedef typename iterator_traits<_BI1>::value_type _ValueType1; + typedef typename iterator_traits<_BI2>::value_type _ValueType2; + typedef typename iterator_traits<_BI1>::iterator_category _Category; + const bool __simple = (__is_scalar<_ValueType1>::__value + && __is_pointer<_BI1>::__value + && __is_pointer<_BI2>::__value + && __are_same<_ValueType1, _ValueType2>::__value); + + return std::__copy_backward<__simple, _Category>::__copy_b(__first, + __last, + __result); + } + + template<bool, bool> + struct __copy_backward_normal + { + template<typename _BI1, typename _BI2> + static _BI2 + __copy_b_n(_BI1 __first, _BI1 __last, _BI2 __result) + { return std::__copy_backward_aux(__first, __last, __result); } + }; + + template<> + struct __copy_backward_normal<true, false> + { + template<typename _BI1, typename _BI2> + static _BI2 + __copy_b_n(_BI1 __first, _BI1 __last, _BI2 __result) + { return std::__copy_backward_aux(__first.base(), __last.base(), + __result); } + }; + + template<> + struct __copy_backward_normal<false, true> + { + template<typename _BI1, typename _BI2> + static _BI2 + __copy_b_n(_BI1 __first, _BI1 __last, _BI2 __result) + { return _BI2(std::__copy_backward_aux(__first, __last, + __result.base())); } + }; + + template<> + struct __copy_backward_normal<true, true> + { + template<typename _BI1, typename _BI2> + static _BI2 + __copy_b_n(_BI1 __first, _BI1 __last, _BI2 __result) + { return _BI2(std::__copy_backward_aux(__first.base(), __last.base(), + __result.base())); } + }; + + /** + * @brief Copies the range [first,last) into result. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @param result A bidirectional iterator. + * @return result - (first - last) + * + * The function has the same effect as copy, but starts at the end of the + * range and works its way to the start, returning the start of the result. + * This inline function will boil down to a call to @c memmove whenever + * possible. Failing that, if random access iterators are passed, then the + * loop count will be known (and therefore a candidate for compiler + * optimizations such as unrolling). + * + * Result may not be in the range [first,last). Use copy instead. Note + * that the start of the output range may overlap [first,last). + */ + template <typename _BI1, typename _BI2> + inline _BI2 + copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>) + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_BI1>::value_type, + typename iterator_traits<_BI2>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + const bool __bi1 = __is_normal_iterator<_BI1>::__value; + const bool __bi2 = __is_normal_iterator<_BI2>::__value; + return std::__copy_backward_normal<__bi1, __bi2>::__copy_b_n(__first, + __last, + __result); + } + + template<bool> + struct __fill + { + template<typename _ForwardIterator, typename _Tp> + static void + fill(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + for (; __first != __last; ++__first) + *__first = __value; + } + }; + + template<> + struct __fill<true> + { + template<typename _ForwardIterator, typename _Tp> + static void + fill(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + const _Tp __tmp = __value; + for (; __first != __last; ++__first) + *__first = __tmp; + } + }; + + /** + * @brief Fills the range [first,last) with copies of value. + * @param first A forward iterator. + * @param last A forward iterator. + * @param value A reference-to-const of arbitrary type. + * @return Nothing. + * + * This function fills a range with copies of the same value. For one-byte + * types filling contiguous areas of memory, this becomes an inline call to + * @c memset. + */ + template<typename _ForwardIterator, typename _Tp> + void + fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_requires_valid_range(__first, __last); + + const bool __scalar = __is_scalar<_Tp>::__value; + std::__fill<__scalar>::fill(__first, __last, __value); + } + + // Specialization: for one-byte types we can use memset. + inline void + fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c) + { + __glibcxx_requires_valid_range(__first, __last); + const unsigned char __tmp = __c; + std::memset(__first, __tmp, __last - __first); + } + + inline void + fill(signed char* __first, signed char* __last, const signed char& __c) + { + __glibcxx_requires_valid_range(__first, __last); + const signed char __tmp = __c; + std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first); + } + + inline void + fill(char* __first, char* __last, const char& __c) + { + __glibcxx_requires_valid_range(__first, __last); + const char __tmp = __c; + std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first); + } + + template<bool> + struct __fill_n + { + template<typename _OutputIterator, typename _Size, typename _Tp> + static _OutputIterator + fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) + { + for (; __n > 0; --__n, ++__first) + *__first = __value; + return __first; + } + }; + + template<> + struct __fill_n<true> + { + template<typename _OutputIterator, typename _Size, typename _Tp> + static _OutputIterator + fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) + { + const _Tp __tmp = __value; + for (; __n > 0; --__n, ++__first) + *__first = __tmp; + return __first; + } + }; + + /** + * @brief Fills the range [first,first+n) with copies of value. + * @param first An output iterator. + * @param n The count of copies to perform. + * @param value A reference-to-const of arbitrary type. + * @return The iterator at first+n. + * + * This function fills a range with copies of the same value. For one-byte + * types filling contiguous areas of memory, this becomes an inline call to + * @c memset. + */ + template<typename _OutputIterator, typename _Size, typename _Tp> + _OutputIterator + fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _Tp>) + + const bool __scalar = __is_scalar<_Tp>::__value; + return std::__fill_n<__scalar>::fill_n(__first, __n, __value); + } + + template<typename _Size> + inline unsigned char* + fill_n(unsigned char* __first, _Size __n, const unsigned char& __c) + { + std::fill(__first, __first + __n, __c); + return __first + __n; + } + + template<typename _Size> + inline signed char* + fill_n(signed char* __first, _Size __n, const signed char& __c) + { + std::fill(__first, __first + __n, __c); + return __first + __n; + } + + template<typename _Size> + inline char* + fill_n(char* __first, _Size __n, const char& __c) + { + std::fill(__first, __first + __n, __c); + return __first + __n; + } + + /** + * @brief Finds the places in ranges which don't match. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @return A pair of iterators pointing to the first mismatch. + * + * This compares the elements of two ranges using @c == and returns a pair + * of iterators. The first iterator points into the first range, the + * second iterator points into the second range, and the elements pointed + * to by the iterators are not equal. + */ + template<typename _InputIterator1, typename _InputIterator2> + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + while (__first1 != __last1 && *__first1 == *__first2) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + } + + /** + * @brief Finds the places in ranges which don't match. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param binary_pred A binary predicate @link s20_3_1_base functor@endlink. + * @return A pair of iterators pointing to the first mismatch. + * + * This compares the elements of two ranges using the binary_pred + * parameter, and returns a pair + * of iterators. The first iterator points into the first range, the + * second iterator points into the second range, and the elements pointed + * to by the iterators are not equal. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + } + + /** + * @brief Tests a range for element-wise equality. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @return A boolean true or false. + * + * This compares the elements of two ranges using @c == and returns true or + * false depending on whether all of the corresponding elements of the + * ranges are equal. + */ + template<typename _InputIterator1, typename _InputIterator2> + inline bool + equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + for (; __first1 != __last1; ++__first1, ++__first2) + if (!(*__first1 == *__first2)) + return false; + return true; + } + + /** + * @brief Tests a range for element-wise equality. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param binary_pred A binary predicate @link s20_3_1_base functor@endlink. + * @return A boolean true or false. + * + * This compares the elements of two ranges using the binary_pred + * parameter, and returns true or + * false depending on whether all of the corresponding elements of the + * ranges are equal. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + inline bool + equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + for (; __first1 != __last1; ++__first1, ++__first2) + if (!__binary_pred(*__first1, *__first2)) + return false; + return true; + } + + /** + * @brief Performs "dictionary" comparison on ranges. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param last2 An input iterator. + * @return A boolean true or false. + * + * "Returns true if the sequence of elements defined by the range + * [first1,last1) is lexicographically less than the sequence of elements + * defined by the range [first2,last2). Returns false otherwise." + * (Quoted from [25.3.8]/1.) If the iterators are all character pointers, + * then this is an inline call to @c memcmp. + */ + template<typename _InputIterator1, typename _InputIterator2> + bool + lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) + { + if (*__first1 < *__first2) + return true; + if (*__first2 < *__first1) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } + + /** + * @brief Performs "dictionary" comparison on ranges. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param last2 An input iterator. + * @param comp A @link s20_3_3_comparisons comparison functor@endlink. + * @return A boolean true or false. + * + * The same as the four-parameter @c lexigraphical_compare, but uses the + * comp parameter instead of @c <. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _Compare> + bool + lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) + { + if (__comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } + + inline bool + lexicographical_compare(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) + { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + const size_t __len1 = __last1 - __first1; + const size_t __len2 = __last2 - __first2; + const int __result = std::memcmp(__first1, __first2, + std::min(__len1, __len2)); + return __result != 0 ? __result < 0 : __len1 < __len2; + } + + inline bool + lexicographical_compare(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) + { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + +#if CHAR_MAX == SCHAR_MAX + return std::lexicographical_compare((const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else /* CHAR_MAX == SCHAR_MAX */ + return std::lexicographical_compare((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif /* CHAR_MAX == SCHAR_MAX */ + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/stl_bvector.h b/libstdc++/include/bits/stl_bvector.h new file mode 100644 index 0000000..9dc2656 --- /dev/null +++ b/libstdc++/include/bits/stl_bvector.h @@ -0,0 +1,1011 @@ +// vector<bool> specialization -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_bvector.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BVECTOR_H +#define _BVECTOR_H 1 + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + typedef unsigned long _Bit_type; + enum { _S_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) }; + + struct _Bit_reference + { + _Bit_type * _M_p; + _Bit_type _M_mask; + + _Bit_reference(_Bit_type * __x, _Bit_type __y) + : _M_p(__x), _M_mask(__y) { } + + _Bit_reference() : _M_p(0), _M_mask(0) { } + + operator bool() const + { return !!(*_M_p & _M_mask); } + + _Bit_reference& + operator=(bool __x) + { + if (__x) + *_M_p |= _M_mask; + else + *_M_p &= ~_M_mask; + return *this; + } + + _Bit_reference& + operator=(const _Bit_reference& __x) + { return *this = bool(__x); } + + bool + operator==(const _Bit_reference& __x) const + { return bool(*this) == bool(__x); } + + bool + operator<(const _Bit_reference& __x) const + { return !bool(*this) && bool(__x); } + + void + flip() + { *_M_p ^= _M_mask; } + }; + + struct _Bit_iterator_base + : public std::iterator<std::random_access_iterator_tag, bool> + { + _Bit_type * _M_p; + unsigned int _M_offset; + + _Bit_iterator_base(_Bit_type * __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) { } + + void + _M_bump_up() + { + if (_M_offset++ == int(_S_word_bit) - 1) + { + _M_offset = 0; + ++_M_p; + } + } + + void + _M_bump_down() + { + if (_M_offset-- == 0) + { + _M_offset = int(_S_word_bit) - 1; + --_M_p; + } + } + + void + _M_incr(ptrdiff_t __i) + { + difference_type __n = __i + _M_offset; + _M_p += __n / int(_S_word_bit); + __n = __n % int(_S_word_bit); + if (__n < 0) + { + __n += int(_S_word_bit); + --_M_p; + } + _M_offset = static_cast<unsigned int>(__n); + } + + bool + operator==(const _Bit_iterator_base& __i) const + { return _M_p == __i._M_p && _M_offset == __i._M_offset; } + + bool + operator<(const _Bit_iterator_base& __i) const + { + return _M_p < __i._M_p + || (_M_p == __i._M_p && _M_offset < __i._M_offset); + } + + bool + operator!=(const _Bit_iterator_base& __i) const + { return !(*this == __i); } + + bool + operator>(const _Bit_iterator_base& __i) const + { return __i < *this; } + + bool + operator<=(const _Bit_iterator_base& __i) const + { return !(__i < *this); } + + bool + operator>=(const _Bit_iterator_base& __i) const + { return !(*this < __i); } + }; + + inline ptrdiff_t + operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) + { + return (int(_S_word_bit) * (__x._M_p - __y._M_p) + + __x._M_offset - __y._M_offset); + } + + struct _Bit_iterator : public _Bit_iterator_base + { + typedef _Bit_reference reference; + typedef _Bit_reference* pointer; + typedef _Bit_iterator iterator; + + _Bit_iterator() : _Bit_iterator_base(0, 0) { } + + _Bit_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + + reference + operator*() const + { return reference(_M_p, 1UL << _M_offset); } + + iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + iterator + operator++(int) + { + iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + iterator + operator--(int) + { + iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + iterator + operator+(difference_type __i) const + { + iterator __tmp = *this; + return __tmp += __i; + } + + iterator + operator-(difference_type __i) const + { + iterator __tmp = *this; + return __tmp -= __i; + } + + reference + operator[](difference_type __i) const + { return *(*this + __i); } + }; + + inline _Bit_iterator + operator+(ptrdiff_t __n, const _Bit_iterator& __x) + { return __x + __n; } + + struct _Bit_const_iterator : public _Bit_iterator_base + { + typedef bool reference; + typedef bool const_reference; + typedef const bool* pointer; + typedef _Bit_const_iterator const_iterator; + + _Bit_const_iterator() : _Bit_iterator_base(0, 0) { } + + _Bit_const_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + + _Bit_const_iterator(const _Bit_iterator& __x) + : _Bit_iterator_base(__x._M_p, __x._M_offset) { } + + const_reference + operator*() const + { return _Bit_reference(_M_p, 1UL << _M_offset); } + + const_iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + const_iterator + operator++(int) + { + const_iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + const_iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + const_iterator + operator--(int) + { + const_iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + const_iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + const_iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + const_iterator + operator+(difference_type __i) const + { + const_iterator __tmp = *this; + return __tmp += __i; + } + + const_iterator + operator-(difference_type __i) const + { + const_iterator __tmp = *this; + return __tmp -= __i; + } + + const_reference + operator[](difference_type __i) const + { return *(*this + __i); } + }; + + inline _Bit_const_iterator + operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) + { return __x + __n; } + + inline void + __fill_bvector(_Bit_iterator __first, _Bit_iterator __last, bool __x) + { + for (; __first != __last; ++__first) + *__first = __x; + } + + inline void + fill(_Bit_iterator __first, _Bit_iterator __last, const bool& __x) + { + if (__first._M_p != __last._M_p) + { + std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0); + __fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x); + __fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x); + } + else + __fill_bvector(__first, __last, __x); + } + + template<class _Alloc> + struct _Bvector_base + { + typedef typename _Alloc::template rebind<_Bit_type>::other + _Bit_alloc_type; + + struct _Bvector_impl + : public _Bit_alloc_type + { + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + _Bit_type* _M_end_of_storage; + _Bvector_impl(const _Bit_alloc_type& __a) + : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) + { } + }; + + public: + typedef _Alloc allocator_type; + + _Bit_alloc_type& + _M_get_Bit_allocator() + { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); } + + const _Bit_alloc_type& + _M_get_Bit_allocator() const + { return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); } + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Bit_allocator()); } + + _Bvector_base(const allocator_type& __a) : _M_impl(__a) { } + + ~_Bvector_base() + { this->_M_deallocate(); } + + protected: + _Bvector_impl _M_impl; + + _Bit_type* + _M_allocate(size_t __n) + { return _M_impl.allocate((__n + int(_S_word_bit) - 1) + / int(_S_word_bit)); } + + void + _M_deallocate() + { + if (_M_impl._M_start._M_p) + _M_impl.deallocate(_M_impl._M_start._M_p, + _M_impl._M_end_of_storage - _M_impl._M_start._M_p); + } + }; + +_GLIBCXX_END_NESTED_NAMESPACE + +// Declare a partial specialization of vector<T, Alloc>. +#include <bits/stl_vector.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + /** + * @brief A specialization of vector for booleans which offers fixed time + * access to individual elements in any order. + * + * Note that vector<bool> does not actually meet the requirements for being + * a container. This is because the reference and pointer types are not + * really references and pointers to bool. See DR96 for details. @see + * vector for function documentation. + * + * @ingroup Containers + * @ingroup Sequences + * + * In some terminology a %vector can be described as a dynamic + * C-style array, it offers fast and efficient access to individual + * elements in any order and saves the user from worrying about + * memory and size allocation. Subscripting ( @c [] ) access is + * also provided as with C-style arrays. + */ +template<typename _Alloc> + class vector<bool, _Alloc> : protected _Bvector_base<_Alloc> + { + typedef _Bvector_base<_Alloc> _Base; + + public: + typedef bool value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Bit_reference reference; + typedef bool const_reference; + typedef _Bit_reference* pointer; + typedef const bool* const_pointer; + typedef _Bit_iterator iterator; + typedef _Bit_const_iterator const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef _Alloc allocator_type; + + allocator_type get_allocator() const + { return _Base::get_allocator(); } + + protected: + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_get_Bit_allocator; + + public: + explicit + vector(const allocator_type& __a = allocator_type()) + : _Base(__a) { } + + explicit + vector(size_type __n, const bool& __value = bool(), + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, + __value ? ~0 : 0); + } + + vector(const vector& __x) + : _Base(__x._M_get_Bit_allocator()) + { + _M_initialize(__x.size()); + _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start); + } + + template<class _InputIterator> + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + ~vector() { } + + vector& + operator=(const vector& __x) + { + if (&__x == this) + return *this; + if (__x.size() > capacity()) + { + this->_M_deallocate(); + _M_initialize(__x.size()); + } + this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(), + begin()); + return *this; + } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + void + assign(size_type __n, const bool& __x) + { _M_fill_assign(__n, __x); } + + template<class _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + iterator + begin() + { return this->_M_impl._M_start; } + + const_iterator + begin() const + { return this->_M_impl._M_start; } + + iterator + end() + { return this->_M_impl._M_finish; } + + const_iterator + end() const + { return this->_M_impl._M_finish; } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + size_type + size() const + { return size_type(end() - begin()); } + + size_type + max_size() const + { + const size_type __asize = _M_get_Bit_allocator().max_size(); + return (__asize <= size_type(-1) / int(_S_word_bit) ? + __asize * int(_S_word_bit) : size_type(-1)); + } + + size_type + capacity() const + { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0) + - begin()); } + + bool + empty() const + { return begin() == end(); } + + reference + operator[](size_type __n) + { + return *iterator(this->_M_impl._M_start._M_p + + __n / int(_S_word_bit), __n % int(_S_word_bit)); + } + + const_reference + operator[](size_type __n) const + { + return *const_iterator(this->_M_impl._M_start._M_p + + __n / int(_S_word_bit), __n % int(_S_word_bit)); + } + + protected: + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("vector<bool>::_M_range_check")); + } + + public: + reference + at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + + const_reference + at(size_type __n) const + { _M_range_check(__n); return (*this)[__n]; } + + void + reserve(size_type __n) + { + if (__n > this->max_size()) + __throw_length_error(__N("vector::reserve")); + if (this->capacity() < __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), + iterator(__q, 0)); + this->_M_deallocate(); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1) + / int(_S_word_bit)); + } + } + + reference + front() + { return *begin(); } + + const_reference + front() const + { return *begin(); } + + reference + back() + { return *(end() - 1); } + + const_reference + back() const + { return *(end() - 1); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 464. Suggestion for new member functions in standard containers. + // N.B. DR 464 says nothing about vector<bool> but we need something + // here due to the way we are implementing DR 464 in the debug-mode + // vector class. + void + data() { } + + void + push_back(bool __x) + { + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(end(), __x); + } + + void + swap(vector<bool, _Alloc>& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, + __x._M_impl._M_end_of_storage); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<typename _Base::_Bit_alloc_type>:: + _S_do_it(_M_get_Bit_allocator(), __x._M_get_Bit_allocator()); + } + + // [23.2.5]/1, third-to-last entry in synopsis listing + static void + swap(reference __x, reference __y) + { + bool __tmp = __x; + __x = __y; + __y = __tmp; + } + + iterator + insert(iterator __position, const bool& __x = bool()) + { + const difference_type __n = __position - begin(); + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage + && __position == end()) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + + template<class _InputIterator> + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + void + insert(iterator __position, size_type __n, const bool& __x) + { _M_fill_insert(__position, __n, __x); } + + void + pop_back() + { --this->_M_impl._M_finish; } + + iterator + erase(iterator __position) + { + if (__position + 1 != end()) + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + return __position; + } + + iterator + erase(iterator __first, iterator __last) + { + _M_erase_at_end(std::copy(__last, end(), __first)); + return __first; + } + + void + resize(size_type __new_size, bool __x = bool()) + { + if (__new_size < size()) + _M_erase_at_end(begin() + difference_type(__new_size)); + else + insert(end(), __new_size - size(), __x); + } + + void + flip() + { + for (_Bit_type * __p = this->_M_impl._M_start._M_p; + __p != this->_M_impl._M_end_of_storage; ++__p) + *__p = ~*__p; + } + + void + clear() + { _M_erase_at_end(begin()); } + + + protected: + // Precondition: __first._M_offset == 0 && __result._M_offset == 0. + iterator + _M_copy_aligned(const_iterator __first, const_iterator __last, + iterator __result) + { + _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p); + return std::copy(const_iterator(__last._M_p, 0), __last, + iterator(__q, 0)); + } + + void + _M_initialize(size_type __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = (__q + + ((__n + int(_S_word_bit) - 1) + / int(_S_word_bit))); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); + } + + // Check whether it's an integral type. If so, it's not an iterator. + template<class _Integer> + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } + + template<class _InputIterator> + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_initialize_range(__first, __last, + std::__iterator_category(__first)); } + + template<class _InputIterator> + void + _M_initialize_range(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + for (; __first != __last; ++__first) + push_back(*__first); + } + + template<class _ForwardIterator> + void + _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + _M_initialize(__n); + std::copy(__first, __last, this->_M_impl._M_start); + } + + template<class _Integer> + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_t) __n, (bool) __val); } + + template<class _InputIterator> + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } + + void + _M_fill_assign(size_t __n, bool __x) + { + if (__n > size()) + { + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + insert(end(), __n - size(), __x); + } + else + { + _M_erase_at_end(begin() + __n); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } + } + + template<class _InputIterator> + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + iterator __cur = begin(); + for (; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + _M_erase_at_end(__cur); + else + insert(end(), __first, __last); + } + + template<class _ForwardIterator> + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len < size()) + _M_erase_at_end(std::copy(__first, __last, begin())); + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } + + // Check whether it's an integral type. If so, it's not an iterator. + template<class _Integer> + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) + { _M_fill_insert(__pos, __n, __x); } + + template<class _InputIterator> + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { _M_insert_range(__pos, __first, __last, + std::__iterator_category(__first)); } + + void + _M_fill_insert(iterator __position, size_type __n, bool __x) + { + if (__n == 0) + return; + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + difference_type(__n)); + std::fill(__position, __position + difference_type(__n), __x); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = size() + std::max(size(), __n); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = _M_copy_aligned(begin(), __position, + iterator(__q, 0)); + std::fill(__i, __i + difference_type(__n), __x); + this->_M_impl._M_finish = std::copy(__position, end(), + __i + difference_type(__n)); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = (__q + ((__len + + int(_S_word_bit) - 1) + / int(_S_word_bit))); + this->_M_impl._M_start = iterator(__q, 0); + } + } + + template<class _InputIterator> + void + _M_insert_range(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag) + { + for (; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template<class _ForwardIterator> + void + _M_insert_range(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag) + { + if (__first != __last) + { + size_type __n = std::distance(__first, __last); + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + + difference_type(__n)); + std::copy(__first, __last, __position); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = size() + std::max(size(), __n); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = _M_copy_aligned(begin(), __position, + iterator(__q, 0)); + __i = std::copy(__first, __last, __i); + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = (__q + + ((__len + + int(_S_word_bit) - 1) + / int(_S_word_bit))); + this->_M_impl._M_start = iterator(__q, 0); + } + } + } + + void + _M_insert_aux(iterator __position, bool __x) + { + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + { + std::copy_backward(__position, this->_M_impl._M_finish, + this->_M_impl._M_finish + 1); + *__position = __x; + ++this->_M_impl._M_finish; + } + else + { + const size_type __len = size() ? 2 * size() + : static_cast<size_type>(_S_word_bit); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = _M_copy_aligned(begin(), __position, + iterator(__q, 0)); + *__i++ = __x; + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = (__q + ((__len + + int(_S_word_bit) - 1) + / int(_S_word_bit))); + this->_M_impl._M_start = iterator(__q, 0); + } + } + + void + _M_erase_at_end(iterator __pos) + { this->_M_impl._M_finish = __pos; } + }; + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/stl_construct.h b/libstdc++/include/bits/stl_construct.h new file mode 100644 index 0000000..0a03fb7 --- /dev/null +++ b/libstdc++/include/bits/stl_construct.h @@ -0,0 +1,188 @@ +// nonstandard construct and destroy functions -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_construct.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_CONSTRUCT_H +#define _STL_CONSTRUCT_H 1 + +#include <bits/cpp_type_traits.h> +#include <new> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @if maint + * Constructs an object in existing memory by invoking an allocated + * object's constructor with an initializer. + * @endif + */ + template<typename _T1, typename _T2> + inline void + _Construct(_T1* __p, const _T2& __value) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_]allocator::construct + ::new(static_cast<void*>(__p)) _T1(__value); + } + + /** + * @if maint + * Constructs an object in existing memory by invoking an allocated + * object's default constructor (no initializers). + * @endif + */ + template<typename _T1> + inline void + _Construct(_T1* __p) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_]allocator::construct + ::new(static_cast<void*>(__p)) _T1(); + } + + /** + * @if maint + * Destroy the object pointed to by a pointer type. + * @endif + */ + template<typename _Tp> + inline void + _Destroy(_Tp* __pointer) + { __pointer->~_Tp(); } + + /** + * @if maint + * Destroy a range of objects with nontrivial destructors. + * + * This is a helper function used only by _Destroy(). + * @endif + */ + template<typename _ForwardIterator> + inline void + __destroy_aux(_ForwardIterator __first, _ForwardIterator __last, + __false_type) + { + for (; __first != __last; ++__first) + std::_Destroy(&*__first); + } + + /** + * @if maint + * Destroy a range of objects with trivial destructors. Since the destructors + * are trivial, there's nothing to do and hopefully this function will be + * entirely optimized away. + * + * This is a helper function used only by _Destroy(). + * @endif + */ + template<typename _ForwardIterator> + inline void + __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) + { } + + /** + * @if maint + * Destroy a range of objects. If the value_type of the object has + * a trivial destructor, the compiler should optimize all of this + * away, otherwise the objects' destructors must be invoked. + * @endif + */ + template<typename _ForwardIterator> + inline void + _Destroy(_ForwardIterator __first, _ForwardIterator __last) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _Value_type; + typedef typename std::__is_scalar<_Value_type>::__type + _Has_trivial_destructor; + + std::__destroy_aux(__first, __last, _Has_trivial_destructor()); + } + + /** + * @if maint + * Destroy a range of objects using the supplied allocator. For + * nondefault allocators we do not optimize away invocation of + * destroy() even if _Tp has a trivial destructor. + * @endif + */ + + template <typename _Tp> class allocator; + + template<typename _ForwardIterator, typename _Allocator> + void + _Destroy(_ForwardIterator __first, _ForwardIterator __last, + _Allocator __alloc) + { + for (; __first != __last; ++__first) + __alloc.destroy(&*__first); + } + + template<typename _ForwardIterator, typename _Tp> + inline void + _Destroy(_ForwardIterator __first, _ForwardIterator __last, + allocator<_Tp>) + { + _Destroy(__first, __last); + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _STL_CONSTRUCT_H */ + diff --git a/libstdc++/include/bits/stl_deque.h b/libstdc++/include/bits/stl_deque.h new file mode 100644 index 0000000..9da0bb7 --- /dev/null +++ b/libstdc++/include/bits/stl_deque.h @@ -0,0 +1,1608 @@ +// Deque implementation -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_deque.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _DEQUE_H +#define _DEQUE_H 1 + +#include <bits/concept_check.h> +#include <bits/stl_iterator_base_types.h> +#include <bits/stl_iterator_base_funcs.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + /** + * @if maint + * @brief This function controls the size of memory nodes. + * @param size The size of an element. + * @return The number (not byte size) of elements per node. + * + * This function started off as a compiler kludge from SGI, but seems to + * be a useful wrapper around a repeated constant expression. The '512' is + * tuneable (and no other code needs to change), but no investigation has + * been done since inheriting the SGI code. + * @endif + */ + inline size_t + __deque_buf_size(size_t __size) + { return __size < 512 ? size_t(512 / __size) : size_t(1); } + + + /** + * @brief A deque::iterator. + * + * Quite a bit of intelligence here. Much of the functionality of + * deque is actually passed off to this class. A deque holds two + * of these internally, marking its valid range. Access to + * elements is done as offsets of either of those two, relying on + * operator overloading in this class. + * + * @if maint + * All the functions are op overloads except for _M_set_node. + * @endif + */ + template<typename _Tp, typename _Ref, typename _Ptr> + struct _Deque_iterator + { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + typedef std::random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp** _Map_pointer; + typedef _Deque_iterator _Self; + + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; + + _Deque_iterator(_Tp* __x, _Map_pointer __y) + : _M_cur(__x), _M_first(*__y), + _M_last(*__y + _S_buffer_size()), _M_node(__y) {} + + _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} + + _Deque_iterator(const iterator& __x) + : _M_cur(__x._M_cur), _M_first(__x._M_first), + _M_last(__x._M_last), _M_node(__x._M_node) {} + + reference + operator*() const + { return *_M_cur; } + + pointer + operator->() const + { return _M_cur; } + + _Self& + operator++() + { + ++_M_cur; + if (_M_cur == _M_last) + { + _M_set_node(_M_node + 1); + _M_cur = _M_first; + } + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + ++*this; + return __tmp; + } + + _Self& + operator--() + { + if (_M_cur == _M_first) + { + _M_set_node(_M_node - 1); + _M_cur = _M_last; + } + --_M_cur; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + --*this; + return __tmp; + } + + _Self& + operator+=(difference_type __n) + { + const difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; + else + { + const difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) + / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + (__offset - __node_offset + * difference_type(_S_buffer_size())); + } + return *this; + } + + _Self + operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; + } + + _Self& + operator-=(difference_type __n) + { return *this += -__n; } + + _Self + operator-(difference_type __n) const + { + _Self __tmp = *this; + return __tmp -= __n; + } + + reference + operator[](difference_type __n) const + { return *(*this + __n); } + + /** @if maint + * Prepares to traverse new_node. Sets everything except + * _M_cur, which should therefore be set by the caller + * immediately afterwards, based on _M_first and _M_last. + * @endif + */ + void + _M_set_node(_Map_pointer __new_node) + { + _M_node = __new_node; + _M_first = *__new_node; + _M_last = _M_first + difference_type(_S_buffer_size()); + } + }; + + // Note: we also provide overloads whose operands are of the same type in + // order to avoid ambiguous overload resolution when std::rel_ops operators + // are in scope (for additional details, see libstdc++/3628) + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __x._M_cur == __y._M_cur; } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __x._M_cur == __y._M_cur; } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x == __y); } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x == __y); } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __y < __x; } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __y < __x; } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__y < __x); } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__y < __x); } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x < __y); } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x < __y); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template<typename _Tp, typename _Ref, typename _Ptr> + inline typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type + operator-(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { + return typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type + (_Deque_iterator<_Tp, _Ref, _Ptr>::_S_buffer_size()) + * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + + (__y._M_last - __y._M_cur); + } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { + return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) + * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + + (__y._M_last - __y._M_cur); + } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline _Deque_iterator<_Tp, _Ref, _Ptr> + operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) + { return __x + __n; } + + template<typename _Tp> + void + fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first, + const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value); + + /** + * @if maint + * Deque base class. This class provides the unified face for %deque's + * allocation. This class's constructor and destructor allocate and + * deallocate (but do not initialize) storage. This makes %exception + * safety easier. + * + * Nothing in this class ever constructs or destroys an actual Tp element. + * (Deque handles that itself.) Only/All memory management is performed + * here. + * @endif + */ + template<typename _Tp, typename _Alloc> + class _Deque_base + { + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Tp_allocator()); } + + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + _Deque_base(const allocator_type& __a, size_t __num_elements) + : _M_impl(__a) + { _M_initialize_map(__num_elements); } + + _Deque_base(const allocator_type& __a) + : _M_impl(__a) + { } + + ~_Deque_base(); + + protected: + //This struct encapsulates the implementation of the std::deque + //standard container and at the same time makes use of the EBO + //for empty allocators. + typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type; + + typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; + + struct _Deque_impl + : public _Tp_alloc_type + { + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + _Deque_impl(const _Tp_alloc_type& __a) + : _Tp_alloc_type(__a), _M_map(0), _M_map_size(0), + _M_start(), _M_finish() + { } + }; + + _Tp_alloc_type& + _M_get_Tp_allocator() + { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } + + const _Tp_alloc_type& + _M_get_Tp_allocator() const + { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); } + + _Map_alloc_type + _M_get_map_allocator() const + { return _Map_alloc_type(_M_get_Tp_allocator()); } + + _Tp* + _M_allocate_node() + { + return _M_impl._Tp_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); + } + + void + _M_deallocate_node(_Tp* __p) + { + _M_impl._Tp_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); + } + + _Tp** + _M_allocate_map(size_t __n) + { return _M_get_map_allocator().allocate(__n); } + + void + _M_deallocate_map(_Tp** __p, size_t __n) + { _M_get_map_allocator().deallocate(__p, __n); } + + protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + + _Deque_impl _M_impl; + }; + + template<typename _Tp, typename _Alloc> + _Deque_base<_Tp, _Alloc>:: + ~_Deque_base() + { + if (this->_M_impl._M_map) + { + _M_destroy_nodes(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + } + } + + /** + * @if maint + * @brief Layout storage. + * @param num_elements The count of T's for which to allocate space + * at first. + * @return Nothing. + * + * The initial underlying memory layout is a bit complicated... + * @endif + */ + template<typename _Tp, typename _Alloc> + void + _Deque_base<_Tp, _Alloc>:: + _M_initialize_map(size_t __num_elements) + { + const size_t __num_nodes = (__num_elements/ __deque_buf_size(sizeof(_Tp)) + + 1); + + this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size, + size_t(__num_nodes + 2)); + this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size); + + // For "small" maps (needing less than _M_map_size nodes), allocation + // starts in the middle elements and grows outwards. So nstart may be + // the beginning of _M_map, but for small maps it may be as far in as + // _M_map+3. + + _Tp** __nstart = (this->_M_impl._M_map + + (this->_M_impl._M_map_size - __num_nodes) / 2); + _Tp** __nfinish = __nstart + __num_nodes; + + try + { _M_create_nodes(__nstart, __nfinish); } + catch(...) + { + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + this->_M_impl._M_map = 0; + this->_M_impl._M_map_size = 0; + __throw_exception_again; + } + + this->_M_impl._M_start._M_set_node(__nstart); + this->_M_impl._M_finish._M_set_node(__nfinish - 1); + this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first; + this->_M_impl._M_finish._M_cur = (this->_M_impl._M_finish._M_first + + __num_elements + % __deque_buf_size(sizeof(_Tp))); + } + + template<typename _Tp, typename _Alloc> + void + _Deque_base<_Tp, _Alloc>:: + _M_create_nodes(_Tp** __nstart, _Tp** __nfinish) + { + _Tp** __cur; + try + { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = this->_M_allocate_node(); + } + catch(...) + { + _M_destroy_nodes(__nstart, __cur); + __throw_exception_again; + } + } + + template<typename _Tp, typename _Alloc> + void + _Deque_base<_Tp, _Alloc>:: + _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) + { + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); + } + + /** + * @brief A standard container using fixed-size memory allocation and + * constant-time manipulation of elements at either end. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and a + * <a href="tables.html#67">sequence</a>, including the + * <a href="tables.html#68">optional sequence requirements</a>. + * + * In previous HP/SGI versions of deque, there was an extra template + * parameter so users could control the node size. This extension turned + * out to violate the C++ standard (it can be detected using template + * template parameters), and it was removed. + * + * @if maint + * Here's how a deque<Tp> manages memory. Each deque has 4 members: + * + * - Tp** _M_map + * - size_t _M_map_size + * - iterator _M_start, _M_finish + * + * map_size is at least 8. %map is an array of map_size + * pointers-to-"nodes". (The name %map has nothing to do with the + * std::map class, and "nodes" should not be confused with + * std::list's usage of "node".) + * + * A "node" has no specific type name as such, but it is referred + * to as "node" in this file. It is a simple array-of-Tp. If Tp + * is very large, there will be one Tp element per node (i.e., an + * "array" of one). For non-huge Tp's, node size is inversely + * related to Tp size: the larger the Tp, the fewer Tp's will fit + * in a node. The goal here is to keep the total size of a node + * relatively small and constant over different Tp's, to improve + * allocator efficiency. + * + * Not every pointer in the %map array will point to a node. If + * the initial number of elements in the deque is small, the + * /middle/ %map pointers will be valid, and the ones at the edges + * will be unused. This same situation will arise as the %map + * grows: available %map pointers, if any, will be on the ends. As + * new nodes are created, only a subset of the %map's pointers need + * to be copied "outward". + * + * Class invariants: + * - For any nonsingular iterator i: + * - i.node points to a member of the %map array. (Yes, you read that + * correctly: i.node does not actually point to a node.) The member of + * the %map array is what actually points to the node. + * - i.first == *(i.node) (This points to the node (first Tp element).) + * - i.last == i.first + node_size + * - i.cur is a pointer in the range [i.first, i.last). NOTE: + * the implication of this is that i.cur is always a dereferenceable + * pointer, even if i is a past-the-end iterator. + * - Start and Finish are always nonsingular iterators. NOTE: this + * means that an empty deque must have one node, a deque with <N + * elements (where N is the node buffer size) must have one node, a + * deque with N through (2N-1) elements must have two nodes, etc. + * - For every node other than start.node and finish.node, every + * element in the node is an initialized object. If start.node == + * finish.node, then [start.cur, finish.cur) are initialized + * objects, and the elements outside that range are uninitialized + * storage. Otherwise, [start.cur, start.last) and [finish.first, + * finish.cur) are initialized objects, and [start.first, start.cur) + * and [finish.cur, finish.last) are uninitialized storage. + * - [%map, %map + map_size) is a valid, non-empty range. + * - [start.node, finish.node] is a valid range contained within + * [%map, %map + map_size). + * - A pointer in the range [%map, %map + map_size) points to an allocated + * node if and only if the pointer is in the range + * [start.node, finish.node]. + * + * Here's the magic: nothing in deque is "aware" of the discontiguous + * storage! + * + * The memory setup and layout occurs in the parent, _Base, and the iterator + * class is entirely responsible for "leaping" from one node to the next. + * All the implementation routines for deque itself work only through the + * start and finish iterators. This keeps the routines simple and sane, + * and we can use other standard algorithms as well. + * @endif + */ + template<typename _Tp, typename _Alloc = std::allocator<_Tp> > + class deque : protected _Deque_base<_Tp, _Alloc> + { + // concept requirements + typedef typename _Alloc::value_type _Alloc_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) + + typedef _Deque_base<_Tp, _Alloc> _Base; + typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; + + public: + typedef _Tp value_type; + typedef typename _Tp_alloc_type::pointer pointer; + typedef typename _Tp_alloc_type::const_pointer const_pointer; + typedef typename _Tp_alloc_type::reference reference; + typedef typename _Tp_alloc_type::const_reference const_reference; + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + protected: + typedef pointer* _Map_pointer; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + // Functions controlling memory layout, and nothing else. + using _Base::_M_initialize_map; + using _Base::_M_create_nodes; + using _Base::_M_destroy_nodes; + using _Base::_M_allocate_node; + using _Base::_M_deallocate_node; + using _Base::_M_allocate_map; + using _Base::_M_deallocate_map; + using _Base::_M_get_Tp_allocator; + + /** @if maint + * A total of four data members accumulated down the heirarchy. + * May be accessed via _M_impl.* + * @endif + */ + using _Base::_M_impl; + + public: + // [23.2.1.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + deque(const allocator_type& __a = allocator_type()) + : _Base(__a, 0) {} + + /** + * @brief Create a %deque with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %deque with @a n copies of @a value. + */ + explicit + deque(size_type __n, const value_type& __value = value_type(), + const allocator_type& __a = allocator_type()) + : _Base(__a, __n) + { _M_fill_initialize(__value); } + + /** + * @brief %Deque copy constructor. + * @param x A %deque of identical element and allocator types. + * + * The newly-created %deque uses a copy of the allocation object used + * by @a x. + */ + deque(const deque& __x) + : _Base(__x._M_get_Tp_allocator(), __x.size()) + { std::__uninitialized_copy_a(__x.begin(), __x.end(), + this->_M_impl._M_start, + _M_get_Tp_allocator()); } + + /** + * @brief Builds a %deque from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %deque consisting of copies of the elements from [first, + * last). + * + * If the iterators are forward, bidirectional, or random-access, then + * this will call the elements' copy constructor N times (where N is + * distance(first,last)) and do no memory reallocation. But if only + * input iterators are used, then this will do at most 2N calls to the + * copy constructor, and logN memory reallocations. + */ + template<typename _InputIterator> + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + ~deque() + { _M_destroy_data(begin(), end(), _M_get_Tp_allocator()); } + + /** + * @brief %Deque assignment operator. + * @param x A %deque of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + deque& + operator=(const deque& __x); + + /** + * @brief Assigns a given value to a %deque. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %deque with @a n copies of the given + * value. Note that the assignment completely changes the + * %deque and that the resulting %deque's size is the same as + * the number of elements assigned. Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %deque with copies of the elements in the + * range [first,last). + * + * Note that the assignment completely changes the %deque and that the + * resulting %deque's size is the same as the number of elements + * assigned. Old data may be lost. + */ + template<typename _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %deque. Iteration is done in ordinary element order. + */ + iterator + begin() + { return this->_M_impl._M_start; } + + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %deque. Iteration is done in ordinary element order. + */ + const_iterator + begin() const + { return this->_M_impl._M_start; } + + /** + * Returns a read/write iterator that points one past the last + * element in the %deque. Iteration is done in ordinary + * element order. + */ + iterator + end() + { return this->_M_impl._M_finish; } + + /** + * Returns a read-only (constant) iterator that points one past + * the last element in the %deque. Iteration is done in + * ordinary element order. + */ + const_iterator + end() const + { return this->_M_impl._M_finish; } + + /** + * Returns a read/write reverse iterator that points to the + * last element in the %deque. Iteration is done in reverse + * element order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->_M_impl._M_finish); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last element in the %deque. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->_M_impl._M_finish); } + + /** + * Returns a read/write reverse iterator that points to one + * before the first element in the %deque. Iteration is done + * in reverse element order. + */ + reverse_iterator + rend() + { return reverse_iterator(this->_M_impl._M_start); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first element in the %deque. Iteration is + * done in reverse element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->_M_impl._M_start); } + + // [23.2.1.2] capacity + /** Returns the number of elements in the %deque. */ + size_type + size() const + { return this->_M_impl._M_finish - this->_M_impl._M_start; } + + /** Returns the size() of the largest possible %deque. */ + size_type + max_size() const + { return _M_get_Tp_allocator().max_size(); } + + /** + * @brief Resizes the %deque to the specified number of elements. + * @param new_size Number of elements the %deque should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %deque to the specified + * number of elements. If the number is smaller than the + * %deque's current size the %deque is truncated, otherwise the + * %deque is extended and new elements are populated with given + * data. + */ + void + resize(size_type __new_size, value_type __x = value_type()) + { + const size_type __len = size(); + if (__new_size < __len) + _M_erase_at_end(this->_M_impl._M_start + difference_type(__new_size)); + else + insert(this->_M_impl._M_finish, __new_size - __len, __x); + } + + /** + * Returns true if the %deque is empty. (Thus begin() would + * equal end().) + */ + bool + empty() const + { return this->_M_impl._M_finish == this->_M_impl._M_start; } + + // element access + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be + * accessed. + * @return Read/write reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + reference + operator[](size_type __n) + { return this->_M_impl._M_start[difference_type(__n)]; } + + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be + * accessed. + * @return Read-only (constant) reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[](size_type __n) const + { return this->_M_impl._M_start[difference_type(__n)]; } + + protected: + /// @if maint Safety check used only from at(). @endif + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("deque::_M_range_check")); + } + + public: + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be + * accessed. + * @return Read/write reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the deque. The + * function throws out_of_range if the check fails. + */ + reference + at(size_type __n) + { + _M_range_check(__n); + return (*this)[__n]; + } + + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be + * accessed. + * @return Read-only (constant) reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the deque. The function throws + * out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + _M_range_check(__n); + return (*this)[__n]; + } + + /** + * Returns a read/write reference to the data at the first + * element of the %deque. + */ + reference + front() + { return *begin(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %deque. + */ + const_reference + front() const + { return *begin(); } + + /** + * Returns a read/write reference to the data at the last element of the + * %deque. + */ + reference + back() + { + iterator __tmp = end(); + --__tmp; + return *__tmp; + } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %deque. + */ + const_reference + back() const + { + const_iterator __tmp = end(); + --__tmp; + return *__tmp; + } + + // [23.2.1.2] modifiers + /** + * @brief Add data to the front of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the front of the %deque and assigns the given + * data to it. Due to the nature of a %deque this operation + * can be done in constant time. + */ + void + push_front(const value_type& __x) + { + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) + { + this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1, __x); + --this->_M_impl._M_start._M_cur; + } + else + _M_push_front_aux(__x); + } + + /** + * @brief Add data to the end of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the end of the %deque and assigns the given data + * to it. Due to the nature of a %deque this operation can be + * done in constant time. + */ + void + push_back(const value_type& __x) + { + if (this->_M_impl._M_finish._M_cur + != this->_M_impl._M_finish._M_last - 1) + { + this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __x); + ++this->_M_impl._M_finish._M_cur; + } + else + _M_push_back_aux(__x); + } + + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the first element's data is + * needed, it should be retrieved before pop_front() is called. + */ + void + pop_front() + { + if (this->_M_impl._M_start._M_cur + != this->_M_impl._M_start._M_last - 1) + { + this->_M_impl.destroy(this->_M_impl._M_start._M_cur); + ++this->_M_impl._M_start._M_cur; + } + else + _M_pop_front_aux(); + } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the last element's data is + * needed, it should be retrieved before pop_back() is called. + */ + void + pop_back() + { + if (this->_M_impl._M_finish._M_cur + != this->_M_impl._M_finish._M_first) + { + --this->_M_impl._M_finish._M_cur; + this->_M_impl.destroy(this->_M_impl._M_finish._M_cur); + } + else + _M_pop_back_aux(); + } + + /** + * @brief Inserts given value into %deque before specified iterator. + * @param position An iterator into the %deque. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before the + * specified location. + */ + iterator + insert(iterator __position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %deque. + * @param position An iterator into the %deque. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the given + * data before the location specified by @a position. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %deque. + * @param position An iterator into the %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range + * [first,last) into the %deque before the location specified + * by @a pos. This is known as "range insert." + */ + template<typename _InputIterator> + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %deque by one. + * + * The user is cautioned that + * this function only erases the element, and that if the element is + * itself a pointer, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range [first,last) and + * shorten the %deque accordingly. + * + * The user is cautioned that + * this function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __first, iterator __last); + + /** + * @brief Swaps data with another %deque. + * @param x A %deque of the same element and allocator types. + * + * This exchanges the elements between two deques in constant time. + * (Four pointers, so it should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(d1,d2) will feed to this function. + */ + void + swap(deque& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_map, __x._M_impl._M_map); + std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(), + __x._M_get_Tp_allocator()); + } + + /** + * Erases all the elements. Note that this function only erases the + * elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_erase_at_end(begin()); } + + protected: + // Internal constructor functions follow. + + // called by the range constructor to implement [23.1.1]/9 + template<typename _Integer> + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize_map(__n); + _M_fill_initialize(__x); + } + + // called by the range constructor to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } + + // called by the second initialize_dispatch above + //@{ + /** + * @if maint + * @brief Fills the deque with whatever is in [first,last). + * @param first An input iterator. + * @param last An input iterator. + * @return Nothing. + * + * If the iterators are actually forward iterators (or better), then the + * memory layout can be done all at once. Else we move forward using + * push_back on each value from the iterator. + * @endif + */ + template<typename _InputIterator> + void + _M_range_initialize(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag); + + // called by the second initialize_dispatch above + template<typename _ForwardIterator> + void + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag); + //@} + + /** + * @if maint + * @brief Fills the %deque with copies of value. + * @param value Initial value. + * @return Nothing. + * @pre _M_start and _M_finish have already been initialized, + * but none of the %deque's elements have yet been constructed. + * + * This function is called only when the user provides an explicit size + * (with or without an explicit exemplar value). + * @endif + */ + void + _M_fill_initialize(const value_type& __value); + + // Internal assign functions follow. The *_aux functions do the actual + // assignment work for the range versions. + + // called by the range assign to implement [23.1.1]/9 + template<typename _Integer> + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast<size_type>(__n), + static_cast<value_type>(__val)); + } + + // called by the range assign to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + // called by the second assign_dispatch above + template<typename _InputIterator> + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag); + + // called by the second assign_dispatch above + template<typename _ForwardIterator> + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len > size()) + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + else + _M_erase_at_end(std::copy(__first, __last, begin())); + } + + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. + void + _M_fill_assign(size_type __n, const value_type& __val) + { + if (__n > size()) + { + std::fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else + { + _M_erase_at_end(begin() + difference_type(__n)); + std::fill(begin(), end(), __val); + } + } + + //@{ + /** + * @if maint + * @brief Helper functions for push_* and pop_*. + * @endif + */ + void _M_push_back_aux(const value_type&); + + void _M_push_front_aux(const value_type&); + + void _M_pop_back_aux(); + + void _M_pop_front_aux(); + //@} + + // Internal insert functions follow. The *_aux functions do the actual + // insertion work when all shortcuts fail. + + // called by the range insert to implement [23.1.1]/9 + template<typename _Integer> + void + _M_insert_dispatch(iterator __pos, + _Integer __n, _Integer __x, __true_type) + { + _M_fill_insert(__pos, static_cast<size_type>(__n), + static_cast<value_type>(__x)); + } + + // called by the range insert to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_range_insert_aux(__pos, __first, __last, _IterCategory()); + } + + // called by the second insert_dispatch above + template<typename _InputIterator> + void + _M_range_insert_aux(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag); + + // called by the second insert_dispatch above + template<typename _ForwardIterator> + void + _M_range_insert_aux(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag); + + // Called by insert(p,n,x), and the range insert when it turns out to be + // the same thing. Can use fill functions in optimal situations, + // otherwise passes off to insert_aux(p,n,x). + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + + // called by insert(p,x) + iterator + _M_insert_aux(iterator __pos, const value_type& __x); + + // called by insert(p,n,x) via fill_insert + void + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); + + // called by range_insert_aux for forward iterators + template<typename _ForwardIterator> + void + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); + + + // Internal erase functions follow. + + void + _M_destroy_data_aux(iterator __first, iterator __last); + + void + _M_destroy_data_dispatch(iterator, iterator, __true_type) { } + + void + _M_destroy_data_dispatch(iterator __first, iterator __last, __false_type) + { _M_destroy_data_aux(__first, __last); } + + // Called by ~deque(). + // NB: Doesn't deallocate the nodes. + template<typename _Alloc1> + void + _M_destroy_data(iterator __first, iterator __last, const _Alloc1&) + { _M_destroy_data_aux(__first, __last); } + + void + _M_destroy_data(iterator __first, iterator __last, + const std::allocator<_Tp>&) + { + typedef typename std::__is_scalar<value_type>::__type + _Has_trivial_destructor; + _M_destroy_data_dispatch(__first, __last, _Has_trivial_destructor()); + } + + // Called by erase(q1, q2). + void + _M_erase_at_begin(iterator __pos) + { + _M_destroy_data(begin(), __pos, _M_get_Tp_allocator()); + _M_destroy_nodes(this->_M_impl._M_start._M_node, __pos._M_node); + this->_M_impl._M_start = __pos; + } + + // Called by erase(q1, q2), resize(), clear(), _M_assign_aux, + // _M_fill_assign, operator=. + void + _M_erase_at_end(iterator __pos) + { + _M_destroy_data(__pos, end(), _M_get_Tp_allocator()); + _M_destroy_nodes(__pos._M_node + 1, + this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish = __pos; + } + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the previous internal insert + * functions. + * @endif + */ + iterator + _M_reserve_elements_at_front(size_type __n) + { + const size_type __vacancies = this->_M_impl._M_start._M_cur + - this->_M_impl._M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return this->_M_impl._M_start - difference_type(__n); + } + + iterator + _M_reserve_elements_at_back(size_type __n) + { + const size_type __vacancies = (this->_M_impl._M_finish._M_last + - this->_M_impl._M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return this->_M_impl._M_finish + difference_type(__n); + } + + void + _M_new_elements_at_front(size_type __new_elements); + + void + _M_new_elements_at_back(size_type __new_elements); + //@} + + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the major %map. + * + * Makes sure the _M_map has space for new nodes. Does not + * actually add the nodes. Can invalidate _M_map pointers. + * (And consequently, %deque iterators.) + * @endif + */ + void + _M_reserve_map_at_back(size_type __nodes_to_add = 1) + { + if (__nodes_to_add + 1 > this->_M_impl._M_map_size + - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, false); + } + + void + _M_reserve_map_at_front(size_type __nodes_to_add = 1) + { + if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node + - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, true); + } + + void + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); + //@} + }; + + + /** + * @brief Deque equality comparison. + * @param x A %deque. + * @param y A %deque of the same type as @a x. + * @return True iff the size and elements of the deques are equal. + * + * This is an equivalence relation. It is linear in the size of the + * deques. Deques are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template<typename _Tp, typename _Alloc> + inline bool + operator==(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); } + + /** + * @brief Deque ordering relation. + * @param x A %deque. + * @param y A %deque of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * deques. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template<typename _Tp, typename _Alloc> + inline bool + operator<(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + /// Based on operator== + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template<typename _Tp, typename _Alloc> + inline bool + operator>(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x < __y); } + + /// See std::deque::swap(). + template<typename _Tp, typename _Alloc> + inline void + swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif /* _DEQUE_H */ diff --git a/libstdc++/include/bits/stl_function.h b/libstdc++/include/bits/stl_function.h new file mode 100644 index 0000000..db213dc --- /dev/null +++ b/libstdc++/include/bits/stl_function.h @@ -0,0 +1,755 @@ +// Functor implementations -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_function.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _FUNCTION_H +#define _FUNCTION_H 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // 20.3.1 base classes + /** @defgroup s20_3_1_base Functor Base Classes + * Function objects, or @e functors, are objects with an @c operator() + * defined and accessible. They can be passed as arguments to algorithm + * templates and used in place of a function pointer. Not only is the + * resulting expressiveness of the library increased, but the generated + * code can be more efficient than what you might write by hand. When we + * refer to "functors," then, generally we include function pointers in + * the description as well. + * + * Often, functors are only created as temporaries passed to algorithm + * calls, rather than being created as named variables. + * + * Two examples taken from the standard itself follow. To perform a + * by-element addition of two vectors @c a and @c b containing @c double, + * and put the result in @c a, use + * \code + * transform (a.begin(), a.end(), b.begin(), a.begin(), plus<double>()); + * \endcode + * To negate every element in @c a, use + * \code + * transform(a.begin(), a.end(), a.begin(), negate<double>()); + * \endcode + * The addition and negation functions will be inlined directly. + * + * The standard functors are derived from structs named @c unary_function + * and @c binary_function. These two classes contain nothing but typedefs, + * to aid in generic (template) programming. If you write your own + * functors, you might consider doing the same. + * + * @{ + */ + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template <class _Arg, class _Result> + struct unary_function + { + typedef _Arg argument_type; ///< @c argument_type is the type of the + /// argument (no surprises here) + + typedef _Result result_type; ///< @c result_type is the return type + }; + + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template <class _Arg1, class _Arg2, class _Result> + struct binary_function + { + typedef _Arg1 first_argument_type; ///< the type of the first argument + /// (no surprises here) + + typedef _Arg2 second_argument_type; ///< the type of the second argument + typedef _Result result_type; ///< type of the return type + }; + /** @} */ + + // 20.3.2 arithmetic + /** @defgroup s20_3_2_arithmetic Arithmetic Classes + * Because basic math often needs to be done during an algorithm, the library + * provides functors for those operations. See the documentation for + * @link s20_3_1_base the base classes@endlink for examples of their use. + * + * @{ + */ + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct plus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct minus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct multiplies : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct divides : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct modulus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct negate : public unary_function<_Tp, _Tp> + { + _Tp + operator()(const _Tp& __x) const + { return -__x; } + }; + /** @} */ + + // 20.3.3 comparisons + /** @defgroup s20_3_3_comparisons Comparison Classes + * The library provides six wrapper functors for all the basic comparisons + * in C++, like @c <. + * + * @{ + */ + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct not_equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct greater : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct less : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct greater_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct less_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + /** @} */ + + // 20.3.4 logical operations + /** @defgroup s20_3_4_logical Boolean Operations Classes + * Here are wrapper functors for Boolean operations: @c &&, @c ||, and @c !. + * + * @{ + */ + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template <class _Tp> + struct logical_and : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template <class _Tp> + struct logical_or : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template <class _Tp> + struct logical_not : public unary_function<_Tp, bool> + { + bool + operator()(const _Tp& __x) const + { return !__x; } + }; + /** @} */ + + // 20.3.5 negators + /** @defgroup s20_3_5_negators Negators + * The functions @c not1 and @c not2 each take a predicate functor + * and return an instance of @c unary_negate or + * @c binary_negate, respectively. These classes are functors whose + * @c operator() performs the stored predicate function and then returns + * the negation of the result. + * + * For example, given a vector of integers and a trivial predicate, + * \code + * struct IntGreaterThanThree + * : public std::unary_function<int, bool> + * { + * bool operator() (int x) { return x > 3; } + * }; + * + * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); + * \endcode + * The call to @c find_if will locate the first index (i) of @c v for which + * "!(v[i] > 3)" is true. + * + * The not1/unary_negate combination works on predicates taking a single + * argument. The not2/binary_negate combination works on predicates which + * take two arguments. + * + * @{ + */ + /// One of the @link s20_3_5_negators negation functors@endlink. + template <class _Predicate> + class unary_negate + : public unary_function<typename _Predicate::argument_type, bool> + { + protected: + _Predicate _M_pred; + public: + explicit + unary_negate(const _Predicate& __x) : _M_pred(__x) {} + + bool + operator()(const typename _Predicate::argument_type& __x) const + { return !_M_pred(__x); } + }; + + /// One of the @link s20_3_5_negators negation functors@endlink. + template <class _Predicate> + inline unary_negate<_Predicate> + not1(const _Predicate& __pred) + { return unary_negate<_Predicate>(__pred); } + + /// One of the @link s20_3_5_negators negation functors@endlink. + template <class _Predicate> + class binary_negate + : public binary_function<typename _Predicate::first_argument_type, + typename _Predicate::second_argument_type, + bool> + { + protected: + _Predicate _M_pred; + public: + explicit + binary_negate(const _Predicate& __x) + : _M_pred(__x) { } + + bool + operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { return !_M_pred(__x, __y); } + }; + + /// One of the @link s20_3_5_negators negation functors@endlink. + template <class _Predicate> + inline binary_negate<_Predicate> + not2(const _Predicate& __pred) + { return binary_negate<_Predicate>(__pred); } + /** @} */ + + // 20.3.6 binders + /** @defgroup s20_3_6_binder Binder Classes + * Binders turn functions/functors with two arguments into functors with + * a single argument, storing an argument to be applied later. For + * example, a variable @c B of type @c binder1st is constructed from a + * functor @c f and an argument @c x. Later, B's @c operator() is called + * with a single argument @c y. The return value is the value of @c f(x,y). + * @c B can be "called" with various arguments (y1, y2, ...) and will in + * turn call @c f(x,y1), @c f(x,y2), ... + * + * The function @c bind1st is provided to save some typing. It takes the + * function and an argument as parameters, and returns an instance of + * @c binder1st. + * + * The type @c binder2nd and its creator function @c bind2nd do the same + * thing, but the stored argument is passed as the second parameter instead + * of the first, e.g., @c bind2nd(std::minus<float>,1.3) will create a + * functor whose @c operator() accepts a floating-point number, subtracts + * 1.3 from it, and returns the result. (If @c bind1st had been used, + * the functor would perform "1.3 - x" instead. + * + * Creator-wrapper functions like @c bind1st are intended to be used in + * calling algorithms. Their return values will be temporary objects. + * (The goal is to not require you to type names like + * @c std::binder1st<std::plus<int>> for declaring a variable to hold the + * return value from @c bind1st(std::plus<int>,5). + * + * These become more useful when combined with the composition functions. + * + * @{ + */ + /// One of the @link s20_3_6_binder binder functors@endlink. + template <class _Operation> + class binder1st + : public unary_function<typename _Operation::second_argument_type, + typename _Operation::result_type> + { + protected: + _Operation op; + typename _Operation::first_argument_type value; + public: + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} + + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + }; + + /// One of the @link s20_3_6_binder binder functors@endlink. + template <class _Operation, class _Tp> + inline binder1st<_Operation> + bind1st(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__fn, _Arg1_type(__x)); + } + + /// One of the @link s20_3_6_binder binder functors@endlink. + template <class _Operation> + class binder2nd + : public unary_function<typename _Operation::first_argument_type, + typename _Operation::result_type> + { + protected: + _Operation op; + typename _Operation::second_argument_type value; + public: + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} + + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + }; + + /// One of the @link s20_3_6_binder binder functors@endlink. + template <class _Operation, class _Tp> + inline binder2nd<_Operation> + bind2nd(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__fn, _Arg2_type(__x)); + } + /** @} */ + + // 20.3.7 adaptors pointers functions + /** @defgroup s20_3_7_adaptors Adaptors for pointers to functions + * The advantage of function objects over pointers to functions is that + * the objects in the standard library declare nested typedefs describing + * their argument and result types with uniform names (e.g., @c result_type + * from the base classes @c unary_function and @c binary_function). + * Sometimes those typedefs are required, not just optional. + * + * Adaptors are provided to turn pointers to unary (single-argument) and + * binary (double-argument) functions into function objects. The + * long-winded functor @c pointer_to_unary_function is constructed with a + * function pointer @c f, and its @c operator() called with argument @c x + * returns @c f(x). The functor @c pointer_to_binary_function does the same + * thing, but with a double-argument @c f and @c operator(). + * + * The function @c ptr_fun takes a pointer-to-function @c f and constructs + * an instance of the appropriate functor. + * + * @{ + */ + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template <class _Arg, class _Result> + class pointer_to_unary_function : public unary_function<_Arg, _Result> + { + protected: + _Result (*_M_ptr)(_Arg); + public: + pointer_to_unary_function() {} + + explicit + pointer_to_unary_function(_Result (*__x)(_Arg)) + : _M_ptr(__x) {} + + _Result + operator()(_Arg __x) const + { return _M_ptr(__x); } + }; + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template <class _Arg, class _Result> + inline pointer_to_unary_function<_Arg, _Result> + ptr_fun(_Result (*__x)(_Arg)) + { return pointer_to_unary_function<_Arg, _Result>(__x); } + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template <class _Arg1, class _Arg2, class _Result> + class pointer_to_binary_function + : public binary_function<_Arg1, _Arg2, _Result> + { + protected: + _Result (*_M_ptr)(_Arg1, _Arg2); + public: + pointer_to_binary_function() {} + + explicit + pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) {} + + _Result + operator()(_Arg1 __x, _Arg2 __y) const + { return _M_ptr(__x, __y); } + }; + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template <class _Arg1, class _Arg2, class _Result> + inline pointer_to_binary_function<_Arg1, _Arg2, _Result> + ptr_fun(_Result (*__x)(_Arg1, _Arg2)) + { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); } + /** @} */ + + template <class _Tp> + struct _Identity : public unary_function<_Tp,_Tp> + { + _Tp& + operator()(_Tp& __x) const + { return __x; } + + const _Tp& + operator()(const _Tp& __x) const + { return __x; } + }; + + template <class _Pair> + struct _Select1st : public unary_function<_Pair, + typename _Pair::first_type> + { + typename _Pair::first_type& + operator()(_Pair& __x) const + { return __x.first; } + + const typename _Pair::first_type& + operator()(const _Pair& __x) const + { return __x.first; } + }; + + template <class _Pair> + struct _Select2nd : public unary_function<_Pair, + typename _Pair::second_type> + { + typename _Pair::second_type& + operator()(_Pair& __x) const + { return __x.second; } + + const typename _Pair::second_type& + operator()(const _Pair& __x) const + { return __x.second; } + }; + + // 20.3.8 adaptors pointers members + /** @defgroup s20_3_8_memadaptors Adaptors for pointers to members + * There are a total of 8 = 2^3 function objects in this family. + * (1) Member functions taking no arguments vs member functions taking + * one argument. + * (2) Call through pointer vs call through reference. + * (3) Const vs non-const member function. + * + * All of this complexity is in the function objects themselves. You can + * ignore it by using the helper function mem_fun and mem_fun_ref, + * which create whichever type of adaptor is appropriate. + * + * @{ + */ + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp> + class mem_fun_t : public unary_function<_Tp*, _Ret> + { + public: + explicit + mem_fun_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} + + _Ret + operator()(_Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp> + class const_mem_fun_t : public unary_function<const _Tp*, _Ret> + { + public: + explicit + const_mem_fun_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp> + class mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + mem_fun_ref_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} + + _Ret + operator()(_Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp> + class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp, class _Arg> + class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> + { + public: + explicit + mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + _Ret + operator()(_Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp, class _Arg> + class const_mem_fun1_t : public binary_function<const _Tp*, _Arg, _Ret> + { + public: + explicit + const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp, class _Arg> + class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + _Ret + operator()(_Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp, class _Arg> + class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + // Mem_fun adaptor helper functions. There are only two: + // mem_fun and mem_fun_ref. + template <class _Ret, class _Tp> + inline mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret, _Tp>(__f); } + + template <class _Ret, class _Tp> + inline const_mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret, _Tp>(__f); } + + template <class _Ret, class _Tp> + inline mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret, _Tp>(__f); } + + template <class _Ret, class _Tp> + inline const_mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret, _Tp>(__f); } + + template <class _Ret, class _Tp, class _Arg> + inline mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template <class _Ret, class _Tp, class _Arg> + inline const_mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template <class _Ret, class _Tp, class _Arg> + inline mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + template <class _Ret, class _Tp, class _Arg> + inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + /** @} */ + +_GLIBCXX_END_NAMESPACE + +#endif /* _FUNCTION_H */ diff --git a/libstdc++/include/bits/stl_heap.h b/libstdc++/include/bits/stl_heap.h new file mode 100644 index 0000000..2f0d04c --- /dev/null +++ b/libstdc++/include/bits/stl_heap.h @@ -0,0 +1,463 @@ +// Heap implementation -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_heap.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_HEAP_H +#define _STL_HEAP_H 1 + +#include <debug/debug.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // is_heap, a predicate testing whether or not a range is + // a heap. This function is an extension, not part of the C++ + // standard. + template<typename _RandomAccessIterator, typename _Distance> + bool + __is_heap(_RandomAccessIterator __first, _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__first[__parent] < __first[__child]) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template<typename _RandomAccessIterator, typename _Distance, + typename _StrictWeakOrdering> + bool + __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp, + _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__comp(__first[__parent], __first[__child])) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template<typename _RandomAccessIterator> + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::__is_heap(__first, std::distance(__first, __last)); } + + template<typename _RandomAccessIterator, typename _StrictWeakOrdering> + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _StrictWeakOrdering __comp) + { return std::__is_heap(__first, __comp, std::distance(__first, __last)); } + + // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. + + template<typename _RandomAccessIterator, typename _Distance, typename _Tp> + void + __push_heap(_RandomAccessIterator __first, + _Distance __holeIndex, _Distance __topIndex, _Tp __value) + { + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && *(__first + __parent) < __value) + { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; + } + + /** + * @brief Push an element onto a heap. + * @param first Start of heap. + * @param last End of heap + element. + * @ingroup heap + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + */ + template<typename _RandomAccessIterator> + inline void + push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last - 1); + + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _ValueType(*(__last - 1))); + } + + template<typename _RandomAccessIterator, typename _Distance, typename _Tp, + typename _Compare> + void + __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __topIndex, _Tp __value, _Compare __comp) + { + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex + && __comp(*(__first + __parent), __value)) + { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; + } + + /** + * @brief Push an element onto a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap + element. + * @param comp Comparison functor. + * @ingroup heap + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + * Compare operations are performed using comp. + */ + template<typename _RandomAccessIterator, typename _Compare> + inline void + push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last - 1, __comp); + + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _ValueType(*(__last - 1)), __comp); + } + + template<typename _RandomAccessIterator, typename _Distance, typename _Tp> + void + __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value) + { + const _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) + { + if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) + { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + std::__push_heap(__first, __holeIndex, __topIndex, __value); + } + + template<typename _RandomAccessIterator, typename _Tp> + inline void + __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + *__result = *__first; + std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value); + } + + /** + * @brief Pop an element off a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. + */ + template<typename _RandomAccessIterator> + inline void + pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap(__first, __last); + + std::__pop_heap(__first, __last - 1, __last - 1, + _ValueType(*(__last - 1))); + } + + template<typename _RandomAccessIterator, typename _Distance, + typename _Tp, typename _Compare> + void + __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value, _Compare __comp) + { + const _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) + { + if (__comp(*(__first + __secondChild), + *(__first + (__secondChild - 1)))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) + { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + std::__push_heap(__first, __holeIndex, __topIndex, __value, __comp); + } + + template<typename _RandomAccessIterator, typename _Tp, typename _Compare> + inline void + __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + *__result = *__first; + std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value, __comp); + } + + /** + * @brief Pop an element off a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. Comparisons are + * made using comp. + */ + template<typename _RandomAccessIterator, typename _Compare> + inline void + pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); + + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + std::__pop_heap(__first, __last - 1, __last - 1, + _ValueType(*(__last - 1)), __comp); + } + + /** + * @brief Construct a heap over a range. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation makes the elements in [first,last) into a heap. + */ + template<typename _RandomAccessIterator> + void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + std::__adjust_heap(__first, __parent, __len, + _ValueType(*(__first + __parent))); + if (__parent == 0) + return; + __parent--; + } + } + + /** + * @brief Construct a heap over a range using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation makes the elements in [first,last) into a heap. + * Comparisons are made using comp. + */ + template<typename _RandomAccessIterator, typename _Compare> + inline void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + std::__adjust_heap(__first, __parent, __len, + _ValueType(*(__first + __parent)), __comp); + if (__parent == 0) + return; + __parent--; + } + } + + /** + * @brief Sort a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation sorts the valid heap in the range [first,last). + */ + template<typename _RandomAccessIterator> + void + sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last); + + while (__last - __first > 1) + std::pop_heap(__first, _RandomAccessIterator(__last--)); + } + + /** + * @brief Sort a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation sorts the valid heap in the range [first,last). + * Comparisons are made using comp. + */ + template<typename _RandomAccessIterator, typename _Compare> + void + sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); + + while (__last - __first > 1) + std::pop_heap(__first, _RandomAccessIterator(__last--), __comp); + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _STL_HEAP_H */ diff --git a/libstdc++/include/bits/stl_iterator.h b/libstdc++/include/bits/stl_iterator.h new file mode 100644 index 0000000..f9425aa --- /dev/null +++ b/libstdc++/include/bits/stl_iterator.h @@ -0,0 +1,827 @@ +// Iterators -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_iterator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * This file implements reverse_iterator, back_insert_iterator, + * front_insert_iterator, insert_iterator, __normal_iterator, and their + * supporting functions and overloaded operators. + */ + +#ifndef _ITERATOR_H +#define _ITERATOR_H 1 + +#include <bits/cpp_type_traits.h> +#include <ext/type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // 24.4.1 Reverse iterators + /** + * "Bidirectional and random access iterators have corresponding reverse + * %iterator adaptors that iterate through the data structure in the + * opposite direction. They have the same signatures as the corresponding + * iterators. The fundamental relation between a reverse %iterator and its + * corresponding %iterator @c i is established by the identity: + * @code + * &*(reverse_iterator(i)) == &*(i - 1) + * @endcode + * + * This mapping is dictated by the fact that while there is always a + * pointer past the end of an array, there might not be a valid pointer + * before the beginning of an array." [24.4.1]/1,2 + * + * Reverse iterators can be tricky and surprising at first. Their + * semantics make sense, however, and the trickiness is a side effect of + * the requirement that the iterators must be safe. + */ + template<typename _Iterator> + class reverse_iterator + : public iterator<typename iterator_traits<_Iterator>::iterator_category, + typename iterator_traits<_Iterator>::value_type, + typename iterator_traits<_Iterator>::difference_type, + typename iterator_traits<_Iterator>::pointer, + typename iterator_traits<_Iterator>::reference> + { + protected: + _Iterator current; + + public: + typedef _Iterator iterator_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::reference reference; + typedef typename iterator_traits<_Iterator>::pointer pointer; + + public: + /** + * The default constructor default-initializes member @p current. + * If it is a pointer, that means it is zero-initialized. + */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 235 No specification of default ctor for reverse_iterator + reverse_iterator() : current() { } + + /** + * This %iterator will move in the opposite direction that @p x does. + */ + explicit + reverse_iterator(iterator_type __x) : current(__x) { } + + /** + * The copy constructor is normal. + */ + reverse_iterator(const reverse_iterator& __x) + : current(__x.current) { } + + /** + * A reverse_iterator across other types can be copied in the normal + * fashion. + */ + template<typename _Iter> + reverse_iterator(const reverse_iterator<_Iter>& __x) + : current(__x.base()) { } + + /** + * @return @c current, the %iterator used for underlying work. + */ + iterator_type + base() const + { return current; } + + /** + * @return TODO + * + * @doctodo + */ + reference + operator*() const + { + _Iterator __tmp = current; + return *--__tmp; + } + + /** + * @return TODO + * + * @doctodo + */ + pointer + operator->() const + { return &(operator*()); } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator++() + { + --current; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator++(int) + { + reverse_iterator __tmp = *this; + --current; + return __tmp; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator--() + { + ++current; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator--(int) + { + reverse_iterator __tmp = *this; + ++current; + return __tmp; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator+(difference_type __n) const + { return reverse_iterator(current - __n); } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator+=(difference_type __n) + { + current -= __n; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator-(difference_type __n) const + { return reverse_iterator(current + __n); } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator-=(difference_type __n) + { + current += __n; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reference + operator[](difference_type __n) const + { return *(*this + __n); } + }; + + //@{ + /** + * @param x A %reverse_iterator. + * @param y A %reverse_iterator. + * @return A simple bool. + * + * Reverse iterators forward many operations to their underlying base() + * iterators. Others are implemented in terms of one another. + * + */ + template<typename _Iterator> + inline bool + operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __x.base() == __y.base(); } + + template<typename _Iterator> + inline bool + operator<(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y.base() < __x.base(); } + + template<typename _Iterator> + inline bool + operator!=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__x == __y); } + + template<typename _Iterator> + inline bool + operator>(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y < __x; } + + template<typename _Iterator> + inline bool + operator<=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__y < __x); } + + template<typename _Iterator> + inline bool + operator>=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__x < __y); } + + template<typename _Iterator> + inline typename reverse_iterator<_Iterator>::difference_type + operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y.base() - __x.base(); } + + template<typename _Iterator> + inline reverse_iterator<_Iterator> + operator+(typename reverse_iterator<_Iterator>::difference_type __n, + const reverse_iterator<_Iterator>& __x) + { return reverse_iterator<_Iterator>(__x.base() - __n); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 280. Comparison of reverse_iterator to const reverse_iterator. + template<typename _IteratorL, typename _IteratorR> + inline bool + operator==(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return __x.base() == __y.base(); } + + template<typename _IteratorL, typename _IteratorR> + inline bool + operator<(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return __y.base() < __x.base(); } + + template<typename _IteratorL, typename _IteratorR> + inline bool + operator!=(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return !(__x == __y); } + + template<typename _IteratorL, typename _IteratorR> + inline bool + operator>(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return __y < __x; } + + template<typename _IteratorL, typename _IteratorR> + inline bool + operator<=(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return !(__y < __x); } + + template<typename _IteratorL, typename _IteratorR> + inline bool + operator>=(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return !(__x < __y); } + + template<typename _IteratorL, typename _IteratorR> + inline typename reverse_iterator<_IteratorL>::difference_type + operator-(const reverse_iterator<_IteratorL>& __x, + const reverse_iterator<_IteratorR>& __y) + { return __y.base() - __x.base(); } + //@} + + // 24.4.2.2.1 back_insert_iterator + /** + * @brief Turns assignment into insertion. + * + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator appends it to the container using + * push_back. + * + * Tip: Using the back_inserter function to create these iterators can + * save typing. + */ + template<typename _Container> + class back_insert_iterator + : public iterator<output_iterator_tag, void, void, void, void> + { + protected: + _Container* container; + + public: + /// A nested typedef for the type of whatever container you used. + typedef _Container container_type; + + /// The only way to create this %iterator is with a container. + explicit + back_insert_iterator(_Container& __x) : container(&__x) { } + + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container<T>. + * @return This %iterator, for chained operations. + * + * This kind of %iterator doesn't really have a "position" in the + * container (you can think of the position as being permanently at + * the end, if you like). Assigning a value to the %iterator will + * always append the value to the end of the container. + */ + back_insert_iterator& + operator=(typename _Container::const_reference __value) + { + container->push_back(__value); + return *this; + } + + /// Simply returns *this. + back_insert_iterator& + operator*() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + back_insert_iterator& + operator++() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + back_insert_iterator + operator++(int) + { return *this; } + }; + + /** + * @param x A container of arbitrary type. + * @return An instance of back_insert_iterator working on @p x. + * + * This wrapper function helps in creating back_insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ + template<typename _Container> + inline back_insert_iterator<_Container> + back_inserter(_Container& __x) + { return back_insert_iterator<_Container>(__x); } + + /** + * @brief Turns assignment into insertion. + * + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator prepends it to the container using + * push_front. + * + * Tip: Using the front_inserter function to create these iterators can + * save typing. + */ + template<typename _Container> + class front_insert_iterator + : public iterator<output_iterator_tag, void, void, void, void> + { + protected: + _Container* container; + + public: + /// A nested typedef for the type of whatever container you used. + typedef _Container container_type; + + /// The only way to create this %iterator is with a container. + explicit front_insert_iterator(_Container& __x) : container(&__x) { } + + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container<T>. + * @return This %iterator, for chained operations. + * + * This kind of %iterator doesn't really have a "position" in the + * container (you can think of the position as being permanently at + * the front, if you like). Assigning a value to the %iterator will + * always prepend the value to the front of the container. + */ + front_insert_iterator& + operator=(typename _Container::const_reference __value) + { + container->push_front(__value); + return *this; + } + + /// Simply returns *this. + front_insert_iterator& + operator*() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + front_insert_iterator& + operator++() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + front_insert_iterator + operator++(int) + { return *this; } + }; + + /** + * @param x A container of arbitrary type. + * @return An instance of front_insert_iterator working on @p x. + * + * This wrapper function helps in creating front_insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ + template<typename _Container> + inline front_insert_iterator<_Container> + front_inserter(_Container& __x) + { return front_insert_iterator<_Container>(__x); } + + /** + * @brief Turns assignment into insertion. + * + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator inserts it in the container at the + * %iterator's position, rather than overwriting the value at that + * position. + * + * (Sequences will actually insert a @e copy of the value before the + * %iterator's position.) + * + * Tip: Using the inserter function to create these iterators can + * save typing. + */ + template<typename _Container> + class insert_iterator + : public iterator<output_iterator_tag, void, void, void, void> + { + protected: + _Container* container; + typename _Container::iterator iter; + + public: + /// A nested typedef for the type of whatever container you used. + typedef _Container container_type; + + /** + * The only way to create this %iterator is with a container and an + * initial position (a normal %iterator into the container). + */ + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x), iter(__i) {} + + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container<T>. + * @return This %iterator, for chained operations. + * + * This kind of %iterator maintains its own position in the + * container. Assigning a value to the %iterator will insert the + * value into the container at the place before the %iterator. + * + * The position is maintained such that subsequent assignments will + * insert values immediately after one another. For example, + * @code + * // vector v contains A and Z + * + * insert_iterator i (v, ++v.begin()); + * i = 1; + * i = 2; + * i = 3; + * + * // vector v contains A, 1, 2, 3, and Z + * @endcode + */ + insert_iterator& + operator=(const typename _Container::const_reference __value) + { + iter = container->insert(iter, __value); + ++iter; + return *this; + } + + /// Simply returns *this. + insert_iterator& + operator*() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + insert_iterator& + operator++() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + insert_iterator& + operator++(int) + { return *this; } + }; + + /** + * @param x A container of arbitrary type. + * @return An instance of insert_iterator working on @p x. + * + * This wrapper function helps in creating insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ + template<typename _Container, typename _Iterator> + inline insert_iterator<_Container> + inserter(_Container& __x, _Iterator __i) + { + return insert_iterator<_Container>(__x, + typename _Container::iterator(__i)); + } + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // This iterator adapter is 'normal' in the sense that it does not + // change the semantics of any of the operators of its iterator + // parameter. Its primary purpose is to convert an iterator that is + // not a class, e.g. a pointer, into an iterator that is a class. + // The _Container parameter exists solely so that different containers + // using this template can instantiate different types, even if the + // _Iterator parameter is the same. + using std::iterator_traits; + using std::iterator; + template<typename _Iterator, typename _Container> + class __normal_iterator + { + protected: + _Iterator _M_current; + + public: + typedef typename iterator_traits<_Iterator>::iterator_category + iterator_category; + typedef typename iterator_traits<_Iterator>::value_type value_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::reference reference; + typedef typename iterator_traits<_Iterator>::pointer pointer; + + __normal_iterator() : _M_current(_Iterator()) { } + + explicit + __normal_iterator(const _Iterator& __i) : _M_current(__i) { } + + // Allow iterator to const_iterator conversion + template<typename _Iter> + __normal_iterator(const __normal_iterator<_Iter, + typename __enable_if< + (std::__are_same<_Iter, typename _Container::pointer>::__value), + _Container>::__type>& __i) + : _M_current(__i.base()) { } + + // Forward iterator requirements + reference + operator*() const + { return *_M_current; } + + pointer + operator->() const + { return _M_current; } + + __normal_iterator& + operator++() + { + ++_M_current; + return *this; + } + + __normal_iterator + operator++(int) + { return __normal_iterator(_M_current++); } + + // Bidirectional iterator requirements + __normal_iterator& + operator--() + { + --_M_current; + return *this; + } + + __normal_iterator + operator--(int) + { return __normal_iterator(_M_current--); } + + // Random access iterator requirements + reference + operator[](const difference_type& __n) const + { return _M_current[__n]; } + + __normal_iterator& + operator+=(const difference_type& __n) + { _M_current += __n; return *this; } + + __normal_iterator + operator+(const difference_type& __n) const + { return __normal_iterator(_M_current + __n); } + + __normal_iterator& + operator-=(const difference_type& __n) + { _M_current -= __n; return *this; } + + __normal_iterator + operator-(const difference_type& __n) const + { return __normal_iterator(_M_current - __n); } + + const _Iterator& + base() const + { return _M_current; } + }; + + // Note: In what follows, the left- and right-hand-side iterators are + // allowed to vary in types (conceptually in cv-qualification) so that + // comparaison between cv-qualified and non-cv-qualified iterators be + // valid. However, the greedy and unfriendly operators in std::rel_ops + // will make overload resolution ambiguous (when in scope) if we don't + // provide overloads whose operands are of the same type. Can someone + // remind me what generic programming is about? -- Gaby + + // Forward iterator requirements + template<typename _IteratorL, typename _IteratorR, typename _Container> + inline bool + operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } + + template<typename _Iterator, typename _Container> + inline bool + operator==(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } + + template<typename _IteratorL, typename _IteratorR, typename _Container> + inline bool + operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } + + template<typename _Iterator, typename _Container> + inline bool + operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } + + // Random access iterator requirements + template<typename _IteratorL, typename _IteratorR, typename _Container> + inline bool + operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } + + template<typename _Iterator, typename _Container> + inline bool + operator<(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } + + template<typename _IteratorL, typename _IteratorR, typename _Container> + inline bool + operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } + + template<typename _Iterator, typename _Container> + inline bool + operator>(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } + + template<typename _IteratorL, typename _IteratorR, typename _Container> + inline bool + operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } + + template<typename _Iterator, typename _Container> + inline bool + operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } + + template<typename _IteratorL, typename _IteratorR, typename _Container> + inline bool + operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } + + template<typename _Iterator, typename _Container> + inline bool + operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template<typename _IteratorL, typename _IteratorR, typename _Container> + inline typename __normal_iterator<_IteratorL, _Container>::difference_type + operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() - __rhs.base(); } + + template<typename _Iterator, typename _Container> + inline typename __normal_iterator<_Iterator, _Container>::difference_type + operator-(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() - __rhs.base(); } + + template<typename _Iterator, typename _Container> + inline __normal_iterator<_Iterator, _Container> + operator+(typename __normal_iterator<_Iterator, _Container>::difference_type + __n, const __normal_iterator<_Iterator, _Container>& __i) + { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/stl_iterator_base_funcs.h b/libstdc++/include/bits/stl_iterator_base_funcs.h new file mode 100644 index 0000000..79fb667 --- /dev/null +++ b/libstdc++/include/bits/stl_iterator_base_funcs.h @@ -0,0 +1,182 @@ +// Functions used by iterators -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_iterator_base_funcs.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * This file contains all of the general iterator-related utility + * functions, such as distance() and advance(). + */ + +#ifndef _ITERATOR_BASE_FUNCS_H +#define _ITERATOR_BASE_FUNCS_H 1 + +#pragma GCC system_header +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _InputIterator> + inline typename iterator_traits<_InputIterator>::difference_type + __distance(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) + { + ++__first; + ++__n; + } + return __n; + } + + template<typename _RandomAccessIterator> + inline typename iterator_traits<_RandomAccessIterator>::difference_type + __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + return __last - __first; + } + + /** + * @brief A generalization of pointer arithmetic. + * @param first An input iterator. + * @param last An input iterator. + * @return The distance between them. + * + * Returns @c n such that first + n == last. This requires that @p last + * must be reachable from @p first. Note that @c n may be negative. + * + * For random access iterators, this uses their @c + and @c - operations + * and are constant time. For other %iterator classes they are linear time. + */ + template<typename _InputIterator> + inline typename iterator_traits<_InputIterator>::difference_type + distance(_InputIterator __first, _InputIterator __last) + { + // concept requirements -- taken care of in __distance + return std::__distance(__first, __last, + std::__iterator_category(__first)); + } + + template<typename _InputIterator, typename _Distance> + inline void + __advance(_InputIterator& __i, _Distance __n, input_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + while (__n--) + ++__i; + } + + template<typename _BidirectionalIterator, typename _Distance> + inline void + __advance(_BidirectionalIterator& __i, _Distance __n, + bidirectional_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + if (__n > 0) + while (__n--) + ++__i; + else + while (__n++) + --__i; + } + + template<typename _RandomAccessIterator, typename _Distance> + inline void + __advance(_RandomAccessIterator& __i, _Distance __n, + random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __i += __n; + } + + /** + * @brief A generalization of pointer arithmetic. + * @param i An input iterator. + * @param n The "delta" by which to change @p i. + * @return Nothing. + * + * This increments @p i by @p n. For bidirectional and random access + * iterators, @p n may be negative, in which case @p i is decremented. + * + * For random access iterators, this uses their @c + and @c - operations + * and are constant time. For other %iterator classes they are linear time. + */ + template<typename _InputIterator, typename _Distance> + inline void + advance(_InputIterator& __i, _Distance __n) + { + // concept requirements -- taken care of in __advance + typename iterator_traits<_InputIterator>::difference_type __d = __n; + std::__advance(__i, __d, std::__iterator_category(__i)); + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _ITERATOR_BASE_FUNCS_H */ diff --git a/libstdc++/include/bits/stl_iterator_base_types.h b/libstdc++/include/bits/stl_iterator_base_types.h new file mode 100644 index 0000000..c02cd26 --- /dev/null +++ b/libstdc++/include/bits/stl_iterator_base_types.h @@ -0,0 +1,170 @@ +// Types used in iterator implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_iterator_base_types.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * This file contains all of the general iterator-related utility types, + * such as iterator_traits and struct iterator. + */ + +#ifndef _ITERATOR_BASE_TYPES_H +#define _ITERATOR_BASE_TYPES_H 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + //@{ + /** + * @defgroup iterator_tags Iterator Tags + * These are empty types, used to distinguish different iterators. The + * distinction is not made by what they contain, but simply by what they + * are. Different underlying algorithms can then be used based on the + * different operations supporetd by different iterator types. + */ + /// Marking input iterators. + struct input_iterator_tag {}; + /// Marking output iterators. + struct output_iterator_tag {}; + /// Forward iterators support a superset of input iterator operations. + struct forward_iterator_tag : public input_iterator_tag {}; + /// Bidirectional iterators support a superset of forward iterator + /// operations. + struct bidirectional_iterator_tag : public forward_iterator_tag {}; + /// Random-access iterators support a superset of bidirectional iterator + /// operations. + struct random_access_iterator_tag : public bidirectional_iterator_tag {}; + //@} + + + /** + * @brief Common %iterator class. + * + * This class does nothing but define nested typedefs. %Iterator classes + * can inherit from this class to save some work. The typedefs are then + * used in specializations and overloading. + * + * In particular, there are no default implementations of requirements + * such as @c operator++ and the like. (How could there be?) + */ + template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t, + typename _Pointer = _Tp*, typename _Reference = _Tp&> + struct iterator + { + /// One of the @link iterator_tags tag types@endlink. + typedef _Category iterator_category; + /// The type "pointed to" by the iterator. + typedef _Tp value_type; + /// Distance between iterators is represented as this type. + typedef _Distance difference_type; + /// This type represents a pointer-to-value_type. + typedef _Pointer pointer; + /// This type represents a reference-to-value_type. + typedef _Reference reference; + }; + + /** + * This class does nothing but define nested typedefs. The general + * version simply "forwards" the nested typedefs from the Iterator + * argument. Specialized versions for pointers and pointers-to-const + * provide tighter, more correct semantics. + */ + template<typename _Iterator> + struct iterator_traits + { + typedef typename _Iterator::iterator_category iterator_category; + typedef typename _Iterator::value_type value_type; + typedef typename _Iterator::difference_type difference_type; + typedef typename _Iterator::pointer pointer; + typedef typename _Iterator::reference reference; + }; + + template<typename _Tp> + struct iterator_traits<_Tp*> + { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + + template<typename _Tp> + struct iterator_traits<const _Tp*> + { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + }; + + /** + * @if maint + * This function is not a part of the C++ standard but is syntactic + * sugar for internal library use only. + * @endif + */ + template<typename _Iter> + inline typename iterator_traits<_Iter>::iterator_category + __iterator_category(const _Iter&) + { return typename iterator_traits<_Iter>::iterator_category(); } + +_GLIBCXX_END_NAMESPACE + +#endif /* _ITERATOR_BASE_TYPES_H */ + diff --git a/libstdc++/include/bits/stl_list.h b/libstdc++/include/bits/stl_list.h new file mode 100644 index 0000000..e37e5ee --- /dev/null +++ b/libstdc++/include/bits/stl_list.h @@ -0,0 +1,1262 @@ +// List implementation -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_list.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LIST_H +#define _LIST_H 1 + +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + // Supporting structures are split into common and templated types; the + // latter publicly inherits from the former in an effort to reduce code + // duplication. This results in some "needless" static_cast'ing later on, + // but it's all safe downcasting. + + /// @if maint Common part of a node in the %list. @endif + struct _List_node_base + { + _List_node_base* _M_next; ///< Self-explanatory + _List_node_base* _M_prev; ///< Self-explanatory + + static void + swap(_List_node_base& __x, _List_node_base& __y); + + void + transfer(_List_node_base * const __first, + _List_node_base * const __last); + + void + reverse(); + + void + hook(_List_node_base * const __position); + + void + unhook(); + }; + + /// @if maint An actual node in the %list. @endif + template<typename _Tp> + struct _List_node : public _List_node_base + { + _Tp _M_data; ///< User's data. + }; + + /** + * @brief A list::iterator. + * + * @if maint + * All the functions are op overloads. + * @endif + */ + template<typename _Tp> + struct _List_iterator + { + typedef _List_iterator<_Tp> _Self; + typedef _List_node<_Tp> _Node; + + typedef ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + + _List_iterator() + : _M_node() { } + + explicit + _List_iterator(_List_node_base* __x) + : _M_node(__x) { } + + // Must downcast from List_node_base to _List_node to get to _M_data. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &static_cast<_Node*>(_M_node)->_M_data; } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + // The only member points to the %list element. + _List_node_base* _M_node; + }; + + /** + * @brief A list::const_iterator. + * + * @if maint + * All the functions are op overloads. + * @endif + */ + template<typename _Tp> + struct _List_const_iterator + { + typedef _List_const_iterator<_Tp> _Self; + typedef const _List_node<_Tp> _Node; + typedef _List_iterator<_Tp> iterator; + + typedef ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + _List_const_iterator() + : _M_node() { } + + explicit + _List_const_iterator(const _List_node_base* __x) + : _M_node(__x) { } + + _List_const_iterator(const iterator& __x) + : _M_node(__x._M_node) { } + + // Must downcast from List_node_base to _List_node to get to + // _M_data. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &static_cast<_Node*>(_M_node)->_M_data; } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + // The only member points to the %list element. + const _List_node_base* _M_node; + }; + + template<typename _Val> + inline bool + operator==(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template<typename _Val> + inline bool + operator!=(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + + /** + * @if maint + * See bits/stl_deque.h's _Deque_base for an explanation. + * @endif + */ + template<typename _Tp, typename _Alloc> + class _List_base + { + protected: + // NOTA BENE + // The stored instance is not actually of "allocator_type"'s + // type. Instead we rebind the type to + // Allocator<List_node<Tp>>, which according to [20.1.5]/4 + // should probably be the same. List_node<Tp> is not the same + // size as Tp (it's two pointers larger), and specializations on + // Tp may go unused because List_node<Tp> is being bound + // instead. + // + // We put this to the test in the constructors and in + // get_allocator, where we use conversions between + // allocator_type and _Node_alloc_type. The conversion is + // required by table 32 in [20.1.5]. + typedef typename _Alloc::template rebind<_List_node<_Tp> >::other + _Node_alloc_type; + + typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; + + struct _List_impl + : public _Node_alloc_type + { + _List_node_base _M_node; + + _List_impl(const _Node_alloc_type& __a) + : _Node_alloc_type(__a), _M_node() + { } + }; + + _List_impl _M_impl; + + _List_node<_Tp>* + _M_get_node() + { return _M_impl._Node_alloc_type::allocate(1); } + + void + _M_put_node(_List_node<_Tp>* __p) + { _M_impl._Node_alloc_type::deallocate(__p, 1); } + + public: + typedef _Alloc allocator_type; + + _Node_alloc_type& + _M_get_Node_allocator() + { return *static_cast<_Node_alloc_type*>(&this->_M_impl); } + + const _Node_alloc_type& + _M_get_Node_allocator() const + { return *static_cast<const _Node_alloc_type*>(&this->_M_impl); } + + _Tp_alloc_type + _M_get_Tp_allocator() const + { return _Tp_alloc_type(_M_get_Node_allocator()); } + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Node_allocator()); } + + _List_base(const allocator_type& __a) + : _M_impl(__a) + { _M_init(); } + + // This is what actually destroys the list. + ~_List_base() + { _M_clear(); } + + void + _M_clear(); + + void + _M_init() + { + this->_M_impl._M_node._M_next = &this->_M_impl._M_node; + this->_M_impl._M_node._M_prev = &this->_M_impl._M_node; + } + }; + + /** + * @brief A standard container with linear time access to elements, + * and fixed time insertion/deletion at any point in the sequence. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and a + * <a href="tables.html#67">sequence</a>, including the + * <a href="tables.html#68">optional sequence requirements</a> with the + * %exception of @c at and @c operator[]. + * + * This is a @e doubly @e linked %list. Traversal up and down the + * %list requires linear time, but adding and removing elements (or + * @e nodes) is done in constant time, regardless of where the + * change takes place. Unlike std::vector and std::deque, + * random-access iterators are not provided, so subscripting ( @c + * [] ) access is not allowed. For algorithms which only need + * sequential access, this lack makes no difference. + * + * Also unlike the other standard containers, std::list provides + * specialized algorithms %unique to linked lists, such as + * splicing, sorting, and in-place reversal. + * + * @if maint + * A couple points on memory allocation for list<Tp>: + * + * First, we never actually allocate a Tp, we allocate + * List_node<Tp>'s and trust [20.1.5]/4 to DTRT. This is to ensure + * that after elements from %list<X,Alloc1> are spliced into + * %list<X,Alloc2>, destroying the memory of the second %list is a + * valid operation, i.e., Alloc1 giveth and Alloc2 taketh away. + * + * Second, a %list conceptually represented as + * @code + * A <---> B <---> C <---> D + * @endcode + * is actually circular; a link exists between A and D. The %list + * class holds (as its only data member) a private list::iterator + * pointing to @e D, not to @e A! To get to the head of the %list, + * we start at the tail and move forward by one. When this member + * iterator's next/previous pointers refer to itself, the %list is + * %empty. @endif + */ + template<typename _Tp, typename _Alloc = std::allocator<_Tp> > + class list : protected _List_base<_Tp, _Alloc> + { + // concept requirements + typedef typename _Alloc::value_type _Alloc_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) + + typedef _List_base<_Tp, _Alloc> _Base; + typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; + + public: + typedef _Tp value_type; + typedef typename _Tp_alloc_type::pointer pointer; + typedef typename _Tp_alloc_type::const_pointer const_pointer; + typedef typename _Tp_alloc_type::reference reference; + typedef typename _Tp_alloc_type::const_reference const_reference; + typedef _List_iterator<_Tp> iterator; + typedef _List_const_iterator<_Tp> const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + protected: + // Note that pointers-to-_Node's can be ctor-converted to + // iterator types. + typedef _List_node<_Tp> _Node; + + using _Base::_M_impl; + using _Base::_M_put_node; + using _Base::_M_get_node; + using _Base::_M_get_Tp_allocator; + using _Base::_M_get_Node_allocator; + + /** + * @if maint + * @param x An instance of user data. + * + * Allocates space for a new node and constructs a copy of @a x in it. + * @endif + */ + _Node* + _M_create_node(const value_type& __x) + { + _Node* __p = this->_M_get_node(); + try + { + _M_get_Tp_allocator().construct(&__p->_M_data, __x); + } + catch(...) + { + _M_put_node(__p); + __throw_exception_again; + } + return __p; + } + + public: + // [23.2.2.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + list(const allocator_type& __a = allocator_type()) + : _Base(__a) { } + + /** + * @brief Create a %list with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %list with @a n copies of @a value. + */ + explicit + list(size_type __n, const value_type& __value = value_type(), + const allocator_type& __a = allocator_type()) + : _Base(__a) + { _M_fill_initialize(__n, __value); } + + /** + * @brief %List copy constructor. + * @param x A %list of identical element and allocator types. + * + * The newly-created %list uses a copy of the allocation object used + * by @a x. + */ + list(const list& __x) + : _Base(__x._M_get_Node_allocator()) + { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); } + + /** + * @brief Builds a %list from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %list consisting of copies of the elements from + * [@a first,@a last). This is linear in N (where N is + * distance(@a first,@a last)). + */ + template<typename _InputIterator> + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + /** + * No explicit dtor needed as the _Base dtor takes care of + * things. The _Base dtor only erases the elements, and note + * that if the elements themselves are pointers, the pointed-to + * memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + + /** + * @brief %List assignment operator. + * @param x A %list of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy + * constructor, the allocator object is not copied. + */ + list& + operator=(const list& __x); + + /** + * @brief Assigns a given value to a %list. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %list with @a n copies of the given + * value. Note that the assignment completely changes the %list + * and that the resulting %list's size is the same as the number + * of elements assigned. Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %list with copies of the elements in the + * range [@a first,@a last). + * + * Note that the assignment completely changes the %list and + * that the resulting %list's size is the same as the number of + * elements assigned. Old data may be lost. + */ + template<typename _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %list. Iteration is done in ordinary element order. + */ + iterator + begin() + { return iterator(this->_M_impl._M_node._M_next); } + + /** + * Returns a read-only (constant) iterator that points to the + * first element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + begin() const + { return const_iterator(this->_M_impl._M_node._M_next); } + + /** + * Returns a read/write iterator that points one past the last + * element in the %list. Iteration is done in ordinary element + * order. + */ + iterator + end() + { return iterator(&this->_M_impl._M_node); } + + /** + * Returns a read-only (constant) iterator that points one past + * the last element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + end() const + { return const_iterator(&this->_M_impl._M_node); } + + /** + * Returns a read/write reverse iterator that points to the last + * element in the %list. Iteration is done in reverse element + * order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + /** + * Returns a read-only (constant) reverse iterator that points to + * the last element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + /** + * Returns a read/write reverse iterator that points to one + * before the first element in the %list. Iteration is done in + * reverse element order. + */ + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // [23.2.2.2] capacity + /** + * Returns true if the %list is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const + { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } + + /** Returns the number of elements in the %list. */ + size_type + size() const + { return std::distance(begin(), end()); } + + /** Returns the size() of the largest possible %list. */ + size_type + max_size() const + { return _M_get_Tp_allocator().max_size(); } + + /** + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %list to the specified number + * of elements. If the number is smaller than the %list's + * current size the %list is truncated, otherwise the %list is + * extended and new elements are populated with given data. + */ + void + resize(size_type __new_size, value_type __x = value_type()); + + // element access + /** + * Returns a read/write reference to the data at the first + * element of the %list. + */ + reference + front() + { return *begin(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %list. + */ + const_reference + front() const + { return *begin(); } + + /** + * Returns a read/write reference to the data at the last element + * of the %list. + */ + reference + back() + { + iterator __tmp = end(); + --__tmp; + return *__tmp; + } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %list. + */ + const_reference + back() const + { + const_iterator __tmp = end(); + --__tmp; + return *__tmp; + } + + // [23.2.2.3] modifiers + /** + * @brief Add data to the front of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the front of the %list and assigns the given data + * to it. Due to the nature of a %list this operation can be + * done in constant time, and does not invalidate iterators and + * references. + */ + void + push_front(const value_type& __x) + { this->_M_insert(begin(), __x); } + + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * Note that no data is returned, and if the first element's data + * is needed, it should be retrieved before pop_front() is + * called. + */ + void + pop_front() + { this->_M_erase(begin()); } + + /** + * @brief Add data to the end of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the end of the %list and assigns the given data to + * it. Due to the nature of a %list this operation can be done + * in constant time, and does not invalidate iterators and + * references. + */ + void + push_back(const value_type& __x) + { this->_M_insert(end(), __x); } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * Note that no data is returned, and if the last element's data + * is needed, it should be retrieved before pop_back() is called. + */ + void + pop_back() + { this->_M_erase(iterator(this->_M_impl._M_node._M_prev)); } + + /** + * @brief Inserts given value into %list before specified iterator. + * @param position An iterator into the %list. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before + * the specified location. Due to the nature of a %list this + * operation can be done in constant time, and does not + * invalidate iterators and references. + */ + iterator + insert(iterator __position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %list. + * @param position An iterator into the %list. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the + * given data before the location specified by @a position. + * + * This operation is linear in the number of elements inserted and + * does not invalidate iterators and references. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { + list __tmp(__n, __x, _M_get_Node_allocator()); + splice(__position, __tmp); + } + + /** + * @brief Inserts a range into the %list. + * @param position An iterator into the %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range [@a + * first,@a last) into the %list before the location specified by + * @a position. + * + * This operation is linear in the number of elements inserted and + * does not invalidate iterators and references. + */ + template<typename _InputIterator> + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + list __tmp(__first, __last, _M_get_Node_allocator()); + splice(__position, __tmp); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %list by one. + * + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the element, and that if the element + * is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range @a + * [first,last) and shorten the %list accordingly. + * + * This operation is linear time in the size of the range and only + * invalidates iterators/references to the element being removed. + * The user is also cautioned that this function only erases the + * elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + iterator + erase(iterator __first, iterator __last) + { + while (__first != __last) + __first = erase(__first); + return __last; + } + + /** + * @brief Swaps data with another %list. + * @param x A %list of the same element and allocator types. + * + * This exchanges the elements between two lists in constant + * time. Note that the global std::swap() function is + * specialized such that std::swap(l1,l2) will feed to this + * function. + */ + void + swap(list& __x) + { + _List_node_base::swap(this->_M_impl._M_node, __x._M_impl._M_node); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<typename _Base::_Node_alloc_type>:: + _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator()); + } + + /** + * Erases all the elements. Note that this function only erases + * the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + void + clear() + { + _Base::_M_clear(); + _Base::_M_init(); + } + + // [23.2.2.4] list operations + /** + * @brief Insert contents of another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * + * The elements of @a x are inserted in constant time in front of + * the element referenced by @a position. @a x becomes an empty + * list. + * + * Requires this != @a x. + */ + void + splice(iterator __position, list& __x) + { + if (!__x.empty()) + { + _M_check_equal_allocators(__x); + + this->_M_transfer(__position, __x.begin(), __x.end()); + } + } + + /** + * @brief Insert element from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param i Iterator referencing the element to move. + * + * Removes the element in list @a x referenced by @a i and + * inserts it into the current list before @a position. + */ + void + splice(iterator __position, list& __x, iterator __i) + { + iterator __j = __i; + ++__j; + if (__position == __i || __position == __j) + return; + + if (this != &__x) + _M_check_equal_allocators(__x); + + this->_M_transfer(__position, __i, __j); + } + + /** + * @brief Insert range from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param first Iterator referencing the start of range in x. + * @param last Iterator referencing the end of range in x. + * + * Removes elements in the range [first,last) and inserts them + * before @a position in constant time. + * + * Undefined if @a position is in [first,last). + */ + void + splice(iterator __position, list& __x, iterator __first, iterator __last) + { + if (__first != __last) + { + if (this != &__x) + _M_check_equal_allocators(__x); + + this->_M_transfer(__position, __first, __last); + } + } + + /** + * @brief Remove all elements equal to value. + * @param value The value to remove. + * + * Removes every element in the list equal to @a value. + * Remaining elements stay in list order. Note that this + * function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + remove(const _Tp& __value); + + /** + * @brief Remove all elements satisfying a predicate. + * @param Predicate Unary predicate function or object. + * + * Removes every element in the list for which the predicate + * returns true. Remaining elements stay in list order. Note + * that this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + template<typename _Predicate> + void + remove_if(_Predicate); + + /** + * @brief Remove consecutive duplicate elements. + * + * For each consecutive set of elements with the same value, + * remove all but the first one. Remaining elements stay in + * list order. Note that this function only erases the + * elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing + * the pointer is the user's responsibilty. + */ + void + unique(); + + /** + * @brief Remove consecutive elements satisfying a predicate. + * @param BinaryPredicate Binary predicate function or object. + * + * For each consecutive set of elements [first,last) that + * satisfy predicate(first,i) where i is an iterator in + * [first,last), remove all but the first one. Remaining + * elements stay in list order. Note that this function only + * erases the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + template<typename _BinaryPredicate> + void + unique(_BinaryPredicate); + + /** + * @brief Merge sorted lists. + * @param x Sorted list to merge. + * + * Assumes that both @a x and this list are sorted according to + * operator<(). Merges elements of @a x into this list in + * sorted order, leaving @a x empty when complete. Elements in + * this list precede elements in @a x that are equal. + */ + void + merge(list& __x); + + /** + * @brief Merge sorted lists according to comparison function. + * @param x Sorted list to merge. + * @param StrictWeakOrdering Comparison function definining + * sort order. + * + * Assumes that both @a x and this list are sorted according to + * StrictWeakOrdering. Merges elements of @a x into this list + * in sorted order, leaving @a x empty when complete. Elements + * in this list precede elements in @a x that are equivalent + * according to StrictWeakOrdering(). + */ + template<typename _StrictWeakOrdering> + void + merge(list&, _StrictWeakOrdering); + + /** + * @brief Reverse the elements in list. + * + * Reverse the order of elements in the list in linear time. + */ + void + reverse() + { this->_M_impl._M_node.reverse(); } + + /** + * @brief Sort the elements. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ + void + sort(); + + /** + * @brief Sort the elements according to comparison function. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ + template<typename _StrictWeakOrdering> + void + sort(_StrictWeakOrdering); + + protected: + // Internal constructor functions follow. + + // Called by the range constructor to implement [23.1.1]/9 + template<typename _Integer> + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_fill_initialize(static_cast<size_type>(__n), + static_cast<value_type>(__x)); + } + + // Called by the range constructor to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + for (; __first != __last; ++__first) + push_back(*__first); + } + + // Called by list(n,v,a), and the range constructor when it turns out + // to be the same thing. + void + _M_fill_initialize(size_type __n, const value_type& __x) + { + for (; __n > 0; --__n) + push_back(__x); + } + + + // Internal assign functions follow. + + // Called by the range assign to implement [23.1.1]/9 + template<typename _Integer> + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast<size_type>(__n), + static_cast<value_type>(__val)); + } + + // Called by the range assign to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. + void + _M_fill_assign(size_type __n, const value_type& __val); + + + // Moves the elements from [first,last) before position. + void + _M_transfer(iterator __position, iterator __first, iterator __last) + { __position._M_node->transfer(__first._M_node, __last._M_node); } + + // Inserts new element at position given and with value given. + void + _M_insert(iterator __position, const value_type& __x) + { + _Node* __tmp = _M_create_node(__x); + __tmp->hook(__position._M_node); + } + + // Erases element at position given. + void + _M_erase(iterator __position) + { + __position._M_node->unhook(); + _Node* __n = static_cast<_Node*>(__position._M_node); + _M_get_Tp_allocator().destroy(&__n->_M_data); + _M_put_node(__n); + } + + // To implement the splice (and merge) bits of N1599. + void + _M_check_equal_allocators(list& __x) + { + if (_M_get_Node_allocator() != __x._M_get_Node_allocator()) + __throw_runtime_error(__N("list::_M_check_equal_allocators")); + } + }; + + /** + * @brief List equality comparison. + * @param x A %list. + * @param y A %list of the same type as @a x. + * @return True iff the size and elements of the lists are equal. + * + * This is an equivalence relation. It is linear in the size of + * the lists. Lists are considered equivalent if their sizes are + * equal, and if corresponding elements compare equal. + */ + template<typename _Tp, typename _Alloc> + inline bool + operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { + typedef typename list<_Tp, _Alloc>::const_iterator const_iterator; + const_iterator __end1 = __x.end(); + const_iterator __end2 = __y.end(); + + const_iterator __i1 = __x.begin(); + const_iterator __i2 = __y.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) + { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; + } + + /** + * @brief List ordering relation. + * @param x A %list. + * @param y A %list of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * lists. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template<typename _Tp, typename _Alloc> + inline bool + operator<(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + /// Based on operator== + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template<typename _Tp, typename _Alloc> + inline bool + operator>(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) + { return !(__x < __y); } + + /// See std::list::swap(). + template<typename _Tp, typename _Alloc> + inline void + swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif /* _LIST_H */ + diff --git a/libstdc++/include/bits/stl_map.h b/libstdc++/include/bits/stl_map.h new file mode 100644 index 0000000..13e62bc --- /dev/null +++ b/libstdc++/include/bits/stl_map.h @@ -0,0 +1,740 @@ +// Map implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +// 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_map.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MAP_H +#define _MAP_H 1 + +#include <bits/functexcept.h> +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + /** + * @brief A standard container made up of (key,value) pairs, which can be + * retrieved based on a key, in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and an + * <a href="tables.html#69">associative container</a> (using unique keys). + * For a @c map<Key,T> the key_type is Key, the mapped_type is T, and the + * value_type is std::pair<const Key,T>. + * + * Maps support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for map and + * multimap; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>, + typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > + class map + { + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair<const _Key, _Tp> value_type; + typedef _Compare key_compare; + typedef _Alloc allocator_type; + + private: + // concept requirements + typedef typename _Alloc::value_type _Alloc_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept) + + public: + class value_compare + : public std::binary_function<value_type, value_type, bool> + { + friend class map<_Key, _Tp, _Compare, _Alloc>; + protected: + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + + public: + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef typename _Alloc::template rebind<value_type>::other + _Pair_alloc_type; + + typedef _Rb_tree<key_type, value_type, _Select1st<value_type>, + key_compare, _Pair_alloc_type> _Rep_type; + + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Pair_alloc_type::pointer pointer; + typedef typename _Pair_alloc_type::const_pointer const_pointer; + typedef typename _Pair_alloc_type::reference reference; + typedef typename _Pair_alloc_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + // [23.3.1.1] construct/copy/destroy + // (get_allocator() is normally listed in this section, but seems to have + // been accidentally omitted in the printed standard) + /** + * @brief Default constructor creates no elements. + */ + map() + : _M_t(_Compare(), allocator_type()) { } + + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + map(const _Compare& __comp, const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief Map copy constructor. + * @param x A %map of identical element and allocator types. + * + * The newly-created %map uses a copy of the allocation object used + * by @a x. + */ + map(const map& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template <typename _InputIterator> + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t._M_insert_unique(__first, __last); } + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template <typename _InputIterator> + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t._M_insert_unique(__first, __last); } + + // FIXME There is no dtor declared, but we should have something + // generated by Doxygen. I don't know what tags to add to this + // paragraph to make that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + + /** + * @brief Map assignment operator. + * @param x A %map of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + map& + operator=(const map& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %map. + * Iteration is done in ascending order according to the keys. + */ + iterator + begin() + { return _M_t.begin(); } + + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %map. Iteration is done in ascending order according to the + * keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last + * pair in the %map. Iteration is done in ascending order + * according to the keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %map. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %map. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %map. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %map. Iteration is done in descending + * order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %map is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %map. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %map. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // [23.3.1.2] element access + /** + * @brief Subscript ( @c [] ) access to %map data. + * @param k The key for which data should be retrieved. + * @return A reference to the data of the (key,data) %pair. + * + * Allows for easy lookup with the subscript ( @c [] ) + * operator. Returns data associated with the key specified in + * subscript. If the key does not exist, a pair with that key + * is created using default values, which is then returned. + * + * Lookup requires logarithmic time. + */ + mapped_type& + operator[](const key_type& __k) + { + // concept requirements + __glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>) + + iterator __i = lower_bound(__k); + // __i->first is greater than or equivalent to __k. + if (__i == end() || key_comp()(__k, (*__i).first)) + __i = insert(__i, value_type(__k, mapped_type())); + return (*__i).second; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 464. Suggestion for new member functions in standard containers. + /** + * @brief Access to %map data. + * @param k The key for which data should be retrieved. + * @return A reference to the data whose key is equivalent to @a k, if + * such a data is present in the %map. + * @throw std::out_of_range If no such data is present. + */ + mapped_type& + at(const key_type& __k) + { + iterator __i = lower_bound(__k); + if (__i == end() || key_comp()(__k, (*__i).first)) + __throw_out_of_range(__N("map::at")); + return (*__i).second; + } + + const mapped_type& + at(const key_type& __k) const + { + const_iterator __i = lower_bound(__k); + if (__i == end() || key_comp()(__k, (*__i).first)) + __throw_out_of_range(__N("map::at")); + return (*__i).second; + } + + // modifiers + /** + * @brief Attempts to insert a std::pair into the %map. + + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + + * @return A pair, of which the first element is an iterator that + * points to the possibly inserted pair, and the second is + * a bool that is true if the pair was actually inserted. + * + * This function attempts to insert a (key, value) %pair into the %map. + * A %map relies on unique keys and thus a %pair is only inserted if its + * first element (the key) is not already present in the %map. + * + * Insertion requires logarithmic time. + */ + std::pair<iterator, bool> + insert(const value_type& __x) + { return _M_t._M_insert_unique(__x); } + + /** + * @brief Attempts to insert a std::pair into the %map. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the element with key of @a x (may + * or may not be the %pair passed in). + * + + * This function is not concerned about whether the insertion + * took place, and thus does not return a boolean like the + * single-argument insert() does. Note that the first + * parameter is only a hint and can potentially improve the + * performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See + * http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { return _M_t._M_insert_unique(__position, __x); } + + /** + * @brief Template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t._M_insert_unique(__first, __last); } + + /** + * @brief Erases an element from a %map. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given + * iterator, from a %map. Note that this function only erases + * the element, and that if the element is itself a pointer, + * the pointed-to memory is not touched in any way. Managing + * the pointer is the user's responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %map. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %map. + * @param x A %map of the same element and allocator types. + * + * This exchanges the elements between two maps in constant + * time. (It is only swapping a pointer, an integer, and an + * instance of the @c Compare type (which itself is often + * stateless and empty), so it should be quite fast.) Note + * that the global std::swap() function is specialized such + * that std::swap(m1,m2) will feed to this function. + */ + void + swap(map& __x) + { _M_t.swap(__x._M_t); } + + /** + * Erases all elements in a %map. Note that this function only + * erases the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // observers + /** + * Returns the key comparison object out of which the %map was + * constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %map was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // [23.3.1.3] map operations + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + * + * This function only makes sense for multimaps; for map the result will + * either be 0 (not present) or 1 (present). + */ + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + std::pair<iterator, iterator> + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template <typename _K1, typename _T1, typename _C1, typename _A1> + friend bool + operator== (const map<_K1, _T1, _C1, _A1>&, + const map<_K1, _T1, _C1, _A1>&); + + template <typename _K1, typename _T1, typename _C1, typename _A1> + friend bool + operator< (const map<_K1, _T1, _C1, _A1>&, + const map<_K1, _T1, _C1, _A1>&); + }; + + /** + * @brief Map equality comparison. + * @param x A %map. + * @param y A %map of the same type as @a x. + * @return True iff the size and elements of the maps are equal. + * + * This is an equivalence relation. It is linear in the size of the + * maps. Maps are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator==(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Map ordering relation. + * @param x A %map. + * @param y A %map of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Based on operator== + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator!=(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator>(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator<=(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator>=(const map<_Key, _Tp, _Compare, _Alloc>& __x, + const map<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + /// See std::map::swap(). + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline void + swap(map<_Key, _Tp, _Compare, _Alloc>& __x, + map<_Key, _Tp, _Compare, _Alloc>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif /* _MAP_H */ diff --git a/libstdc++/include/bits/stl_multimap.h b/libstdc++/include/bits/stl_multimap.h new file mode 100644 index 0000000..b11b6e4 --- /dev/null +++ b/libstdc++/include/bits/stl_multimap.h @@ -0,0 +1,670 @@ +// Multimap implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_multimap.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MULTIMAP_H +#define _MULTIMAP_H 1 + +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + /** + * @brief A standard container made up of (key,value) pairs, which can be + * retrieved based on a key, in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and an + * <a href="tables.html#69">associative container</a> (using equivalent + * keys). For a @c multimap<Key,T> the key_type is Key, the mapped_type + * is T, and the value_type is std::pair<const Key,T>. + * + * Multimaps support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for map and + * multimap; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template <typename _Key, typename _Tp, + typename _Compare = std::less<_Key>, + typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > + class multimap + { + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair<const _Key, _Tp> value_type; + typedef _Compare key_compare; + typedef _Alloc allocator_type; + + private: + // concept requirements + typedef typename _Alloc::value_type _Alloc_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept) + + public: + class value_compare + : public std::binary_function<value_type, value_type, bool> + { + friend class multimap<_Key, _Tp, _Compare, _Alloc>; + protected: + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + + public: + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef typename _Alloc::template rebind<value_type>::other + _Pair_alloc_type; + + typedef _Rb_tree<key_type, value_type, _Select1st<value_type>, + key_compare, _Pair_alloc_type> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Pair_alloc_type::pointer pointer; + typedef typename _Pair_alloc_type::const_pointer const_pointer; + typedef typename _Pair_alloc_type::reference reference; + typedef typename _Pair_alloc_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + // [23.3.2] construct/copy/destroy + // (get_allocator() is also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + multimap() + : _M_t(_Compare(), allocator_type()) { } + + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief %Multimap copy constructor. + * @param x A %multimap of identical element and allocator types. + * + * The newly-created %multimap uses a copy of the allocation object used + * by @a x. + */ + multimap(const multimap& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template <typename _InputIterator> + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t._M_insert_equal(__first, __last); } + + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template <typename _InputIterator> + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t._M_insert_equal(__first, __last); } + + // FIXME There is no dtor declared, but we should have something generated + // by Doxygen. I don't know what tags to add to this paragraph to make + // that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + + /** + * @brief %Multimap assignment operator. + * @param x A %multimap of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multimap& + operator=(const multimap& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() + { return _M_t.begin(); } + + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %multimap. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last pair in + * the %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %multimap. Iteration is done in ascending order according + * to the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %multimap. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %multimap. Iteration is done in + * descending order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %multimap is empty. */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %multimap. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %multimap. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // modifiers + /** + * @brief Inserts a std::pair into the %multimap. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t._M_insert_equal(__x); } + + /** + * @brief Inserts a std::pair into the %multimap. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { return _M_t._M_insert_equal(__position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t._M_insert_equal(__first, __last); } + + /** + * @brief Erases an element from a %multimap. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multimap. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multimap. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %multimap. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multimap. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %multimap. + * @param x A %multimap of the same element and allocator types. + * + * This exchanges the elements between two multimaps in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(multimap& __x) + { _M_t.swap(__x._M_t); } + + /** + * Erases all elements in a %multimap. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // observers + /** + * Returns the key comparison object out of which the %multimap + * was constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %multimap was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // multimap operations + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to sought-after element, + * or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful the iterator will point + * to the next greatest element or, if no such greater element exists, to + * end(). + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + std::pair<iterator, iterator> + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template <typename _K1, typename _T1, typename _C1, typename _A1> + friend bool + operator== (const multimap<_K1, _T1, _C1, _A1>&, + const multimap<_K1, _T1, _C1, _A1>&); + + template <typename _K1, typename _T1, typename _C1, typename _A1> + friend bool + operator< (const multimap<_K1, _T1, _C1, _A1>&, + const multimap<_K1, _T1, _C1, _A1>&); + }; + + /** + * @brief Multimap equality comparison. + * @param x A %multimap. + * @param y A %multimap of the same type as @a x. + * @return True iff the size and elements of the maps are equal. + * + * This is an equivalence relation. It is linear in the size of the + * multimaps. Multimaps are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Multimap ordering relation. + * @param x A %multimap. + * @param y A %multimap of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * multimaps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Based on operator== + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator!=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator>(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator<=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline bool + operator>=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, + const multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + /// See std::multimap::swap(). + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> + inline void + swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x, + multimap<_Key, _Tp, _Compare, _Alloc>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif /* _MULTIMAP_H */ diff --git a/libstdc++/include/bits/stl_multiset.h b/libstdc++/include/bits/stl_multiset.h new file mode 100644 index 0000000..8c499c3 --- /dev/null +++ b/libstdc++/include/bits/stl_multiset.h @@ -0,0 +1,565 @@ +// Multiset implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_multiset.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MULTISET_H +#define _MULTISET_H 1 + +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + /** + * @brief A standard container made up of elements, which can be retrieved + * in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and an + * <a href="tables.html#69">associative container</a> (using equivalent + * keys). For a @c multiset<Key> the key_type and value_type are Key. + * + * Multisets support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for set and + * multiset; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template <class _Key, class _Compare = std::less<_Key>, + class _Alloc = std::allocator<_Key> > + class multiset + { + // concept requirements + typedef typename _Alloc::value_type _Alloc_value_type; + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept) + + public: + // typedefs: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Alloc allocator_type; + + private: + /// @if maint This turns a red-black tree into a [multi]set. @endif + typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type; + + typedef _Rb_tree<key_type, value_type, _Identity<value_type>, + key_compare, _Key_alloc_type> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + typedef typename _Key_alloc_type::pointer pointer; + typedef typename _Key_alloc_type::const_pointer const_pointer; + typedef typename _Key_alloc_type::reference reference; + typedef typename _Key_alloc_type::const_reference const_reference; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 103. set::iterator is required to be modifiable, + // but this allows modification of keys. + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + + // allocation/deallocation + + /** + * @brief Default constructor creates no elements. + */ + multiset() + : _M_t(_Compare(), allocator_type()) { } + + explicit + multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template <class _InputIterator> + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t._M_insert_equal(__first, __last); } + + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template <class _InputIterator> + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t._M_insert_equal(__first, __last); } + + /** + * @brief %Multiset copy constructor. + * @param x A %multiset of identical element and allocator types. + * + * The newly-created %multiset uses a copy of the allocation object used + * by @a x. + */ + multiset(const multiset<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } + + /** + * @brief %Multiset assignment operator. + * @param x A %multiset of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multiset<_Key,_Compare,_Alloc>& + operator=(const multiset<_Key,_Compare,_Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + /// Returns the comparison object. + key_compare + key_comp() const + { return _M_t.key_comp(); } + /// Returns the comparison object. + value_compare + value_comp() const + { return _M_t.key_comp(); } + /// Returns the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + /** + * Returns a read/write iterator that points to the first element in the + * %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last element in + * the %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rend() const + { return _M_t.rend(); } + + /// Returns true if the %set is empty. + bool + empty() const + { return _M_t.empty(); } + + /// Returns the size of the %set. + size_type + size() const + { return _M_t.size(); } + + /// Returns the maximum size of the %set. + size_type + max_size() const + { return _M_t.max_size(); } + + /** + * @brief Swaps data with another %multiset. + * @param x A %multiset of the same element and allocator types. + * + * This exchanges the elements between two multisets in constant time. + * (It is only swapping a pointer, an integer, and an instance of the @c + * Compare type (which itself is often stateless and empty), so it should + * be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(multiset<_Key, _Compare, _Alloc>& __x) + { _M_t.swap(__x._M_t); } + + // insert/erase + /** + * @brief Inserts an element into the %multiset. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t._M_insert_equal(__x); } + + /** + * @brief Inserts an element into the %multiset. + * @param position An iterator that serves as a hint as to where the + * element should be inserted. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { return _M_t._M_insert_equal(__position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template <class _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t._M_insert_equal(__first, __last); } + + /** + * @brief Erases an element from a %multiset. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multiset. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multiset. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %multiset. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multiset. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * Erases all elements in a %multiset. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // multiset operations: + + /** + * @brief Finds the number of elements with given key. + * @param x Key of elements to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + //@{ + /** + * @brief Tries to locate an element in a %set. + * @param x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + //@} + + //@{ + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + //@} + + //@{ + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + //@} + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multisets. + */ + std::pair<iterator, iterator> + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template <class _K1, class _C1, class _A1> + friend bool + operator== (const multiset<_K1, _C1, _A1>&, + const multiset<_K1, _C1, _A1>&); + + template <class _K1, class _C1, class _A1> + friend bool + operator< (const multiset<_K1, _C1, _A1>&, + const multiset<_K1, _C1, _A1>&); + }; + + /** + * @brief Multiset equality comparison. + * @param x A %multiset. + * @param y A %multiset of the same type as @a x. + * @return True iff the size and elements of the multisets are equal. + * + * This is an equivalence relation. It is linear in the size of the + * multisets. + * Multisets are considered equivalent if their sizes are equal, and if + * corresponding elements compare equal. + */ + template <class _Key, class _Compare, class _Alloc> + inline bool + operator==(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Multiset ordering relation. + * @param x A %multiset. + * @param y A %multiset of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template <class _Key, class _Compare, class _Alloc> + inline bool + operator<(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Returns !(x == y). + template <class _Key, class _Compare, class _Alloc> + inline bool + operator!=(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + /// Returns y < x. + template <class _Key, class _Compare, class _Alloc> + inline bool + operator>(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Returns !(y < x) + template <class _Key, class _Compare, class _Alloc> + inline bool + operator<=(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + /// Returns !(x < y) + template <class _Key, class _Compare, class _Alloc> + inline bool + operator>=(const multiset<_Key, _Compare, _Alloc>& __x, + const multiset<_Key, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + /// See std::multiset::swap(). + template <class _Key, class _Compare, class _Alloc> + inline void + swap(multiset<_Key, _Compare, _Alloc>& __x, + multiset<_Key, _Compare, _Alloc>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif /* _MULTISET_H */ diff --git a/libstdc++/include/bits/stl_numeric.h b/libstdc++/include/bits/stl_numeric.h new file mode 100644 index 0000000..82bee21 --- /dev/null +++ b/libstdc++/include/bits/stl_numeric.h @@ -0,0 +1,339 @@ +// Numeric functions implementation -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_numeric.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_NUMERIC_H +#define _STL_NUMERIC_H 1 + +#include <debug/debug.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Accumulate values in a range. + * + * Accumulates the values in the range [first,last) using operator+(). The + * initial value is @a init. The values are processed in order. + * + * @param first Start of range. + * @param last End of range. + * @param init Starting value to add other values to. + * @return The final sum. + */ + template<typename _InputIterator, typename _Tp> + _Tp + accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); + + for (; __first != __last; ++__first) + __init = __init + *__first; + return __init; + } + + /** + * @brief Accumulate values in a range with operation. + * + * Accumulates the values in the range [first,last) using the function + * object @a binary_op. The initial value is @a init. The values are + * processed in order. + * + * @param first Start of range. + * @param last End of range. + * @param init Starting value to add other values to. + * @param binary_op Function object to accumulate with. + * @return The final sum. + */ + template<typename _InputIterator, typename _Tp, typename _BinaryOperation> + _Tp + accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, + _BinaryOperation __binary_op) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); + + for (; __first != __last; ++__first) + __init = __binary_op(__init, *__first); + return __init; + } + + /** + * @brief Compute inner product of two ranges. + * + * Starting with an initial value of @a init, multiplies successive + * elements from the two ranges and adds each product into the accumulated + * value using operator+(). The values in the ranges are processed in + * order. + * + * @param first1 Start of range 1. + * @param last1 End of range 1. + * @param first2 Start of range 2. + * @param init Starting value to add other values to. + * @return The final inner product. + */ + template<typename _InputIterator1, typename _InputIterator2, typename _Tp> + _Tp + inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + for (; __first1 != __last1; ++__first1, ++__first2) + __init = __init + (*__first1 * *__first2); + return __init; + } + + /** + * @brief Compute inner product of two ranges. + * + * Starting with an initial value of @a init, applies @a binary_op2 to + * successive elements from the two ranges and accumulates each result into + * the accumulated value using @a binary_op1. The values in the ranges are + * processed in order. + * + * @param first1 Start of range 1. + * @param last1 End of range 1. + * @param first2 Start of range 2. + * @param init Starting value to add other values to. + * @param binary_op1 Function object to accumulate with. + * @param binary_op2 Function object to apply to pairs of input values. + * @return The final inner product. + */ + template<typename _InputIterator1, typename _InputIterator2, typename _Tp, + typename _BinaryOperation1, typename _BinaryOperation2> + _Tp + inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + for (; __first1 != __last1; ++__first1, ++__first2) + __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); + return __init; + } + + /** + * @brief Return list of partial sums + * + * Accumulates the values in the range [first,last) using operator+(). + * As each successive input value is added into the total, that partial sum + * is written to @a result. Therefore, the first value in result is the + * first value of the input, the second value in result is the sum of the + * first and second input values, and so on. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template<typename _InputIterator, typename _OutputIterator> + _OutputIterator + partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __result; + _ValueType __value = *__first; + *__result = __value; + while (++__first != __last) + { + __value = __value + *__first; + *++__result = __value; + } + return ++__result; + } + + /** + * @brief Return list of partial sums + * + * Accumulates the values in the range [first,last) using operator+(). + * As each successive input value is added into the total, that partial sum + * is written to @a result. Therefore, the first value in result is the + * first value of the input, the second value in result is the sum of the + * first and second input values, and so on. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template<typename _InputIterator, typename _OutputIterator, + typename _BinaryOperation> + _OutputIterator + partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __result; + _ValueType __value = *__first; + *__result = __value; + while (++__first != __last) + { + __value = __binary_op(__value, *__first); + *++__result = __value; + } + return ++__result; + } + + /** + * @brief Return differences between adjacent values. + * + * Computes the difference between adjacent values in the range + * [first,last) using operator-() and writes the result to @a result. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template<typename _InputIterator, typename _OutputIterator> + _OutputIterator + adjacent_difference(_InputIterator __first, + _InputIterator __last, _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __result; + _ValueType __value = *__first; + *__result = __value; + while (++__first != __last) + { + _ValueType __tmp = *__first; + *++__result = __tmp - __value; + __value = __tmp; + } + return ++__result; + } + + /** + * @brief Return differences between adjacent values. + * + * Computes the difference between adjacent values in the range + * [first,last) using the function object @a binary_op and writes the + * result to @a result. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template<typename _InputIterator, typename _OutputIterator, + typename _BinaryOperation> + _OutputIterator + adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __result; + _ValueType __value = *__first; + *__result = __value; + while (++__first != __last) + { + _ValueType __tmp = *__first; + *++__result = __binary_op(__tmp, __value); + __value = __tmp; + } + return ++__result; + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _STL_NUMERIC_H */ diff --git a/libstdc++/include/bits/stl_pair.h b/libstdc++/include/bits/stl_pair.h new file mode 100644 index 0000000..b4bb00c --- /dev/null +++ b/libstdc++/include/bits/stl_pair.h @@ -0,0 +1,149 @@ +// Pair implementation -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_pair.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _PAIR_H +#define _PAIR_H 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /// pair holds two objects of arbitrary type. + template<class _T1, class _T2> + struct pair + { + typedef _T1 first_type; ///< @c first_type is the first bound type + typedef _T2 second_type; ///< @c second_type is the second bound type + + _T1 first; ///< @c first is a copy of the first object + _T2 second; ///< @c second is a copy of the second object + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 265. std::pair::pair() effects overly restrictive + /** The default constructor creates @c first and @c second using their + * respective default constructors. */ + pair() + : first(), second() { } + + /** Two objects may be passed to a @c pair constructor to be copied. */ + pair(const _T1& __a, const _T2& __b) + : first(__a), second(__b) { } + + /** There is also a templated copy ctor for the @c pair class itself. */ + template<class _U1, class _U2> + pair(const pair<_U1, _U2>& __p) + : first(__p.first), second(__p.second) { } + }; + + /// Two pairs of the same type are equal iff their members are equal. + template<class _T1, class _T2> + inline bool + operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __x.first == __y.first && __x.second == __y.second; } + + /// <http://gcc.gnu.org/onlinedocs/libstdc++/20_util/howto.html#pairlt> + template<class _T1, class _T2> + inline bool + operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __x.first < __y.first + || (!(__y.first < __x.first) && __x.second < __y.second); } + + /// Uses @c operator== to find the result. + template<class _T1, class _T2> + inline bool + operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x == __y); } + + /// Uses @c operator< to find the result. + template<class _T1, class _T2> + inline bool + operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __y < __x; } + + /// Uses @c operator< to find the result. + template<class _T1, class _T2> + inline bool + operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__y < __x); } + + /// Uses @c operator< to find the result. + template<class _T1, class _T2> + inline bool + operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x < __y); } + + /** + * @brief A convenience wrapper for creating a pair from two objects. + * @param x The first object. + * @param y The second object. + * @return A newly-constructed pair<> object of the appropriate type. + * + * The standard requires that the objects be passed by reference-to-const, + * but LWG issue #181 says they should be passed by const value. We follow + * the LWG by default. + */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 181. make_pair() unintended behavior + template<class _T1, class _T2> + inline pair<_T1, _T2> + make_pair(_T1 __x, _T2 __y) + { return pair<_T1, _T2>(__x, __y); } + +_GLIBCXX_END_NAMESPACE + +#endif /* _PAIR_H */ diff --git a/libstdc++/include/bits/stl_queue.h b/libstdc++/include/bits/stl_queue.h new file mode 100644 index 0000000..04e3a7b --- /dev/null +++ b/libstdc++/include/bits/stl_queue.h @@ -0,0 +1,443 @@ +// Queue implementation -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_queue.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _QUEUE_H +#define _QUEUE_H 1 + +#include <bits/concept_check.h> +#include <debug/debug.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief A standard container giving FIFO behavior. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets many of the requirements of a + * <a href="tables.html#65">container</a>, + * but does not define anything to do with iterators. Very few of the + * other standard container interfaces are defined. + * + * This is not a true container, but an @e adaptor. It holds another + * container, and provides a wrapper interface to that container. The + * wrapper is what enforces strict first-in-first-out %queue behavior. + * + * The second template parameter defines the type of the underlying + * sequence/container. It defaults to std::deque, but it can be any type + * that supports @c front, @c back, @c push_back, and @c pop_front, + * such as std::list or an appropriate user-defined type. + * + * Members not found in "normal" containers are @c container_type, + * which is a typedef for the second Sequence parameter, and @c push and + * @c pop, which are standard %queue/FIFO operations. + */ + template<typename _Tp, typename _Sequence = deque<_Tp> > + class queue + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + + template<typename _Tp1, typename _Seq1> + friend bool + operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + template<typename _Tp1, typename _Seq1> + friend bool + operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + /** + * 'c' is the underlying container. Maintainers wondering why + * this isn't uglified as per style guidelines should note that + * this name is specified in the standard, [23.2.3.1]. (Why? + * Presumably for the same reason that it's protected instead + * of private: to allow derivation. But none of the other + * containers allow for derivation. Odd.) + */ + _Sequence c; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + queue(const _Sequence& __c = _Sequence()) : c(__c) {} + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const + { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const + { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %queue. + */ + reference + front() + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %queue. + */ + const_reference + front() const + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * Returns a read/write reference to the data at the last + * element of the %queue. + */ + reference + back() + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %queue. + */ + const_reference + back() const + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * @brief Add data to the end of the %queue. + * @param x Data to be added. + * + * This is a typical %queue operation. The function creates an + * element at the end of the %queue and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) + { c.push_back(__x); } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue by one. + * The time complexity of the operation depends on the underlying + * sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_front(); + } + }; + + + /** + * @brief Queue equality comparison. + * @param x A %queue. + * @param y A %queue of the same type as @a x. + * @return True iff the size and elements of the queues are equal. + * + * This is an equivalence relation. Complexity and semantics depend on the + * underlying sequence type, but the expected rules are: this relation is + * linear in the size of the sequences, and queues are considered equivalent + * if their sequences compare equal. + */ + template<typename _Tp, typename _Seq> + inline bool + operator==(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return __x.c == __y.c; } + + /** + * @brief Queue ordering relation. + * @param x A %queue. + * @param y A %queue of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the + * determination. + */ + template<typename _Tp, typename _Seq> + inline bool + operator<(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return __x.c < __y.c; } + + /// Based on operator== + template<typename _Tp, typename _Seq> + inline bool + operator!=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return !(__x == __y); } + + /// Based on operator< + template<typename _Tp, typename _Seq> + inline bool + operator>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return __y < __x; } + + /// Based on operator< + template<typename _Tp, typename _Seq> + inline bool + operator<=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return !(__y < __x); } + + /// Based on operator< + template<typename _Tp, typename _Seq> + inline bool + operator>=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) + { return !(__x < __y); } + + /** + * @brief A standard container automatically sorting its contents. + * + * @ingroup Containers + * @ingroup Sequences + * + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces priority-based sorting + * and %queue behavior. Very few of the standard container/sequence + * interface requirements are met (e.g., iterators). + * + * The second template parameter defines the type of the underlying + * sequence/container. It defaults to std::vector, but it can be + * any type that supports @c front(), @c push_back, @c pop_back, + * and random-access iterators, such as std::deque or an + * appropriate user-defined type. + * + * The third template parameter supplies the means of making + * priority comparisons. It defaults to @c less<value_type> but + * can be anything defining a strict weak ordering. + * + * Members not found in "normal" containers are @c container_type, + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %queue operations. + * + * @note No equality/comparison operators are provided for + * %priority_queue. + * + * @note Sorting of the elements takes place as they are added to, + * and removed from, the %priority_queue using the + * %priority_queue's member functions. If you access the elements + * by other means, and change their data such that the sorting + * order would be different, the %priority_queue will not re-sort + * the elements for you. (How could it know to do so?) + */ + template<typename _Tp, typename _Sequence = vector<_Tp>, + typename _Compare = less<typename _Sequence::value_type> > + class priority_queue + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _SequenceConcept) + __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + __glibcxx_class_requires4(_Compare, bool, _Tp, _Tp, + _BinaryFunctionConcept) + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on these names. + _Sequence c; + _Compare comp; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + priority_queue(const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { std::make_heap(c.begin(), c.end(), comp); } + + /** + * @brief Builds a %queue from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param x A comparison functor describing a strict weak ordering. + * @param s An initial sequence with which to start. + * + * Begins by copying @a s, inserting a copy of the elements + * from @a [first,last) into the copy of @a s, then ordering + * the copy according to @a x. + * + * For more information on function objects, see the + * documentation on @link s20_3_1_base functor base + * classes@endlink. + */ + template<typename _InputIterator> + priority_queue(_InputIterator __first, _InputIterator __last, + const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { + __glibcxx_requires_valid_range(__first, __last); + c.insert(c.end(), __first, __last); + std::make_heap(c.begin(), c.end(), comp); + } + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const + { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const + { return c.size(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %queue. + */ + const_reference + top() const + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * @brief Add data to the %queue. + * @param x Data to be added. + * + * This is a typical %queue operation. + * The time complexity of the operation depends on the underlying + * sequence. + */ + void + push(const value_type& __x) + { + c.push_back(__x); + std::push_heap(c.begin(), c.end(), comp); + } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + std::pop_heap(c.begin(), c.end(), comp); + c.pop_back(); + } + }; + + // No equality/comparison operators are provided for priority_queue. + +_GLIBCXX_END_NAMESPACE + +#endif /* _QUEUE_H */ diff --git a/libstdc++/include/bits/stl_raw_storage_iter.h b/libstdc++/include/bits/stl_raw_storage_iter.h new file mode 100644 index 0000000..615da28 --- /dev/null +++ b/libstdc++/include/bits/stl_raw_storage_iter.h @@ -0,0 +1,110 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_raw_storage_iter.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_RAW_STORAGE_ITERATOR_H +#define _STL_RAW_STORAGE_ITERATOR_H 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * This iterator class lets algorithms store their results into + * uninitialized memory. + */ + template <class _ForwardIterator, class _Tp> + class raw_storage_iterator + : public iterator<output_iterator_tag, void, void, void, void> + { + protected: + _ForwardIterator _M_iter; + + public: + explicit + raw_storage_iterator(_ForwardIterator __x) + : _M_iter(__x) {} + + raw_storage_iterator& + operator*() { return *this; } + + raw_storage_iterator& + operator=(const _Tp& __element) + { + std::_Construct(&*_M_iter, __element); + return *this; + } + + raw_storage_iterator<_ForwardIterator, _Tp>& + operator++() + { + ++_M_iter; + return *this; + } + + raw_storage_iterator<_ForwardIterator, _Tp> + operator++(int) + { + raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; + ++_M_iter; + return __tmp; + } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/stl_relops.h b/libstdc++/include/bits/stl_relops.h new file mode 100644 index 0000000..11fc30d --- /dev/null +++ b/libstdc++/include/bits/stl_relops.h @@ -0,0 +1,138 @@ +// std::rel_ops implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1996,1997 + * Silicon Graphics + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file stl_relops.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * @if maint + * Inclusion of this file has been removed from + * all of the other STL headers for safety reasons, except std_utility.h. + * For more information, see the thread of about twenty messages starting + * with http://gcc.gnu.org/ml/libstdc++/2001-01/msg00223.html , or the + * FAQ at http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#4_4 . + * + * Short summary: the rel_ops operators should be avoided for the present. + * @endif + */ + +#ifndef _STL_RELOPS_H +#define _STL_RELOPS_H 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + namespace rel_ops + { + /** @namespace std::rel_ops + * @brief The generated relational operators are sequestered here. + */ + + /** + * @brief Defines @c != for arbitrary types, in terms of @c ==. + * @param x A thing. + * @param y Another thing. + * @return x != y + * + * This function uses @c == to determine its result. + */ + template <class _Tp> + inline bool + operator!=(const _Tp& __x, const _Tp& __y) + { return !(__x == __y); } + + /** + * @brief Defines @c > for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x > y + * + * This function uses @c < to determine its result. + */ + template <class _Tp> + inline bool + operator>(const _Tp& __x, const _Tp& __y) + { return __y < __x; } + + /** + * @brief Defines @c <= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x <= y + * + * This function uses @c < to determine its result. + */ + template <class _Tp> + inline bool + operator<=(const _Tp& __x, const _Tp& __y) + { return !(__y < __x); } + + /** + * @brief Defines @c >= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x >= y + * + * This function uses @c < to determine its result. + */ + template <class _Tp> + inline bool + operator>=(const _Tp& __x, const _Tp& __y) + { return !(__x < __y); } + + } // namespace rel_ops + +_GLIBCXX_END_NAMESPACE + +#endif /* _STL_RELOPS_H */ diff --git a/libstdc++/include/bits/stl_set.h b/libstdc++/include/bits/stl_set.h new file mode 100644 index 0000000..b61106a --- /dev/null +++ b/libstdc++/include/bits/stl_set.h @@ -0,0 +1,578 @@ +// Set implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_set.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _SET_H +#define _SET_H 1 + +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + /** + * @brief A standard container made up of unique keys, which can be + * retrieved in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and an + * <a href="tables.html#69">associative container</a> (using unique keys). + * + * Sets support bidirectional iterators. + * + * @param Key Type of key objects. + * @param Compare Comparison function object type, defaults to less<Key>. + * @param Alloc Allocator type, defaults to allocator<Key>. + * + * @if maint + * The private tree data is declared exactly the same way for set and + * multiset; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template<class _Key, class _Compare = std::less<_Key>, + class _Alloc = std::allocator<_Key> > + class set + { + // concept requirements + typedef typename _Alloc::value_type _Alloc_value_type; + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept) + + public: + // typedefs: + //@{ + /// Public typedefs. + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Alloc allocator_type; + //@} + + private: + typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type; + + typedef _Rb_tree<key_type, value_type, _Identity<value_type>, + key_compare, _Key_alloc_type> _Rep_type; + _Rep_type _M_t; // red-black tree representing set + + public: + //@{ + /// Iterator-related typedefs. + typedef typename _Key_alloc_type::pointer pointer; + typedef typename _Key_alloc_type::const_pointer const_pointer; + typedef typename _Key_alloc_type::reference reference; + typedef typename _Key_alloc_type::const_reference const_reference; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 103. set::iterator is required to be modifiable, + // but this allows modification of keys. + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + //@} + + // allocation/deallocation + /// Default constructor creates no elements. + set() + : _M_t(_Compare(), allocator_type()) {} + + /** + * @brief Default constructor creates no elements. + * + * @param comp Comparator to use. + * @param a Allocator to use. + */ + explicit + set(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + + /** + * @brief Builds a %set from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %set consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template<class _InputIterator> + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t._M_insert_unique(__first, __last); } + + /** + * @brief Builds a %set from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %set consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template<class _InputIterator> + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t._M_insert_unique(__first, __last); } + + /** + * @brief Set copy constructor. + * @param x A %set of identical element and allocator types. + * + * The newly-created %set uses a copy of the allocation object used + * by @a x. + */ + set(const set<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Set assignment operator. + * @param x A %set of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + set<_Key,_Compare,_Alloc>& + operator=(const set<_Key, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + /// Returns the comparison object with which the %set was constructed. + key_compare + key_comp() const + { return _M_t.key_comp(); } + /// Returns the comparison object with which the %set was constructed. + value_compare + value_comp() const + { return _M_t.key_comp(); } + /// Returns the allocator object with which the %set was constructed. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + /** + * Returns a read/write iterator that points to the first element in the + * %set. Iteration is done in ascending order according to the keys. + */ + iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last element in + * the %set. Iteration is done in ascending order according to the keys. + */ + iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %set. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() const + { return _M_t.rend(); } + + /// Returns true if the %set is empty. + bool + empty() const + { return _M_t.empty(); } + + /// Returns the size of the %set. + size_type + size() const + { return _M_t.size(); } + + /// Returns the maximum size of the %set. + size_type + max_size() const + { return _M_t.max_size(); } + + /** + * @brief Swaps data with another %set. + * @param x A %set of the same element and allocator types. + * + * This exchanges the elements between two sets in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(set<_Key,_Compare,_Alloc>& __x) + { _M_t.swap(__x._M_t); } + + // insert/erase + /** + * @brief Attempts to insert an element into the %set. + * @param x Element to be inserted. + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted element, and the second is a bool + * that is true if the element was actually inserted. + * + * This function attempts to insert an element into the %set. A %set + * relies on unique keys and thus an element is only inserted if it is + * not already present in the %set. + * + * Insertion requires logarithmic time. + */ + std::pair<iterator,bool> + insert(const value_type& __x) + { + std::pair<typename _Rep_type::iterator, bool> __p = + _M_t._M_insert_unique(__x); + return std::pair<iterator, bool>(__p.first, __p.second); + } + + /** + * @brief Attempts to insert an element into the %set. + * @param position An iterator that serves as a hint as to where the + * element should be inserted. + * @param x Element to be inserted. + * @return An iterator that points to the element with key of @a x (may + * or may not be the element passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument insert() + * does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { return _M_t._M_insert_unique(__position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template<class _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t._M_insert_unique(__first, __last); } + + /** + * @brief Erases an element from a %set. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %set. Note that this function only erases the element, and + * that if the element is itself a pointer, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * a %set. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %set. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %set. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * Erases all elements in a %set. Note that this function only erases + * the elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // set operations: + + /** + * @brief Finds the number of elements. + * @param x Element to located. + * @return Number of elements with specified key. + * + * This function only makes sense for multisets; for set the result will + * either be 0 (not present) or 1 (present). + */ + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + //@{ + /** + * @brief Tries to locate an element in a %set. + * @param x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + //@} + + //@{ + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + //@} + + //@{ + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + //@} + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multisets. + */ + std::pair<iterator, iterator> + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + //@} + + template<class _K1, class _C1, class _A1> + friend bool + operator== (const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); + + template<class _K1, class _C1, class _A1> + friend bool + operator< (const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); + }; + + + /** + * @brief Set equality comparison. + * @param x A %set. + * @param y A %set of the same type as @a x. + * @return True iff the size and elements of the sets are equal. + * + * This is an equivalence relation. It is linear in the size of the sets. + * Sets are considered equivalent if their sizes are equal, and if + * corresponding elements compare equal. + */ + template<class _Key, class _Compare, class _Alloc> + inline bool + operator==(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Set ordering relation. + * @param x A %set. + * @param y A %set of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template<class _Key, class _Compare, class _Alloc> + inline bool + operator<(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Returns !(x == y). + template<class _Key, class _Compare, class _Alloc> + inline bool + operator!=(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + /// Returns y < x. + template<class _Key, class _Compare, class _Alloc> + inline bool + operator>(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return __y < __x; } + + /// Returns !(y < x) + template<class _Key, class _Compare, class _Alloc> + inline bool + operator<=(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + /// Returns !(x < y) + template<class _Key, class _Compare, class _Alloc> + inline bool + operator>=(const set<_Key, _Compare, _Alloc>& __x, + const set<_Key, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + /// See std::set::swap(). + template<class _Key, class _Compare, class _Alloc> + inline void + swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif /* _SET_H */ diff --git a/libstdc++/include/bits/stl_stack.h b/libstdc++/include/bits/stl_stack.h new file mode 100644 index 0000000..f5b41fa --- /dev/null +++ b/libstdc++/include/bits/stl_stack.h @@ -0,0 +1,261 @@ +// Stack implementation -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_stack.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STACK_H +#define _STACK_H 1 + +#include <bits/concept_check.h> +#include <debug/debug.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief A standard container giving FILO behavior. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets many of the requirements of a + * <a href="tables.html#65">container</a>, + * but does not define anything to do with iterators. Very few of the + * other standard container interfaces are defined. + * + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces strict + * first-in-last-out %stack behavior. + * + * The second template parameter defines the type of the underlying + * sequence/container. It defaults to std::deque, but it can be + * any type that supports @c back, @c push_back, and @c pop_front, + * such as std::list, std::vector, or an appropriate user-defined + * type. + * + * Members not found in "normal" containers are @c container_type, + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %stack/FILO + * operations. + */ + template<typename _Tp, typename _Sequence = deque<_Tp> > + class stack + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + + template<typename _Tp1, typename _Seq1> + friend bool + operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); + + template<typename _Tp1, typename _Seq1> + friend bool + operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on this name. + _Sequence c; + + public: + // XXX removed old def ctor, added def arg to this one to match 14882 + /** + * @brief Default constructor creates no elements. + */ + explicit + stack(const _Sequence& __c = _Sequence()) + : c(__c) { } + + /** + * Returns true if the %stack is empty. + */ + bool + empty() const + { return c.empty(); } + + /** Returns the number of elements in the %stack. */ + size_type + size() const + { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %stack. + */ + reference + top() + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %stack. + */ + const_reference + top() const + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * @brief Add data to the top of the %stack. + * @param x Data to be added. + * + * This is a typical %stack operation. The function creates an + * element at the top of the %stack and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) + { c.push_back(__x); } + + /** + * @brief Removes first element. + * + * This is a typical %stack operation. It shrinks the %stack + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_back(); + } + }; + + /** + * @brief Stack equality comparison. + * @param x A %stack. + * @param y A %stack of the same type as @a x. + * @return True iff the size and elements of the stacks are equal. + * + * This is an equivalence relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, and + * stacks are considered equivalent if their sequences compare + * equal. + */ + template<typename _Tp, typename _Seq> + inline bool + operator==(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return __x.c == __y.c; } + + /** + * @brief Stack ordering relation. + * @param x A %stack. + * @param y A %stack of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the + * determination. + */ + template<typename _Tp, typename _Seq> + inline bool + operator<(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return __x.c < __y.c; } + + /// Based on operator== + template<typename _Tp, typename _Seq> + inline bool + operator!=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return !(__x == __y); } + + /// Based on operator< + template<typename _Tp, typename _Seq> + inline bool + operator>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return __y < __x; } + + /// Based on operator< + template<typename _Tp, typename _Seq> + inline bool + operator<=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return !(__y < __x); } + + /// Based on operator< + template<typename _Tp, typename _Seq> + inline bool + operator>=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return !(__x < __y); } + +_GLIBCXX_END_NAMESPACE + +#endif /* _STACK_H */ diff --git a/libstdc++/include/bits/stl_tempbuf.h b/libstdc++/include/bits/stl_tempbuf.h new file mode 100644 index 0000000..fbe24e7 --- /dev/null +++ b/libstdc++/include/bits/stl_tempbuf.h @@ -0,0 +1,172 @@ +// Temporary buffer implementation -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_tempbuf.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TEMPBUF_H +#define _TEMPBUF_H 1 + +#include <memory> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @if maint + * This class is used in two places: stl_algo.h and ext/memory, + * where it is wrapped as the temporary_buffer class. See + * temporary_buffer docs for more notes. + * @endif + */ + template<typename _ForwardIterator, typename _Tp> + class _Temporary_buffer + { + // concept requirements + __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept) + + public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef pointer iterator; + typedef ptrdiff_t size_type; + + protected: + size_type _M_original_len; + size_type _M_len; + pointer _M_buffer; + + void + _M_initialize_buffer(const _Tp&, __true_type) { } + + void + _M_initialize_buffer(const _Tp& __val, __false_type) + { std::uninitialized_fill_n(_M_buffer, _M_len, __val); } + + public: + /// As per Table mumble. + size_type + size() const + { return _M_len; } + + /// Returns the size requested by the constructor; may be >size(). + size_type + requested_size() const + { return _M_original_len; } + + /// As per Table mumble. + iterator + begin() + { return _M_buffer; } + + /// As per Table mumble. + iterator + end() + { return _M_buffer + _M_len; } + + /** + * Constructs a temporary buffer of a size somewhere between + * zero and the size of the given range. + */ + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last); + + ~_Temporary_buffer() + { + std::_Destroy(_M_buffer, _M_buffer + _M_len); + std::return_temporary_buffer(_M_buffer); + } + + private: + // Disable copy constructor and assignment operator. + _Temporary_buffer(const _Temporary_buffer&); + + void + operator=(const _Temporary_buffer&); + }; + + + template<typename _ForwardIterator, typename _Tp> + _Temporary_buffer<_ForwardIterator, _Tp>:: + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _M_original_len(std::distance(__first, __last)), + _M_len(0), _M_buffer(0) + { + // Workaround for a __type_traits bug in the pre-7.3 compiler. + typedef typename std::__is_scalar<_Tp>::__type _Trivial; + + try + { + pair<pointer, size_type> __p(get_temporary_buffer< + value_type>(_M_original_len)); + _M_buffer = __p.first; + _M_len = __p.second; + if (_M_len > 0) + _M_initialize_buffer(*__first, _Trivial()); + } + catch(...) + { + std::return_temporary_buffer(_M_buffer); + _M_buffer = 0; + _M_len = 0; + __throw_exception_again; + } + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _TEMPBUF_H */ + diff --git a/libstdc++/include/bits/stl_tree.h b/libstdc++/include/bits/stl_tree.h new file mode 100644 index 0000000..22e132f --- /dev/null +++ b/libstdc++/include/bits/stl_tree.h @@ -0,0 +1,1557 @@ +// RB tree implementation -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + */ + +/** @file stl_tree.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TREE_H +#define _TREE_H 1 + +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_construct.h> +#include <bits/stl_function.h> +#include <bits/cpp_type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Red-black tree class, designed for use in implementing STL + // associative containers (set, multiset, map, and multimap). The + // insertion and deletion algorithms are based on those in Cormen, + // Leiserson, and Rivest, Introduction to Algorithms (MIT Press, + // 1990), except that + // + // (1) the header cell is maintained with links not only to the root + // but also to the leftmost node of the tree, to enable constant + // time begin(), and to the rightmost node of the tree, to enable + // linear time performance when used with the generic set algorithms + // (set_union, etc.) + // + // (2) when a node being deleted has two children its successor node + // is relinked into its place, rather than copied, so that the only + // iterators invalidated are those referring to the deleted node. + + enum _Rb_tree_color { _S_red = false, _S_black = true }; + + struct _Rb_tree_node_base + { + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + + _Rb_tree_color _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; + + static _Base_ptr + _S_minimum(_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Base_ptr + _S_maximum(_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } + }; + + template<typename _Val> + struct _Rb_tree_node : public _Rb_tree_node_base + { + typedef _Rb_tree_node<_Val>* _Link_type; + _Val _M_value_field; + }; + + _Rb_tree_node_base* + _Rb_tree_increment(_Rb_tree_node_base* __x); + + const _Rb_tree_node_base* + _Rb_tree_increment(const _Rb_tree_node_base* __x); + + _Rb_tree_node_base* + _Rb_tree_decrement(_Rb_tree_node_base* __x); + + const _Rb_tree_node_base* + _Rb_tree_decrement(const _Rb_tree_node_base* __x); + + template<typename _Tp> + struct _Rb_tree_iterator + { + typedef _Tp value_type; + typedef _Tp& reference; + typedef _Tp* pointer; + + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + + typedef _Rb_tree_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + typedef _Rb_tree_node<_Tp>* _Link_type; + + _Rb_tree_iterator() + : _M_node() { } + + explicit + _Rb_tree_iterator(_Link_type __x) + : _M_node(__x) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; + } + + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; + }; + + template<typename _Tp> + struct _Rb_tree_const_iterator + { + typedef _Tp value_type; + typedef const _Tp& reference; + typedef const _Tp* pointer; + + typedef _Rb_tree_iterator<_Tp> iterator; + + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + + typedef _Rb_tree_const_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; + typedef const _Rb_tree_node<_Tp>* _Link_type; + + _Rb_tree_const_iterator() + : _M_node() { } + + explicit + _Rb_tree_const_iterator(_Link_type __x) + : _M_node(__x) { } + + _Rb_tree_const_iterator(const iterator& __it) + : _M_node(__it._M_node) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; + } + + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; + }; + + template<typename _Val> + inline bool + operator==(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template<typename _Val> + inline bool + operator!=(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + void + _Rb_tree_rotate_left(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); + + void + _Rb_tree_rotate_right(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); + + void + _Rb_tree_insert_and_rebalance(const bool __insert_left, + _Rb_tree_node_base* __x, + _Rb_tree_node_base* __p, + _Rb_tree_node_base& __header); + + _Rb_tree_node_base* + _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, + _Rb_tree_node_base& __header); + + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc = allocator<_Val> > + class _Rb_tree + { + typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other + _Node_allocator; + + protected: + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + typedef _Rb_tree_node<_Val> _Rb_tree_node; + + public: + typedef _Key key_type; + typedef _Val value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Rb_tree_node* _Link_type; + typedef const _Rb_tree_node* _Const_Link_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + _Node_allocator& + _M_get_Node_allocator() + { return *static_cast<_Node_allocator*>(&this->_M_impl); } + + const _Node_allocator& + _M_get_Node_allocator() const + { return *static_cast<const _Node_allocator*>(&this->_M_impl); } + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Node_allocator()); } + + protected: + _Rb_tree_node* + _M_get_node() + { return _M_impl._Node_allocator::allocate(1); } + + void + _M_put_node(_Rb_tree_node* __p) + { _M_impl._Node_allocator::deallocate(__p, 1); } + + _Link_type + _M_create_node(const value_type& __x) + { + _Link_type __tmp = _M_get_node(); + try + { get_allocator().construct(&__tmp->_M_value_field, __x); } + catch(...) + { + _M_put_node(__tmp); + __throw_exception_again; + } + return __tmp; + } + + _Link_type + _M_clone_node(_Const_Link_type __x) + { + _Link_type __tmp = _M_create_node(__x->_M_value_field); + __tmp->_M_color = __x->_M_color; + __tmp->_M_left = 0; + __tmp->_M_right = 0; + return __tmp; + } + + void + _M_destroy_node(_Link_type __p) + { + get_allocator().destroy(&__p->_M_value_field); + _M_put_node(__p); + } + + protected: + template<typename _Key_compare, + bool _Is_pod_comparator = std::__is_pod<_Key_compare>::__value> + struct _Rb_tree_impl : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; // Keeps track of size of tree. + + _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(), + const _Key_compare& __comp = _Key_compare()) + : _Node_allocator(__a), _M_key_compare(__comp), _M_header(), + _M_node_count(0) + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; + + // Specialization for _Comparison types that are not capable of + // being base classes / super classes. + template<typename _Key_compare> + struct _Rb_tree_impl<_Key_compare, true> : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; // Keeps track of size of tree. + + _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(), + const _Key_compare& __comp = _Key_compare()) + : _Node_allocator(__a), _M_key_compare(__comp), _M_header(), + _M_node_count(0) + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; + + _Rb_tree_impl<_Compare> _M_impl; + + protected: + _Base_ptr& + _M_root() + { return this->_M_impl._M_header._M_parent; } + + _Const_Base_ptr + _M_root() const + { return this->_M_impl._M_header._M_parent; } + + _Base_ptr& + _M_leftmost() + { return this->_M_impl._M_header._M_left; } + + _Const_Base_ptr + _M_leftmost() const + { return this->_M_impl._M_header._M_left; } + + _Base_ptr& + _M_rightmost() + { return this->_M_impl._M_header._M_right; } + + _Const_Base_ptr + _M_rightmost() const + { return this->_M_impl._M_header._M_right; } + + _Link_type + _M_begin() + { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } + + _Const_Link_type + _M_begin() const + { + return static_cast<_Const_Link_type> + (this->_M_impl._M_header._M_parent); + } + + _Link_type + _M_end() + { return static_cast<_Link_type>(&this->_M_impl._M_header); } + + _Const_Link_type + _M_end() const + { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } + + static const_reference + _S_value(_Const_Link_type __x) + { return __x->_M_value_field; } + + static const _Key& + _S_key(_Const_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } + + static _Link_type + _S_left(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_left); } + + static _Const_Link_type + _S_left(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_left); } + + static _Link_type + _S_right(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_right); } + + static _Const_Link_type + _S_right(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_right); } + + static const_reference + _S_value(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x)->_M_value_field; } + + static const _Key& + _S_key(_Const_Base_ptr __x) + { return _KeyOfValue()(_S_value(__x)); } + + static _Base_ptr + _S_minimum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Base_ptr + _S_maximum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } + + public: + typedef _Rb_tree_iterator<value_type> iterator; + typedef _Rb_tree_const_iterator<value_type> const_iterator; + + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + private: + iterator + _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 233. Insertion hints in associative containers. + iterator + _M_insert_lower(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + + const_iterator + _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __y, + const value_type& __v); + + _Link_type + _M_copy(_Const_Link_type __x, _Link_type __p); + + void + _M_erase(_Link_type __x); + + public: + // allocation/deallocation + _Rb_tree() + { } + + _Rb_tree(const _Compare& __comp) + : _M_impl(allocator_type(), __comp) + { } + + _Rb_tree(const _Compare& __comp, const allocator_type& __a) + : _M_impl(__a, __comp) + { } + + _Rb_tree(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x) + : _M_impl(__x._M_get_Node_allocator(), __x._M_impl._M_key_compare) + { + if (__x._M_root() != 0) + { + _M_root() = _M_copy(__x._M_begin(), _M_end()); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; + } + } + + ~_Rb_tree() + { _M_erase(_M_begin()); } + + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& + operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x); + + // Accessors. + _Compare + key_comp() const + { return _M_impl._M_key_compare; } + + iterator + begin() + { + return iterator(static_cast<_Link_type> + (this->_M_impl._M_header._M_left)); + } + + const_iterator + begin() const + { + return const_iterator(static_cast<_Const_Link_type> + (this->_M_impl._M_header._M_left)); + } + + iterator + end() + { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); } + + const_iterator + end() const + { + return const_iterator(static_cast<_Const_Link_type> + (&this->_M_impl._M_header)); + } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + bool + empty() const + { return _M_impl._M_node_count == 0; } + + size_type + size() const + { return _M_impl._M_node_count; } + + size_type + max_size() const + { return get_allocator().max_size(); } + + void + swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t); + + // Insert/erase. + pair<iterator, bool> + _M_insert_unique(const value_type& __x); + + iterator + _M_insert_equal(const value_type& __x); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 233. Insertion hints in associative containers. + iterator + _M_insert_equal_lower(const value_type& __x); + + iterator + _M_insert_unique(iterator __position, const value_type& __x); + + const_iterator + _M_insert_unique(const_iterator __position, const value_type& __x); + + iterator + _M_insert_equal(iterator __position, const value_type& __x); + + const_iterator + _M_insert_equal(const_iterator __position, const value_type& __x); + + template<typename _InputIterator> + void + _M_insert_unique(_InputIterator __first, _InputIterator __last); + + template<typename _InputIterator> + void + _M_insert_equal(_InputIterator __first, _InputIterator __last); + + void + erase(iterator __position); + + void + erase(const_iterator __position); + + size_type + erase(const key_type& __x); + + void + erase(iterator __first, iterator __last); + + void + erase(const_iterator __first, const_iterator __last); + + void + erase(const key_type* __first, const key_type* __last); + + void + clear() + { + _M_erase(_M_begin()); + _M_leftmost() = _M_end(); + _M_root() = 0; + _M_rightmost() = _M_end(); + _M_impl._M_node_count = 0; + } + + // Set operations. + iterator + find(const key_type& __x); + + const_iterator + find(const key_type& __x) const; + + size_type + count(const key_type& __x) const; + + iterator + lower_bound(const key_type& __x); + + const_iterator + lower_bound(const key_type& __x) const; + + iterator + upper_bound(const key_type& __x); + + const_iterator + upper_bound(const key_type& __x) const; + + pair<iterator,iterator> + equal_range(const key_type& __x); + + pair<const_iterator, const_iterator> + equal_range(const key_type& __x) const; + + // Debugging. + bool + __rb_verify() const; + }; + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline bool + operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { + return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline bool + operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { + return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline bool + operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { return !(__x == __y); } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline bool + operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { return __y < __x; } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline bool + operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { return !(__y < __x); } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline bool + operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { return !(__x < __y); } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline void + swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) + { __x.swap(__y); } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x) + { + if (this != &__x) + { + // Note that _Key may be a constant type. + clear(); + _M_impl._M_key_compare = __x._M_impl._M_key_compare; + if (__x._M_root() != 0) + { + _M_root() = _M_copy(__x._M_begin(), _M_end()); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; + } + } + return *this; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert(_Base_ptr __x, _Base_ptr __p, const _Val& __v) + { + bool __insert_left = (__x != 0 || __p == _M_end() + || _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__p))); + + _Link_type __z = _M_create_node(__v); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return iterator(__z); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_lower(_Base_ptr __x, _Base_ptr __p, const _Val& __v) + { + bool __insert_left = (__x != 0 || __p == _M_end() + || !_M_impl._M_key_compare(_S_key(__p), + _KeyOfValue()(__v))); + + _Link_type __z = _M_create_node(__v); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return iterator(__z); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v) + { + bool __insert_left = (__x != 0 || __p == _M_end() + || _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__p))); + + _Link_type __z = _M_create_node(__v); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, + const_cast<_Base_ptr>(__p), + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return const_iterator(__z); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_equal(const _Val& __v) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) + { + __y = __x; + __x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert(__x, __y, __v); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_equal_lower(const _Val& __v) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) + { + __y = __x; + __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert_lower(__x, __y, __v); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t) + { + if (_M_root() == 0) + { + if (__t._M_root() != 0) + { + _M_root() = __t._M_root(); + _M_leftmost() = __t._M_leftmost(); + _M_rightmost() = __t._M_rightmost(); + _M_root()->_M_parent = _M_end(); + + __t._M_root() = 0; + __t._M_leftmost() = __t._M_end(); + __t._M_rightmost() = __t._M_end(); + } + } + else if (__t._M_root() == 0) + { + __t._M_root() = _M_root(); + __t._M_leftmost() = _M_leftmost(); + __t._M_rightmost() = _M_rightmost(); + __t._M_root()->_M_parent = __t._M_end(); + + _M_root() = 0; + _M_leftmost() = _M_end(); + _M_rightmost() = _M_end(); + } + else + { + std::swap(_M_root(),__t._M_root()); + std::swap(_M_leftmost(),__t._M_leftmost()); + std::swap(_M_rightmost(),__t._M_rightmost()); + + _M_root()->_M_parent = _M_end(); + __t._M_root()->_M_parent = __t._M_end(); + } + // No need to swap header's color as it does not change. + std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count); + std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<_Node_allocator>:: + _S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator()); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator, bool> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_unique(const _Val& __v) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + bool __comp = true; + while (__x != 0) + { + __y = __x; + __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __x = __comp ? _S_left(__x) : _S_right(__x); + } + iterator __j = iterator(__y); + if (__comp) + if (__j == begin()) + return pair<iterator,bool>(_M_insert(__x, __y, __v), true); + else + --__j; + if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair<iterator, bool>(_M_insert(__x, __y, __v), true); + return pair<iterator, bool>(__j, false); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_unique(iterator __position, const _Val& __v) + { + // end() + if (__position._M_node == _M_end()) + { + if (size() > 0 + && _M_impl._M_key_compare(_S_key(_M_rightmost()), + _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return _M_insert_unique(__v).first; + } + else if (_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) + { + // First, try before... + iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert(_M_leftmost(), _M_leftmost(), __v); + else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, + __position._M_node, __v); + } + else + return _M_insert_unique(__v).first; + } + else if (_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + // ... then try after. + iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert(0, _M_rightmost(), __v); + else if (_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key((++__after)._M_node))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert(0, __position._M_node, __v); + else + return _M_insert(__after._M_node, __after._M_node, __v); + } + else + return _M_insert_unique(__v).first; + } + else + return __position; // Equivalent keys. + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_unique(const_iterator __position, const _Val& __v) + { + // end() + if (__position._M_node == _M_end()) + { + if (size() > 0 + && _M_impl._M_key_compare(_S_key(_M_rightmost()), + _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return const_iterator(_M_insert_unique(__v).first); + } + else if (_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) + { + // First, try before... + const_iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert(_M_leftmost(), _M_leftmost(), __v); + else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, + __position._M_node, __v); + } + else + return const_iterator(_M_insert_unique(__v).first); + } + else if (_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + // ... then try after. + const_iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert(0, _M_rightmost(), __v); + else if (_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key((++__after)._M_node))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert(0, __position._M_node, __v); + else + return _M_insert(__after._M_node, __after._M_node, __v); + } + else + return const_iterator(_M_insert_unique(__v).first); + } + else + return __position; // Equivalent keys. + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_equal(iterator __position, const _Val& __v) + { + // end() + if (__position._M_node == _M_end()) + { + if (size() > 0 + && !_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return _M_insert_equal(__v); + } + else if (!_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + // First, try before... + iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert(_M_leftmost(), _M_leftmost(), __v); + else if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key((--__before)._M_node))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, + __position._M_node, __v); + } + else + return _M_insert_equal(__v); + } + else + { + // ... then try after. + iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert(0, _M_rightmost(), __v); + else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert(0, __position._M_node, __v); + else + return _M_insert(__after._M_node, __after._M_node, __v); + } + else + return _M_insert_equal_lower(__v); + } + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_equal(const_iterator __position, const _Val& __v) + { + // end() + if (__position._M_node == _M_end()) + { + if (size() > 0 + && !_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return const_iterator(_M_insert_equal(__v)); + } + else if (!_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + // First, try before... + const_iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert(_M_leftmost(), _M_leftmost(), __v); + else if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key((--__before)._M_node))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, + __position._M_node, __v); + } + else + return const_iterator(_M_insert_equal(__v)); + } + else + { + // ... then try after. + const_iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert(0, _M_rightmost(), __v); + else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert(0, __position._M_node, __v); + else + return _M_insert(__after._M_node, __after._M_node, __v); + } + else + return const_iterator(_M_insert_equal_lower(__v)); + } + } + + template<typename _Key, typename _Val, typename _KoV, + typename _Cmp, typename _Alloc> + template<class _II> + void + _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: + _M_insert_equal(_II __first, _II __last) + { + for (; __first != __last; ++__first) + _M_insert_equal(end(), *__first); + } + + template<typename _Key, typename _Val, typename _KoV, + typename _Cmp, typename _Alloc> + template<class _II> + void + _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: + _M_insert_unique(_II __first, _II __last) + { + for (; __first != __last; ++__first) + _M_insert_unique(end(), *__first); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(iterator __position) + { + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase + (__position._M_node, + this->_M_impl._M_header)); + _M_destroy_node(__y); + --_M_impl._M_node_count; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const_iterator __position) + { + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase + (const_cast<_Base_ptr>(__position._M_node), + this->_M_impl._M_header)); + _M_destroy_node(__y); + --_M_impl._M_node_count; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const _Key& __x) + { + pair<iterator, iterator> __p = equal_range(__x); + const size_type __old_size = size(); + erase(__p.first, __p.second); + return __old_size - size(); + } + + template<typename _Key, typename _Val, typename _KoV, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type + _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: + _M_copy(_Const_Link_type __x, _Link_type __p) + { + // Structural copy. __x and __p must be non-null. + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; + + try + { + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) + { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); + } + } + catch(...) + { + _M_erase(__top); + __throw_exception_again; + } + return __top; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_erase(_Link_type __x) + { + // Erase without rebalancing. + while (__x != 0) + { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + _M_destroy_node(__x); + __x = __y; + } + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(iterator __first, iterator __last) + { + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) + erase(__first++); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const_iterator __first, const_iterator __last) + { + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) + erase(__first++); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const _Key* __first, const _Key* __last) + { + while (__first != __last) + erase(*__first++); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + find(const _Key& __k) + { + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + iterator __j = iterator(__y); + return (__j == end() + || _M_impl._M_key_compare(__k, + _S_key(__j._M_node))) ? end() : __j; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + find(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + { + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + } + const_iterator __j = const_iterator(__y); + return (__j == end() + || _M_impl._M_key_compare(__k, + _S_key(__j._M_node))) ? end() : __j; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + count(const _Key& __k) const + { + pair<const_iterator, const_iterator> __p = equal_range(__k); + const size_type __n = std::distance(__p.first, __p.second); + return __n; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + lower_bound(const _Key& __k) + { + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + lower_bound(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + upper_bound(const _Key& __k) + { + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is greater than __k. + + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + upper_bound(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is greater than __k. + + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + inline + pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator, + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + equal_range(const _Key& __k) + { return pair<iterator, iterator>(lower_bound(__k), upper_bound(__k)); } + + template<typename _Key, typename _Val, typename _KoV, + typename _Compare, typename _Alloc> + inline + pair<typename _Rb_tree<_Key, _Val, _KoV, + _Compare, _Alloc>::const_iterator, + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator> + _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: + equal_range(const _Key& __k) const + { return pair<const_iterator, const_iterator>(lower_bound(__k), + upper_bound(__k)); } + + unsigned int + _Rb_tree_black_count(const _Rb_tree_node_base* __node, + const _Rb_tree_node_base* __root); + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + bool + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const + { + if (_M_impl._M_node_count == 0 || begin() == end()) + return _M_impl._M_node_count == 0 && begin() == end() + && this->_M_impl._M_header._M_left == _M_end() + && this->_M_impl._M_header._M_right == _M_end(); + + unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) + { + _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node); + _Const_Link_type __L = _S_left(__x); + _Const_Link_type __R = _S_right(__x); + + if (__x->_M_color == _S_red) + if ((__L && __L->_M_color == _S_red) + || (__R && __R->_M_color == _S_red)) + return false; + + if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) + return false; + if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) + return false; + + if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) + return false; + } + + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) + return false; + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) + return false; + return true; + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/stl_uninitialized.h b/libstdc++/include/bits/stl_uninitialized.h new file mode 100644 index 0000000..2c947f6 --- /dev/null +++ b/libstdc++/include/bits/stl_uninitialized.h @@ -0,0 +1,392 @@ +// Raw memory manipulators -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_uninitialized.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_UNINITIALIZED_H +#define _STL_UNINITIALIZED_H 1 + +#include <cstring> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // uninitialized_copy + template<typename _InputIterator, typename _ForwardIterator> + inline _ForwardIterator + __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + __true_type) + { return std::copy(__first, __last, __result); } + + template<typename _InputIterator, typename _ForwardIterator> + inline _ForwardIterator + __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + __false_type) + { + _ForwardIterator __cur = __result; + try + { + for (; __first != __last; ++__first, ++__cur) + std::_Construct(&*__cur, *__first); + return __cur; + } + catch(...) + { + std::_Destroy(__result, __cur); + __throw_exception_again; + } + } + + /** + * @brief Copies the range [first,last) into result. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return result + (first - last) + * + * Like copy(), but does not require an initialized output range. + */ + template<typename _InputIterator, typename _ForwardIterator> + inline _ForwardIterator + uninitialized_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; + return std::__uninitialized_copy_aux(__first, __last, __result, + _Is_POD()); + } + + inline char* + uninitialized_copy(const char* __first, const char* __last, char* __result) + { + std::memmove(__result, __first, __last - __first); + return __result + (__last - __first); + } + + inline wchar_t* + uninitialized_copy(const wchar_t* __first, const wchar_t* __last, + wchar_t* __result) + { + std::memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + return __result + (__last - __first); + } + + // Valid if copy construction is equivalent to assignment, and if the + // destructor is trivial. + template<typename _ForwardIterator, typename _Tp> + inline void + __uninitialized_fill_aux(_ForwardIterator __first, + _ForwardIterator __last, + const _Tp& __x, __true_type) + { std::fill(__first, __last, __x); } + + template<typename _ForwardIterator, typename _Tp> + void + __uninitialized_fill_aux(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x, __false_type) + { + _ForwardIterator __cur = __first; + try + { + for (; __cur != __last; ++__cur) + std::_Construct(&*__cur, __x); + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + + /** + * @brief Copies the value x into the range [first,last). + * @param first An input iterator. + * @param last An input iterator. + * @param x The source value. + * @return Nothing. + * + * Like fill(), but does not require an initialized output range. + */ + template<typename _ForwardIterator, typename _Tp> + inline void + uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; + std::__uninitialized_fill_aux(__first, __last, __x, _Is_POD()); + } + + // Valid if copy construction is equivalent to assignment, and if the + // destructor is trivial. + template<typename _ForwardIterator, typename _Size, typename _Tp> + inline void + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, + const _Tp& __x, __true_type) + { std::fill_n(__first, __n, __x); } + + template<typename _ForwardIterator, typename _Size, typename _Tp> + void + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, + const _Tp& __x, __false_type) + { + _ForwardIterator __cur = __first; + try + { + for (; __n > 0; --__n, ++__cur) + std::_Construct(&*__cur, __x); + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + + /** + * @brief Copies the value x into the range [first,first+n). + * @param first An input iterator. + * @param n The number of copies to make. + * @param x The source value. + * @return Nothing. + * + * Like fill_n(), but does not require an initialized output range. + */ + template<typename _ForwardIterator, typename _Size, typename _Tp> + inline void + uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; + std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); + } + + // Extensions: versions of uninitialized_copy, uninitialized_fill, + // and uninitialized_fill_n that take an allocator parameter. + // We dispatch back to the standard versions when we're given the + // default allocator. For nondefault allocators we do not use + // any of the POD optimizations. + + template<typename _InputIterator, typename _ForwardIterator, + typename _Allocator> + _ForwardIterator + __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + _Allocator __alloc) + { + _ForwardIterator __cur = __result; + try + { + for (; __first != __last; ++__first, ++__cur) + __alloc.construct(&*__cur, *__first); + return __cur; + } + catch(...) + { + std::_Destroy(__result, __cur, __alloc); + __throw_exception_again; + } + } + + template<typename _InputIterator, typename _ForwardIterator, typename _Tp> + inline _ForwardIterator + __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + allocator<_Tp>) + { return std::uninitialized_copy(__first, __last, __result); } + + template<typename _ForwardIterator, typename _Tp, typename _Allocator> + void + __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x, _Allocator __alloc) + { + _ForwardIterator __cur = __first; + try + { + for (; __cur != __last; ++__cur) + __alloc.construct(&*__cur, __x); + } + catch(...) + { + std::_Destroy(__first, __cur, __alloc); + __throw_exception_again; + } + } + + template<typename _ForwardIterator, typename _Tp, typename _Tp2> + inline void + __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x, allocator<_Tp2>) + { std::uninitialized_fill(__first, __last, __x); } + + template<typename _ForwardIterator, typename _Size, typename _Tp, + typename _Allocator> + void + __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, + const _Tp& __x, + _Allocator __alloc) + { + _ForwardIterator __cur = __first; + try + { + for (; __n > 0; --__n, ++__cur) + __alloc.construct(&*__cur, __x); + } + catch(...) + { + std::_Destroy(__first, __cur, __alloc); + __throw_exception_again; + } + } + + template<typename _ForwardIterator, typename _Size, typename _Tp, + typename _Tp2> + inline void + __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, + const _Tp& __x, + allocator<_Tp2>) + { std::uninitialized_fill_n(__first, __n, __x); } + + + // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, + // __uninitialized_fill_copy. All of these algorithms take a user- + // supplied allocator, which is used for construction and destruction. + + // __uninitialized_copy_copy + // Copies [first1, last1) into [result, result + (last1 - first1)), and + // copies [first2, last2) into + // [result, result + (last1 - first1) + (last2 - first2)). + + template<typename _InputIterator1, typename _InputIterator2, + typename _ForwardIterator, typename _Allocator> + inline _ForwardIterator + __uninitialized_copy_copy(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _ForwardIterator __result, + _Allocator __alloc) + { + _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, + __result, + __alloc); + try + { + return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); + } + catch(...) + { + std::_Destroy(__result, __mid, __alloc); + __throw_exception_again; + } + } + + // __uninitialized_fill_copy + // Fills [result, mid) with x, and copies [first, last) into + // [mid, mid + (last - first)). + template<typename _ForwardIterator, typename _Tp, typename _InputIterator, + typename _Allocator> + inline _ForwardIterator + __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, + const _Tp& __x, _InputIterator __first, + _InputIterator __last, + _Allocator __alloc) + { + std::__uninitialized_fill_a(__result, __mid, __x, __alloc); + try + { + return std::__uninitialized_copy_a(__first, __last, __mid, __alloc); + } + catch(...) + { + std::_Destroy(__result, __mid, __alloc); + __throw_exception_again; + } + } + + // __uninitialized_copy_fill + // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and + // fills [first2 + (last1 - first1), last2) with x. + template<typename _InputIterator, typename _ForwardIterator, typename _Tp, + typename _Allocator> + inline void + __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, + _ForwardIterator __last2, const _Tp& __x, + _Allocator __alloc) + { + _ForwardIterator __mid2 = std::__uninitialized_copy_a(__first1, __last1, + __first2, + __alloc); + try + { + std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); + } + catch(...) + { + std::_Destroy(__first2, __mid2, __alloc); + __throw_exception_again; + } + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _STL_UNINITIALIZED_H */ diff --git a/libstdc++/include/bits/stl_vector.h b/libstdc++/include/bits/stl_vector.h new file mode 100644 index 0000000..a81c597 --- /dev/null +++ b/libstdc++/include/bits/stl_vector.h @@ -0,0 +1,992 @@ +// Vector implementation -*- C++ -*- + +// Copyright (C) 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_vector.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VECTOR_H +#define _VECTOR_H 1 + +#include <bits/stl_iterator_base_funcs.h> +#include <bits/functexcept.h> +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + /** + * @if maint + * See bits/stl_deque.h's _Deque_base for an explanation. + * @endif + */ + template<typename _Tp, typename _Alloc> + struct _Vector_base + { + typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; + + struct _Vector_impl + : public _Tp_alloc_type + { + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + _Vector_impl(_Tp_alloc_type const& __a) + : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + { } + }; + + public: + typedef _Alloc allocator_type; + + _Tp_alloc_type& + _M_get_Tp_allocator() + { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } + + const _Tp_alloc_type& + _M_get_Tp_allocator() const + { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); } + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Tp_allocator()); } + + _Vector_base(const allocator_type& __a) + : _M_impl(__a) + { } + + _Vector_base(size_t __n, const allocator_type& __a) + : _M_impl(__a) + { + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_finish = this->_M_impl._M_start; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } + + ~_Vector_base() + { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); } + + public: + _Vector_impl _M_impl; + + _Tp* + _M_allocate(size_t __n) + { return _M_impl.allocate(__n); } + + void + _M_deallocate(_Tp* __p, size_t __n) + { + if (__p) + _M_impl.deallocate(__p, __n); + } + }; + + + /** + * @brief A standard container which offers fixed time access to + * individual elements in any order. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and a + * <a href="tables.html#67">sequence</a>, including the + * <a href="tables.html#68">optional sequence requirements</a> with the + * %exception of @c push_front and @c pop_front. + * + * In some terminology a %vector can be described as a dynamic + * C-style array, it offers fast and efficient access to individual + * elements in any order and saves the user from worrying about + * memory and size allocation. Subscripting ( @c [] ) access is + * also provided as with C-style arrays. + */ + template<typename _Tp, typename _Alloc = std::allocator<_Tp> > + class vector : protected _Vector_base<_Tp, _Alloc> + { + // Concept requirements. + typedef typename _Alloc::value_type _Alloc_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) + + typedef _Vector_base<_Tp, _Alloc> _Base; + typedef vector<_Tp, _Alloc> vector_type; + typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; + + public: + typedef _Tp value_type; + typedef typename _Tp_alloc_type::pointer pointer; + typedef typename _Tp_alloc_type::const_pointer const_pointer; + typedef typename _Tp_alloc_type::reference reference; + typedef typename _Tp_alloc_type::const_reference const_reference; + typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator; + typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type> + const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + protected: + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_impl; + using _Base::_M_get_Tp_allocator; + + public: + // [23.2.4.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + vector(const allocator_type& __a = allocator_type()) + : _Base(__a) + { } + + /** + * @brief Create a %vector with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %vector with @a n copies of @a value. + */ + explicit + vector(size_type __n, const value_type& __value = value_type(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { + std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = this->_M_impl._M_start + __n; + } + + /** + * @brief %Vector copy constructor. + * @param x A %vector of identical element and allocator types. + * + * The newly-created %vector uses a copy of the allocation + * object used by @a x. All the elements of @a x are copied, + * but any extra memory in + * @a x (for fast expansion) will not be copied. + */ + vector(const vector& __x) + : _Base(__x.size(), __x._M_get_Tp_allocator()) + { this->_M_impl._M_finish = + std::__uninitialized_copy_a(__x.begin(), __x.end(), + this->_M_impl._M_start, + _M_get_Tp_allocator()); + } + + /** + * @brief Builds a %vector from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %vector consisting of copies of the elements from + * [first,last). + * + * If the iterators are forward, bidirectional, or + * random-access, then this will call the elements' copy + * constructor N times (where N is distance(first,last)) and do + * no memory reallocation. But if only input iterators are + * used, then this will do at most 2N calls to the copy + * constructor, and logN memory reallocations. + */ + template<typename _InputIterator> + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + /** + * The dtor only erases the elements, and note that if the + * elements themselves are pointers, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + ~vector() + { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); } + + /** + * @brief %Vector assignment operator. + * @param x A %vector of identical element and allocator types. + * + * All the elements of @a x are copied, but any extra memory in + * @a x (for fast expansion) will not be copied. Unlike the + * copy constructor, the allocator object is not copied. + */ + vector& + operator=(const vector& __x); + + /** + * @brief Assigns a given value to a %vector. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %vector with @a n copies of the given + * value. Note that the assignment completely changes the + * %vector and that the resulting %vector's size is the same as + * the number of elements assigned. Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %vector. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %vector with copies of the elements in the + * range [first,last). + * + * Note that the assignment completely changes the %vector and + * that the resulting %vector's size is the same as the number + * of elements assigned. Old data may be lost. + */ + template<typename _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + using _Base::get_allocator; + + // iterators + /** + * Returns a read/write iterator that points to the first + * element in the %vector. Iteration is done in ordinary + * element order. + */ + iterator + begin() + { return iterator(this->_M_impl._M_start); } + + /** + * Returns a read-only (constant) iterator that points to the + * first element in the %vector. Iteration is done in ordinary + * element order. + */ + const_iterator + begin() const + { return const_iterator(this->_M_impl._M_start); } + + /** + * Returns a read/write iterator that points one past the last + * element in the %vector. Iteration is done in ordinary + * element order. + */ + iterator + end() + { return iterator(this->_M_impl._M_finish); } + + /** + * Returns a read-only (constant) iterator that points one past + * the last element in the %vector. Iteration is done in + * ordinary element order. + */ + const_iterator + end() const + { return const_iterator(this->_M_impl._M_finish); } + + /** + * Returns a read/write reverse iterator that points to the + * last element in the %vector. Iteration is done in reverse + * element order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last element in the %vector. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + /** + * Returns a read/write reverse iterator that points to one + * before the first element in the %vector. Iteration is done + * in reverse element order. + */ + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first element in the %vector. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // [23.2.4.2] capacity + /** Returns the number of elements in the %vector. */ + size_type + size() const + { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } + + /** Returns the size() of the largest possible %vector. */ + size_type + max_size() const + { return _M_get_Tp_allocator().max_size(); } + + /** + * @brief Resizes the %vector to the specified number of elements. + * @param new_size Number of elements the %vector should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %vector to the specified + * number of elements. If the number is smaller than the + * %vector's current size the %vector is truncated, otherwise + * the %vector is extended and new elements are populated with + * given data. + */ + void + resize(size_type __new_size, value_type __x = value_type()) + { + if (__new_size < size()) + _M_erase_at_end(this->_M_impl._M_start + __new_size); + else + insert(end(), __new_size - size(), __x); + } + + /** + * Returns the total number of elements that the %vector can + * hold before needing to allocate more memory. + */ + size_type + capacity() const + { return size_type(this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); } + + /** + * Returns true if the %vector is empty. (Thus begin() would + * equal end().) + */ + bool + empty() const + { return begin() == end(); } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * elements. + * @param n Number of elements required. + * @throw std::length_error If @a n exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %vector to hold the specified number of elements. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the number of elements + * that will be required, the user can reserve the memory in + * %advance, and thus prevent a possible reallocation of memory + * and copying of %vector data. + */ + void + reserve(size_type __n); + + // element access + /** + * @brief Subscript access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read/write reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + reference + operator[](size_type __n) + { return *(this->_M_impl._M_start + __n); } + + /** + * @brief Subscript access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read-only (constant) reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[](size_type __n) const + { return *(this->_M_impl._M_start + __n); } + + protected: + /// @if maint Safety check used only from at(). @endif + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("vector::_M_range_check")); + } + + public: + /** + * @brief Provides access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read/write reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the vector. The + * function throws out_of_range if the check fails. + */ + reference + at(size_type __n) + { + _M_range_check(__n); + return (*this)[__n]; + } + + /** + * @brief Provides access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read-only (constant) reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the vector. The + * function throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + _M_range_check(__n); + return (*this)[__n]; + } + + /** + * Returns a read/write reference to the data at the first + * element of the %vector. + */ + reference + front() + { return *begin(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %vector. + */ + const_reference + front() const + { return *begin(); } + + /** + * Returns a read/write reference to the data at the last + * element of the %vector. + */ + reference + back() + { return *(end() - 1); } + + /** + * Returns a read-only (constant) reference to the data at the + * last element of the %vector. + */ + const_reference + back() const + { return *(end() - 1); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 464. Suggestion for new member functions in standard containers. + // data access + /** + * Returns a pointer such that [data(), data() + size()) is a valid + * range. For a non-empty %vector, data() == &front(). + */ + pointer + data() + { return pointer(this->_M_impl._M_start); } + + const_pointer + data() const + { return const_pointer(this->_M_impl._M_start); } + + // [23.2.4.3] modifiers + /** + * @brief Add data to the end of the %vector. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the end of the %vector and assigns the given data + * to it. Due to the nature of a %vector this operation can be + * done in constant time if the %vector has preallocated space + * available. + */ + void + push_back(const value_type& __x) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + this->_M_impl.construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(end(), __x); + } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %vector by one. + * + * Note that no data is returned, and if the last element's + * data is needed, it should be retrieved before pop_back() is + * called. + */ + void + pop_back() + { + --this->_M_impl._M_finish; + this->_M_impl.destroy(this->_M_impl._M_finish); + } + + /** + * @brief Inserts given value into %vector before specified iterator. + * @param position An iterator into the %vector. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before + * the specified location. Note that this kind of operation + * could be expensive for a %vector and if it is frequently + * used the user should consider using std::list. + */ + iterator + insert(iterator __position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %vector. + * @param position An iterator into the %vector. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of + * the given data before the location specified by @a position. + * + * Note that this kind of operation could be expensive for a + * %vector and if it is frequently used the user should + * consider using std::list. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %vector. + * @param position An iterator into the %vector. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range + * [first,last) into the %vector before the location specified + * by @a pos. + * + * Note that this kind of operation could be expensive for a + * %vector and if it is frequently used the user should + * consider using std::list. + */ + template<typename _InputIterator> + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %vector by one. + * + * Note This operation could be expensive and if it is + * frequently used the user should consider using std::list. + * The user is also cautioned that this function only erases + * the element, and that if the element is itself a pointer, + * the pointed-to memory is not touched in any way. Managing + * the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range [first,last) and + * shorten the %vector accordingly. + * + * Note This operation could be expensive and if it is + * frequently used the user should consider using std::list. + * The user is also cautioned that this function only erases + * the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __first, iterator __last); + + /** + * @brief Swaps data with another %vector. + * @param x A %vector of the same element and allocator types. + * + * This exchanges the elements between two vectors in constant time. + * (Three pointers, so it should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(v1,v2) will feed to this function. + */ + void + swap(vector& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, + __x._M_impl._M_end_of_storage); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(), + __x._M_get_Tp_allocator()); + } + + /** + * Erases all the elements. Note that this function only erases the + * elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_erase_at_end(this->_M_impl._M_start); } + + protected: + /** + * @if maint + * Memory expansion handler. Uses the member allocation function to + * obtain @a n bytes of memory, and then copies [first,last) into it. + * @endif + */ + template<typename _ForwardIterator> + pointer + _M_allocate_and_copy(size_type __n, + _ForwardIterator __first, _ForwardIterator __last) + { + pointer __result = this->_M_allocate(__n); + try + { + std::__uninitialized_copy_a(__first, __last, __result, + _M_get_Tp_allocator()); + return __result; + } + catch(...) + { + _M_deallocate(__result, __n); + __throw_exception_again; + } + } + + + // Internal constructor functions follow. + + // Called by the range constructor to implement [23.1.1]/9 + template<typename _Integer> + void + _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) + { + this->_M_impl._M_start = _M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; + } + + // Called by the range constructor to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } + + // Called by the second initialize_dispatch above + template<typename _InputIterator> + void + _M_range_initialize(_InputIterator __first, + _InputIterator __last, std::input_iterator_tag) + { + for (; __first != __last; ++__first) + push_back(*__first); + } + + // Called by the second initialize_dispatch above + template<typename _ForwardIterator> + void + _M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = + std::__uninitialized_copy_a(__first, __last, + this->_M_impl._M_start, + _M_get_Tp_allocator()); + } + + + // Internal assign functions follow. The *_aux functions do the actual + // assignment work for the range versions. + + // Called by the range assign to implement [23.1.1]/9 + template<typename _Integer> + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast<size_type>(__n), + static_cast<value_type>(__val)); + } + + // Called by the range assign to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + // Called by the second assign_dispatch above + template<typename _InputIterator> + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag); + + // Called by the second assign_dispatch above + template<typename _ForwardIterator> + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag); + + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. + void + _M_fill_assign(size_type __n, const value_type& __val); + + + // Internal insert functions follow. + + // Called by the range insert to implement [23.1.1]/9 + template<typename _Integer> + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) + { + _M_fill_insert(__pos, static_cast<size_type>(__n), + static_cast<value_type>(__val)); + } + + // Called by the range insert to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_insert_dispatch(iterator __pos, _InputIterator __first, + _InputIterator __last, __false_type) + { + typedef typename std::iterator_traits<_InputIterator>:: + iterator_category _IterCategory; + _M_range_insert(__pos, __first, __last, _IterCategory()); + } + + // Called by the second insert_dispatch above + template<typename _InputIterator> + void + _M_range_insert(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag); + + // Called by the second insert_dispatch above + template<typename _ForwardIterator> + void + _M_range_insert(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag); + + // Called by insert(p,n,x), and the range insert when it turns out to be + // the same thing. + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + + // Called by insert(p,x) + void + _M_insert_aux(iterator __position, const value_type& __x); + + // Internal erase functions follow. + + // Called by erase(q1,q2), clear(), resize(), _M_fill_assign, + // _M_assign_aux. + void + _M_erase_at_end(pointer __pos) + { + std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); + this->_M_impl._M_finish = __pos; + } + }; + + + /** + * @brief Vector equality comparison. + * @param x A %vector. + * @param y A %vector of the same type as @a x. + * @return True iff the size and elements of the vectors are equal. + * + * This is an equivalence relation. It is linear in the size of the + * vectors. Vectors are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template<typename _Tp, typename _Alloc> + inline bool + operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return (__x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin())); } + + /** + * @brief Vector ordering relation. + * @param x A %vector. + * @param y A %vector of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * vectors. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template<typename _Tp, typename _Alloc> + inline bool + operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + /// Based on operator== + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template<typename _Tp, typename _Alloc> + inline bool + operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) + { return !(__x < __y); } + + /// See std::vector::swap(). + template<typename _Tp, typename _Alloc> + inline void + swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif /* _VECTOR_H */ diff --git a/libstdc++/include/bits/stream_iterator.h b/libstdc++/include/bits/stream_iterator.h new file mode 100644 index 0000000..ce3e675 --- /dev/null +++ b/libstdc++/include/bits/stream_iterator.h @@ -0,0 +1,216 @@ +// Stream iterators + +// Copyright (C) 2001, 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. + +/** @file stream_iterator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STREAM_ITERATOR_H +#define _STREAM_ITERATOR_H 1 + +#pragma GCC system_header + +#include <debug/debug.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /// Provides input iterator semantics for streams. + template<typename _Tp, typename _CharT = char, + typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t> + class istream_iterator + : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&> + { + public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_istream<_CharT, _Traits> istream_type; + + private: + istream_type* _M_stream; + _Tp _M_value; + bool _M_ok; + + public: + /// Construct end of input stream iterator. + istream_iterator() + : _M_stream(0), _M_value(), _M_ok(false) {} + + /// Construct start of input stream iterator. + istream_iterator(istream_type& __s) + : _M_stream(&__s) + { _M_read(); } + + istream_iterator(const istream_iterator& __obj) + : _M_stream(__obj._M_stream), _M_value(__obj._M_value), + _M_ok(__obj._M_ok) + { } + + const _Tp& + operator*() const + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_deref_istream) + ._M_iterator(*this)); + return _M_value; + } + + const _Tp* + operator->() const { return &(operator*()); } + + istream_iterator& + operator++() + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); + _M_read(); + return *this; + } + + istream_iterator + operator++(int) + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); + istream_iterator __tmp = *this; + _M_read(); + return __tmp; + } + + bool + _M_equal(const istream_iterator& __x) const + { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); } + + private: + void + _M_read() + { + _M_ok = (_M_stream && *_M_stream) ? true : false; + if (_M_ok) + { + *_M_stream >> _M_value; + _M_ok = *_M_stream ? true : false; + } + } + }; + + /// Return true if x and y are both end or not end, or x and y are the same. + template<typename _Tp, typename _CharT, typename _Traits, typename _Dist> + inline bool + operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) + { return __x._M_equal(__y); } + + /// Return false if x and y are both end or not end, or x and y are the same. + template <class _Tp, class _CharT, class _Traits, class _Dist> + inline bool + operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) + { return !__x._M_equal(__y); } + + /** + * @brief Provides output iterator semantics for streams. + * + * This class provides an iterator to write to an ostream. The type Tp is + * the only type written by this iterator and there must be an + * operator<<(Tp) defined. + * + * @param Tp The type to write to the ostream. + * @param CharT The ostream char_type. + * @param Traits The ostream char_traits. + */ + template<typename _Tp, typename _CharT = char, + typename _Traits = char_traits<_CharT> > + class ostream_iterator + : public iterator<output_iterator_tag, void, void, void, void> + { + public: + //@{ + /// Public typedef + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + //@} + + private: + ostream_type* _M_stream; + const _CharT* _M_string; + + public: + /// Construct from an ostream. + ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {} + + /** + * Construct from an ostream. + * + * The delimiter string @a c is written to the stream after every Tp + * written to the stream. The delimiter is not copied, and thus must + * not be destroyed while this iterator is in use. + * + * @param s Underlying ostream to write to. + * @param c CharT delimiter string to insert. + */ + ostream_iterator(ostream_type& __s, const _CharT* __c) + : _M_stream(&__s), _M_string(__c) { } + + /// Copy constructor. + ostream_iterator(const ostream_iterator& __obj) + : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { } + + /// Writes @a value to underlying ostream using operator<<. If + /// constructed with delimiter string, writes delimiter to ostream. + ostream_iterator& + operator=(const _Tp& __value) + { + __glibcxx_requires_cond(_M_stream != 0, + _M_message(__gnu_debug::__msg_output_ostream) + ._M_iterator(*this)); + *_M_stream << __value; + if (_M_string) *_M_stream << _M_string; + return *this; + } + + ostream_iterator& + operator*() + { return *this; } + + ostream_iterator& + operator++() + { return *this; } + + ostream_iterator& + operator++(int) + { return *this; } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/streambuf.tcc b/libstdc++/include/bits/streambuf.tcc new file mode 100644 index 0000000..c4b8605 --- /dev/null +++ b/libstdc++/include/bits/streambuf.tcc @@ -0,0 +1,179 @@ +// Stream buffer classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file streambuf.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 27.5 Stream buffers +// + +#ifndef _STREAMBUF_TCC +#define _STREAMBUF_TCC 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _CharT, typename _Traits> + streamsize + basic_streambuf<_CharT, _Traits>:: + xsgetn(char_type* __s, streamsize __n) + { + streamsize __ret = 0; + while (__ret < __n) + { + const streamsize __buf_len = this->egptr() - this->gptr(); + if (__buf_len) + { + const streamsize __remaining = __n - __ret; + const streamsize __len = std::min(__buf_len, __remaining); + traits_type::copy(__s, this->gptr(), __len); + __ret += __len; + __s += __len; + this->gbump(__len); + } + + if (__ret < __n) + { + const int_type __c = this->uflow(); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + traits_type::assign(*__s++, traits_type::to_char_type(__c)); + ++__ret; + } + else + break; + } + } + return __ret; + } + + template<typename _CharT, typename _Traits> + streamsize + basic_streambuf<_CharT, _Traits>:: + xsputn(const char_type* __s, streamsize __n) + { + streamsize __ret = 0; + while (__ret < __n) + { + const streamsize __buf_len = this->epptr() - this->pptr(); + if (__buf_len) + { + const streamsize __remaining = __n - __ret; + const streamsize __len = std::min(__buf_len, __remaining); + traits_type::copy(this->pptr(), __s, __len); + __ret += __len; + __s += __len; + this->pbump(__len); + } + + if (__ret < __n) + { + int_type __c = this->overflow(traits_type::to_int_type(*__s)); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + ++__ret; + ++__s; + } + else + break; + } + } + return __ret; + } + + // Conceivably, this could be used to implement buffer-to-buffer + // copies, if this was ever desired in an un-ambiguous way by the + // standard. + template<typename _CharT, typename _Traits> + streamsize + __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout, + bool& __ineof) + { + streamsize __ret = 0; + __ineof = true; + typename _Traits::int_type __c = __sbin->sgetc(); + while (!_Traits::eq_int_type(__c, _Traits::eof())) + { + __c = __sbout->sputc(_Traits::to_char_type(__c)); + if (_Traits::eq_int_type(__c, _Traits::eof())) + { + __ineof = false; + break; + } + ++__ret; + __c = __sbin->snextc(); + } + return __ret; + } + + template<typename _CharT, typename _Traits> + inline streamsize + __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout) + { + bool __ineof; + return __copy_streambufs_eof(__sbin, __sbout, __ineof); + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_streambuf<char>; + extern template + streamsize + __copy_streambufs(basic_streambuf<char>*, + basic_streambuf<char>*); + extern template + streamsize + __copy_streambufs_eof(basic_streambuf<char>*, + basic_streambuf<char>*, bool&); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_streambuf<wchar_t>; + extern template + streamsize + __copy_streambufs(basic_streambuf<wchar_t>*, + basic_streambuf<wchar_t>*); + extern template + streamsize + __copy_streambufs_eof(basic_streambuf<wchar_t>*, + basic_streambuf<wchar_t>*, bool&); +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/streambuf_iterator.h b/libstdc++/include/bits/streambuf_iterator.h new file mode 100644 index 0000000..a1cf234 --- /dev/null +++ b/libstdc++/include/bits/streambuf_iterator.h @@ -0,0 +1,400 @@ +// Streambuf iterators + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file streambuf_iterator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STREAMBUF_ITERATOR_H +#define _STREAMBUF_ITERATOR_H 1 + +#pragma GCC system_header + +#include <streambuf> +#include <debug/debug.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // 24.5.3 Template class istreambuf_iterator + /// Provides input iterator semantics for streambufs. + template<typename _CharT, typename _Traits> + class istreambuf_iterator + : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, + _CharT*, _CharT&> + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_istream<_CharT, _Traits> istream_type; + //@} + + template<typename _CharT2> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + ostreambuf_iterator<_CharT2> >::__type + copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, + ostreambuf_iterator<_CharT2>); + + template<typename _CharT2> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + _CharT2*>::__type + __copy_aux(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, + _CharT2*); + + template<typename _CharT2> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + istreambuf_iterator<_CharT2> >::__type + find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, + const _CharT2&); + + private: + // 24.5.3 istreambuf_iterator + // p 1 + // If the end of stream is reached (streambuf_type::sgetc() + // returns traits_type::eof()), the iterator becomes equal to + // the "end of stream" iterator value. + // NB: This implementation assumes the "end of stream" value + // is EOF, or -1. + mutable streambuf_type* _M_sbuf; + mutable int_type _M_c; + + public: + /// Construct end of input stream iterator. + istreambuf_iterator() throw() + : _M_sbuf(0), _M_c(traits_type::eof()) { } + + /// Construct start of input stream iterator. + istreambuf_iterator(istream_type& __s) throw() + : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } + + /// Construct start of streambuf iterator. + istreambuf_iterator(streambuf_type* __s) throw() + : _M_sbuf(__s), _M_c(traits_type::eof()) { } + + /// Return the current character pointed to by iterator. This returns + /// streambuf.sgetc(). It cannot be assigned. NB: The result of + /// operator*() on an end of stream is undefined. + char_type + operator*() const + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + // Dereferencing a past-the-end istreambuf_iterator is a + // libstdc++ extension + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_deref_istreambuf) + ._M_iterator(*this)); +#endif + return traits_type::to_char_type(_M_get()); + } + + /// Advance the iterator. Calls streambuf.sbumpc(). + istreambuf_iterator& + operator++() + { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(*this)); + if (_M_sbuf) + { + _M_sbuf->sbumpc(); + _M_c = traits_type::eof(); + } + return *this; + } + + /// Advance the iterator. Calls streambuf.sbumpc(). + istreambuf_iterator + operator++(int) + { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(*this)); + + istreambuf_iterator __old = *this; + if (_M_sbuf) + { + __old._M_c = _M_sbuf->sbumpc(); + _M_c = traits_type::eof(); + } + return __old; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 110 istreambuf_iterator::equal not const + // NB: there is also number 111 (NAD, Future) pending on this function. + /// Return true both iterators are end or both are not end. + bool + equal(const istreambuf_iterator& __b) const + { + const bool __thiseof = _M_at_eof(); + const bool __beof = __b._M_at_eof(); + return (__thiseof && __beof || (!__thiseof && !__beof)); + } + + private: + int_type + _M_get() const + { + const int_type __eof = traits_type::eof(); + int_type __ret = __eof; + if (_M_sbuf) + { + if (!traits_type::eq_int_type(_M_c, __eof)) + __ret = _M_c; + else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), + __eof)) + _M_c = __ret; + else + _M_sbuf = 0; + } + return __ret; + } + + bool + _M_at_eof() const + { + const int_type __eof = traits_type::eof(); + return traits_type::eq_int_type(_M_get(), __eof); + } + }; + + template<typename _CharT, typename _Traits> + inline bool + operator==(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return __a.equal(__b); } + + template<typename _CharT, typename _Traits> + inline bool + operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return !__a.equal(__b); } + + /// Provides output iterator semantics for streambufs. + template<typename _CharT, typename _Traits> + class ostreambuf_iterator + : public iterator<output_iterator_tag, void, void, void, void> + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + //@} + + template<typename _CharT2> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + ostreambuf_iterator<_CharT2> >::__type + copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, + ostreambuf_iterator<_CharT2>); + + private: + streambuf_type* _M_sbuf; + bool _M_failed; + + public: + /// Construct output iterator from ostream. + ostreambuf_iterator(ostream_type& __s) throw () + : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } + + /// Construct output iterator from streambuf. + ostreambuf_iterator(streambuf_type* __s) throw () + : _M_sbuf(__s), _M_failed(!_M_sbuf) { } + + /// Write character to streambuf. Calls streambuf.sputc(). + ostreambuf_iterator& + operator=(_CharT __c) + { + if (!_M_failed && + _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) + _M_failed = true; + return *this; + } + + /// Return *this. + ostreambuf_iterator& + operator*() + { return *this; } + + /// Return *this. + ostreambuf_iterator& + operator++(int) + { return *this; } + + /// Return *this. + ostreambuf_iterator& + operator++() + { return *this; } + + /// Return true if previous operator=() failed. + bool + failed() const throw() + { return _M_failed; } + + ostreambuf_iterator& + _M_put(const _CharT* __ws, streamsize __len) + { + if (__builtin_expect(!_M_failed, true) + && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, + false)) + _M_failed = true; + return *this; + } + }; + + // Overloads for streambuf iterators. + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT> >::__type + copy(istreambuf_iterator<_CharT> __first, + istreambuf_iterator<_CharT> __last, + ostreambuf_iterator<_CharT> __result) + { + if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed) + { + bool __ineof; + __copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof); + if (!__ineof) + __result._M_failed = true; + } + return __result; + } + + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT> >::__type + __copy_aux(_CharT* __first, _CharT* __last, + ostreambuf_iterator<_CharT> __result) + { + const streamsize __num = __last - __first; + if (__num > 0) + __result._M_put(__first, __num); + return __result; + } + + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + ostreambuf_iterator<_CharT> >::__type + __copy_aux(const _CharT* __first, const _CharT* __last, + ostreambuf_iterator<_CharT> __result) + { + const streamsize __num = __last - __first; + if (__num > 0) + __result._M_put(__first, __num); + return __result; + } + + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + _CharT*>::__type + __copy_aux(istreambuf_iterator<_CharT> __first, + istreambuf_iterator<_CharT> __last, _CharT* __result) + { + typedef istreambuf_iterator<_CharT> __is_iterator_type; + typedef typename __is_iterator_type::traits_type traits_type; + typedef typename __is_iterator_type::streambuf_type streambuf_type; + typedef typename traits_type::int_type int_type; + + if (__first._M_sbuf && !__last._M_sbuf) + { + streambuf_type* __sb = __first._M_sbuf; + int_type __c = __sb->sgetc(); + while (!traits_type::eq_int_type(__c, traits_type::eof())) + { + const streamsize __n = __sb->egptr() - __sb->gptr(); + if (__n > 1) + { + traits_type::copy(__result, __sb->gptr(), __n); + __sb->gbump(__n); + __result += __n; + __c = __sb->underflow(); + } + else + { + *__result++ = traits_type::to_char_type(__c); + __c = __sb->snextc(); + } + } + } + return __result; + } + + template<typename _CharT> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + istreambuf_iterator<_CharT> >::__type + find(istreambuf_iterator<_CharT> __first, + istreambuf_iterator<_CharT> __last, const _CharT& __val) + { + typedef istreambuf_iterator<_CharT> __is_iterator_type; + typedef typename __is_iterator_type::traits_type traits_type; + typedef typename __is_iterator_type::streambuf_type streambuf_type; + typedef typename traits_type::int_type int_type; + + if (__first._M_sbuf && !__last._M_sbuf) + { + const int_type __ival = traits_type::to_int_type(__val); + streambuf_type* __sb = __first._M_sbuf; + int_type __c = __sb->sgetc(); + while (!traits_type::eq_int_type(__c, traits_type::eof()) + && !traits_type::eq_int_type(__c, __ival)) + { + streamsize __n = __sb->egptr() - __sb->gptr(); + if (__n > 1) + { + const _CharT* __p = traits_type::find(__sb->gptr(), + __n, __val); + if (__p) + __n = __p - __sb->gptr(); + __sb->gbump(__n); + __c = __sb->sgetc(); + } + else + __c = __sb->snextc(); + } + + if (!traits_type::eq_int_type(__c, traits_type::eof())) + __first._M_c = __c; + else + __first._M_sbuf = 0; + } + return __first; + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/bits/stringfwd.h b/libstdc++/include/bits/stringfwd.h new file mode 100644 index 0000000..d27ef14 --- /dev/null +++ b/libstdc++/include/bits/stringfwd.h @@ -0,0 +1,70 @@ +// String support -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/** @file stringfwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 21 Strings library +// + +#ifndef _STRINGFWD_H +#define _STRINGFWD_H 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _Alloc> + class allocator; + + template<class _CharT> + struct char_traits; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_string; + + template<> struct char_traits<char>; + + typedef basic_string<char> string; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> struct char_traits<wchar_t>; + + typedef basic_string<wchar_t> wstring; +#endif + +_GLIBCXX_END_NAMESPACE + +#endif // _STRINGFWD_H diff --git a/libstdc++/include/bits/valarray_after.h b/libstdc++/include/bits/valarray_after.h new file mode 100644 index 0000000..723df61 --- /dev/null +++ b/libstdc++/include/bits/valarray_after.h @@ -0,0 +1,554 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file valarray_after.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> + +#ifndef _VALARRAY_AFTER_H +#define _VALARRAY_AFTER_H 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // + // gslice_array closure. + // + template<class _Dom> + class _GBase + { + public: + typedef typename _Dom::value_type value_type; + + _GBase (const _Dom& __e, const valarray<size_t>& __i) + : _M_expr (__e), _M_index(__i) {} + + value_type + operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + + size_t + size () const + { return _M_index.size(); } + + private: + const _Dom& _M_expr; + const valarray<size_t>& _M_index; + }; + + template<typename _Tp> + class _GBase<_Array<_Tp> > + { + public: + typedef _Tp value_type; + + _GBase (_Array<_Tp> __a, const valarray<size_t>& __i) + : _M_array (__a), _M_index(__i) {} + + value_type + operator[] (size_t __i) const + { return _M_array._M_data[_M_index[__i]]; } + + size_t + size () const + { return _M_index.size(); } + + private: + const _Array<_Tp> _M_array; + const valarray<size_t>& _M_index; + }; + + template<class _Dom> + struct _GClos<_Expr, _Dom> + : _GBase<_Dom> + { + typedef _GBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _GClos (const _Dom& __e, const valarray<size_t>& __i) + : _Base (__e, __i) {} + }; + + template<typename _Tp> + struct _GClos<_ValArray, _Tp> + : _GBase<_Array<_Tp> > + { + typedef _GBase<_Array<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _GClos (_Array<_Tp> __a, const valarray<size_t>& __i) + : _Base (__a, __i) {} + }; + + // + // indirect_array closure + // + template<class _Dom> + class _IBase + { + public: + typedef typename _Dom::value_type value_type; + + _IBase (const _Dom& __e, const valarray<size_t>& __i) + : _M_expr (__e), _M_index (__i) {} + + value_type + operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + + size_t + size() const + { return _M_index.size(); } + + private: + const _Dom& _M_expr; + const valarray<size_t>& _M_index; + }; + + template<class _Dom> + struct _IClos<_Expr, _Dom> + : _IBase<_Dom> + { + typedef _IBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _IClos (const _Dom& __e, const valarray<size_t>& __i) + : _Base (__e, __i) {} + }; + + template<typename _Tp> + struct _IClos<_ValArray, _Tp> + : _IBase<valarray<_Tp> > + { + typedef _IBase<valarray<_Tp> > _Base; + typedef _Tp value_type; + + _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i) + : _Base (__a, __i) {} + }; + + // + // class _Expr + // + template<class _Clos, typename _Tp> + class _Expr + { + public: + typedef _Tp value_type; + + _Expr(const _Clos&); + + const _Clos& operator()() const; + + value_type operator[](size_t) const; + valarray<value_type> operator[](slice) const; + valarray<value_type> operator[](const gslice&) const; + valarray<value_type> operator[](const valarray<bool>&) const; + valarray<value_type> operator[](const valarray<size_t>&) const; + + _Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type> + operator+() const; + + _Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type> + operator-() const; + + _Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type> + operator~() const; + + _Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool> + operator!() const; + + size_t size() const; + value_type sum() const; + + valarray<value_type> shift(int) const; + valarray<value_type> cshift(int) const; + + value_type min() const; + value_type max() const; + + valarray<value_type> apply(value_type (*)(const value_type&)) const; + valarray<value_type> apply(value_type (*)(value_type)) const; + + private: + const _Clos _M_closure; + }; + + template<class _Clos, typename _Tp> + inline + _Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {} + + template<class _Clos, typename _Tp> + inline const _Clos& + _Expr<_Clos, _Tp>::operator()() const + { return _M_closure; } + + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos, _Tp>::operator[](size_t __i) const + { return _M_closure[__i]; } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::operator[](slice __s) const + { + valarray<_Tp> __v = valarray<_Tp>(*this)[__s]; + return __v; + } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const + { + valarray<_Tp> __v = valarray<_Tp>(*this)[__gs]; + return __v; + } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const + { + valarray<_Tp> __v = valarray<_Tp>(*this)[__m]; + return __v; + } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const + { + valarray<_Tp> __v = valarray<_Tp>(*this)[__i]; + return __v; + } + + template<class _Clos, typename _Tp> + inline size_t + _Expr<_Clos, _Tp>::size() const + { return _M_closure.size(); } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::shift(int __n) const + { + valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n); + return __v; + } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::cshift(int __n) const + { + valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n); + return __v; + } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const + { + valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f); + return __v; + } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const + { + valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f); + return __v; + } + + // XXX: replace this with a more robust summation algorithm. + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos, _Tp>::sum() const + { + size_t __n = _M_closure.size(); + if (__n == 0) + return _Tp(); + else + { + _Tp __s = _M_closure[--__n]; + while (__n != 0) + __s += _M_closure[--__n]; + return __s; + } + } + + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos, _Tp>::min() const + { return __valarray_min(_M_closure); } + + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos, _Tp>::max() const + { return __valarray_max(_M_closure); } + + template<class _Dom, typename _Tp> + inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool> + _Expr<_Dom, _Tp>::operator!() const + { + typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure; + return _Expr<_Closure, _Tp>(_Closure(this->_M_closure)); + } + +#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ + template<class _Dom, typename _Tp> \ + inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp> \ + _Expr<_Dom, _Tp>::operator _Op() const \ + { \ + typedef _UnClos<_Name, std::_Expr, _Dom> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(this->_M_closure)); \ + } + + _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus) + _DEFINE_EXPR_UNARY_OPERATOR(-, __negate) + _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not) + +#undef _DEFINE_EXPR_UNARY_OPERATOR + +#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ + template<class _Dom1, class _Dom2> \ + inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>, \ + typename __fun<_Name, typename _Dom1::value_type>::result_type> \ + operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \ + const _Expr<_Dom2, typename _Dom2::value_type>& __w) \ + { \ + typedef typename _Dom1::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure; \ + return _Expr<_Closure, _Value>(_Closure(__v(), __w())); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom, \ + typename _Dom::value_type>, \ + typename __fun<_Name, typename _Dom::value_type>::result_type> \ + operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \ + const typename _Dom::value_type& __t) \ + { \ + typedef typename _Dom::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure; \ + return _Expr<_Closure, _Value>(_Closure(__v(), __t)); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<_Name, _Constant, _Expr, \ + typename _Dom::value_type, _Dom>, \ + typename __fun<_Name, typename _Dom::value_type>::result_type> \ + operator _Op(const typename _Dom::value_type& __t, \ + const _Expr<_Dom, typename _Dom::value_type>& __v) \ + { \ + typedef typename _Dom::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure; \ + return _Expr<_Closure, _Value>(_Closure(__t, __v())); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<_Name, _Expr, _ValArray, \ + _Dom, typename _Dom::value_type>, \ + typename __fun<_Name, typename _Dom::value_type>::result_type> \ + operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray<typename _Dom::value_type>& __v) \ + { \ + typedef typename _Dom::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure; \ + return _Expr<_Closure, _Value>(_Closure(__e(), __v)); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<_Name, _ValArray, _Expr, \ + typename _Dom::value_type, _Dom>, \ + typename __fun<_Name, typename _Dom::value_type>::result_type> \ + operator _Op(const valarray<typename _Dom::value_type>& __v, \ + const _Expr<_Dom, typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef typename __fun<_Name, _Tp>::result_type _Value; \ + typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure; \ + return _Expr<_Closure, _Value>(_Closure(__v, __e ())); \ + } + + _DEFINE_EXPR_BINARY_OPERATOR(+, __plus) + _DEFINE_EXPR_BINARY_OPERATOR(-, __minus) + _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies) + _DEFINE_EXPR_BINARY_OPERATOR(/, __divides) + _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus) + _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor) + _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and) + _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or) + _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left) + _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right) + _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and) + _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or) + _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to) + _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to) + _DEFINE_EXPR_BINARY_OPERATOR(<, __less) + _DEFINE_EXPR_BINARY_OPERATOR(>, __greater) + _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal) + _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal) + +#undef _DEFINE_EXPR_BINARY_OPERATOR + +#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ + template<class _Dom> \ + inline _Expr<_UnClos<__##_Name, _Expr, _Dom>, \ + typename _Dom::value_type> \ + _Name(const _Expr<_Dom, typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _UnClos<__##_Name, _Expr, _Dom> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(__e())); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_UnClos<__##_Name, _ValArray, _Tp>, _Tp> \ + _Name(const valarray<_Tp>& __v) \ + { \ + typedef _UnClos<__##_Name, _ValArray, _Tp> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(__v)); \ + } + + _DEFINE_EXPR_UNARY_FUNCTION(abs) + _DEFINE_EXPR_UNARY_FUNCTION(cos) + _DEFINE_EXPR_UNARY_FUNCTION(acos) + _DEFINE_EXPR_UNARY_FUNCTION(cosh) + _DEFINE_EXPR_UNARY_FUNCTION(sin) + _DEFINE_EXPR_UNARY_FUNCTION(asin) + _DEFINE_EXPR_UNARY_FUNCTION(sinh) + _DEFINE_EXPR_UNARY_FUNCTION(tan) + _DEFINE_EXPR_UNARY_FUNCTION(tanh) + _DEFINE_EXPR_UNARY_FUNCTION(atan) + _DEFINE_EXPR_UNARY_FUNCTION(exp) + _DEFINE_EXPR_UNARY_FUNCTION(log) + _DEFINE_EXPR_UNARY_FUNCTION(log10) + _DEFINE_EXPR_UNARY_FUNCTION(sqrt) + +#undef _DEFINE_EXPR_UNARY_FUNCTION + +#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \ + template<class _Dom1, class _Dom2> \ + inline _Expr<_BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2>, \ + typename _Dom1::value_type> \ + _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1, \ + const _Expr<_Dom2, typename _Dom2::value_type>& __e2) \ + { \ + typedef typename _Dom1::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2())); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \ + typename _Dom::value_type>, \ + typename _Dom::value_type> \ + _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ + const valarray<typename _Dom::value_type>& __v) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(__e(), __v)); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \ + typename _Dom::value_type, _Dom>, \ + typename _Dom::value_type> \ + _Fun(const valarray<typename _Dom::valarray>& __v, \ + const _Expr<_Dom, typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _ValArray, _Expr, _Tp, _Dom> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(__v, __e())); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<__##_Fun, _Expr, _Constant, _Dom, \ + typename _Dom::value_type>, \ + typename _Dom::value_type> \ + _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ + const typename _Dom::value_type& __t) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Expr, _Constant, _Dom, _Tp> _Closure;\ + return _Expr<_Closure, _Tp>(_Closure(__e(), __t)); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<__##_Fun, _Constant, _Expr, \ + typename _Dom::value_type, _Dom>, \ + typename _Dom::value_type> \ + _Fun(const typename _Dom::value_type& __t, \ + const _Expr<_Dom, typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Constant, _Expr, _Tp, _Dom> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(__t, __e())); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \ + _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ + { \ + typedef _BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(__v, __w)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \ + _Fun(const valarray<_Tp>& __v, const _Tp& __t) \ + { \ + typedef _BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(__v, __t)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \ + _Fun(const _Tp& __t, const valarray<_Tp>& __v) \ + { \ + typedef _BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp> _Closure; \ + return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \ + } + +_DEFINE_EXPR_BINARY_FUNCTION(atan2) +_DEFINE_EXPR_BINARY_FUNCTION(pow) + +#undef _DEFINE_EXPR_BINARY_FUNCTION + +_GLIBCXX_END_NAMESPACE + +#endif /* _CPP_VALARRAY_AFTER_H */ diff --git a/libstdc++/include/bits/valarray_array.h b/libstdc++/include/bits/valarray_array.h new file mode 100644 index 0000000..a40c880 --- /dev/null +++ b/libstdc++/include/bits/valarray_array.h @@ -0,0 +1,704 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997, 1998, 1999, 2000, 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. + +/** @file valarray_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _VALARRAY_ARRAY_H +#define _VALARRAY_ARRAY_H 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/cpp_type_traits.h> +#include <cstdlib> +#include <cstring> +#include <new> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // + // Helper functions on raw pointers + // + + // We get memory by the old fashion way + inline void* + __valarray_get_memory(size_t __n) + { return operator new(__n); } + + template<typename _Tp> + inline _Tp*__restrict__ + __valarray_get_storage(size_t __n) + { + return static_cast<_Tp*__restrict__> + (std::__valarray_get_memory(__n * sizeof(_Tp))); + } + + // Return memory to the system + inline void + __valarray_release_memory(void* __p) + { operator delete(__p); } + + // Turn a raw-memory into an array of _Tp filled with _Tp() + // This is required in 'valarray<T> v(n);' + template<typename _Tp, bool> + struct _Array_default_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { + while (__b != __e) + new(__b++) _Tp(); + } + }; + + template<typename _Tp> + struct _Array_default_ctor<_Tp, true> + { + // For fundamental types, it suffices to say 'memset()' + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { std::memset(__b, 0, (__e - __b) * sizeof(_Tp)); } + }; + + template<typename _Tp> + inline void + __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { + _Array_default_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e); + } + + // Turn a raw-memory into an array of _Tp filled with __t + // This is the required in valarray<T> v(n, t). Also + // used in valarray<>::resize(). + template<typename _Tp, bool> + struct _Array_init_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) + { + while (__b != __e) + new(__b++) _Tp(__t); + } + }; + + template<typename _Tp> + struct _Array_init_ctor<_Tp, true> + { + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) + { + while (__b != __e) + *__b++ = __t; + } + }; + + template<typename _Tp> + inline void + __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e, + const _Tp __t) + { + _Array_init_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e, __t); + } + + // + // copy-construct raw array [__o, *) from plain array [__b, __e) + // We can't just say 'memcpy()' + // + template<typename _Tp, bool> + struct _Array_copy_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { + while (__b != __e) + new(__o++) _Tp(*__b++); + } + }; + + template<typename _Tp> + struct _Array_copy_ctor<_Tp, true> + { + inline static void + _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { std::memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); } + }; + + template<typename _Tp> + inline void + __valarray_copy_construct(const _Tp* __restrict__ __b, + const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { + _Array_copy_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e, __o); + } + + // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] + template<typename _Tp> + inline void + __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, + size_t __s, _Tp* __restrict__ __o) + { + if (__is_pod<_Tp>::__value) + while (__n--) + { + *__o++ = *__a; + __a += __s; + } + else + while (__n--) + { + new(__o++) _Tp(*__a); + __a += __s; + } + } + + // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] + template<typename _Tp> + inline void + __valarray_copy_construct (const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __o, size_t __n) + { + if (__is_pod<_Tp>::__value) + while (__n--) + *__o++ = __a[*__i++]; + else + while (__n--) + new (__o++) _Tp(__a[*__i++]); + } + + // Do the necessary cleanup when we're done with arrays. + template<typename _Tp> + inline void + __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { + if (!__is_pod<_Tp>::__value) + while (__b != __e) + { + __b->~_Tp(); + ++__b; + } + } + + // Fill a plain array __a[<__n>] with __t + template<typename _Tp> + inline void + __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t) + { + while (__n--) + *__a++ = __t; + } + + // fill strided array __a[<__n-1 : __s>] with __t + template<typename _Tp> + inline void + __valarray_fill(_Tp* __restrict__ __a, size_t __n, + size_t __s, const _Tp& __t) + { + for (size_t __i = 0; __i < __n; ++__i, __a += __s) + *__a = __t; + } + + // fill indir ect array __a[__i[<__n>]] with __i + template<typename _Tp> + inline void + __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, + size_t __n, const _Tp& __t) + { + for (size_t __j = 0; __j < __n; ++__j, ++__i) + __a[*__i] = __t; + } + + // copy plain array __a[<__n>] in __b[<__n>] + // For non-fundamental types, it is wrong to say 'memcpy()' + template<typename _Tp, bool> + struct _Array_copier + { + inline static void + _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) + { + while(__n--) + *__b++ = *__a++; + } + }; + + template<typename _Tp> + struct _Array_copier<_Tp, true> + { + inline static void + _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) + { std::memcpy (__b, __a, __n * sizeof (_Tp)); } + }; + + // Copy a plain array __a[<__n>] into a play array __b[<>] + template<typename _Tp> + inline void + __valarray_copy(const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b) + { + _Array_copier<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__a, __n, __b); + } + + // Copy strided array __a[<__n : __s>] in plain __b[<__n>] + template<typename _Tp> + inline void + __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s, + _Tp* __restrict__ __b) + { + for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s) + *__b = *__a; + } + + // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] + template<typename _Tp> + inline void + __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b, + size_t __n, size_t __s) + { + for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s) + *__b = *__a; + } + + // Copy strided array __src[<__n : __s1>] into another + // strided array __dst[< : __s2>]. Their sizes must match. + template<typename _Tp> + inline void + __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1, + _Tp* __restrict__ __dst, size_t __s2) + { + for (size_t __i = 0; __i < __n; ++__i) + __dst[__i * __s2] = __src[__i * __s1]; + } + + // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] + template<typename _Tp> + inline void + __valarray_copy(const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __b, size_t __n) + { + for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i) + *__b = __a[*__i]; + } + + // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] + template<typename _Tp> + inline void + __valarray_copy(const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b, const size_t* __restrict__ __i) + { + for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i) + __b[*__i] = *__a; + } + + // Copy the __n first elements of an indexed array __src[<__i>] into + // another indexed array __dst[<__j>]. + template<typename _Tp> + inline void + __valarray_copy(const _Tp* __restrict__ __src, size_t __n, + const size_t* __restrict__ __i, + _Tp* __restrict__ __dst, const size_t* __restrict__ __j) + { + for (size_t __k = 0; __k < __n; ++__k) + __dst[*__j++] = __src[*__i++]; + } + + // + // Compute the sum of elements in range [__f, __l) + // This is a naive algorithm. It suffers from cancelling. + // In the future try to specialize + // for _Tp = float, double, long double using a more accurate + // algorithm. + // + template<typename _Tp> + inline _Tp + __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l) + { + _Tp __r = _Tp(); + while (__f != __l) + __r += *__f++; + return __r; + } + + // Compute the product of all elements in range [__f, __l) + template<typename _Tp> + inline _Tp + __valarray_product(const _Tp* __restrict__ __f, + const _Tp* __restrict__ __l) + { + _Tp __r = _Tp(1); + while (__f != __l) + __r = __r * *__f++; + return __r; + } + + // Compute the min/max of an array-expression + template<typename _Ta> + inline typename _Ta::value_type + __valarray_min(const _Ta& __a) + { + size_t __s = __a.size(); + typedef typename _Ta::value_type _Value_type; + _Value_type __r = __s == 0 ? _Value_type() : __a[0]; + for (size_t __i = 1; __i < __s; ++__i) + { + _Value_type __t = __a[__i]; + if (__t < __r) + __r = __t; + } + return __r; + } + + template<typename _Ta> + inline typename _Ta::value_type + __valarray_max(const _Ta& __a) + { + size_t __s = __a.size(); + typedef typename _Ta::value_type _Value_type; + _Value_type __r = __s == 0 ? _Value_type() : __a[0]; + for (size_t __i = 1; __i < __s; ++__i) + { + _Value_type __t = __a[__i]; + if (__t > __r) + __r = __t; + } + return __r; + } + + // + // Helper class _Array, first layer of valarray abstraction. + // All operations on valarray should be forwarded to this class + // whenever possible. -- gdr + // + + template<typename _Tp> + struct _Array + { + explicit _Array(size_t); + explicit _Array(_Tp* const __restrict__); + explicit _Array(const valarray<_Tp>&); + _Array(const _Tp* __restrict__, size_t); + + _Tp* begin() const; + + _Tp* const __restrict__ _M_data; + }; + + + // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]] + template<typename _Tp> + inline void + __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i, + _Array<_Tp> __b, size_t __n) + { std::__valarray_copy_construct(__a._M_data, __i._M_data, + __b._M_data, __n); } + + // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>] + template<typename _Tp> + inline void + __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s, + _Array<_Tp> __b) + { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); } + + template<typename _Tp> + inline void + __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) + { std::__valarray_fill(__a._M_data, __n, __t); } + + template<typename _Tp> + inline void + __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) + { std::__valarray_fill(__a._M_data, __n, __s, __t); } + + template<typename _Tp> + inline void + __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i, + size_t __n, const _Tp& __t) + { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); } + + // Copy a plain array __a[<__n>] into a play array __b[<>] + template<typename _Tp> + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) + { std::__valarray_copy(__a._M_data, __n, __b._M_data); } + + // Copy strided array __a[<__n : __s>] in plain __b[<__n>] + template<typename _Tp> + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) + { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); } + + // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] + template<typename _Tp> + inline void + __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) + { __valarray_copy(__a._M_data, __b._M_data, __n, __s); } + + // Copy strided array __src[<__n : __s1>] into another + // strided array __dst[< : __s2>]. Their sizes must match. + template<typename _Tp> + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, + _Array<_Tp> __b, size_t __s2) + { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } + + // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] + template<typename _Tp> + inline void + __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i, + _Array<_Tp> __b, size_t __n) + { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); } + + // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] + template<typename _Tp> + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + _Array<size_t> __i) + { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); } + + // Copy the __n first elements of an indexed array __src[<__i>] into + // another indexed array __dst[<__j>]. + template<typename _Tp> + inline void + __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i, + _Array<_Tp> __dst, _Array<size_t> __j) + { + std::__valarray_copy(__src._M_data, __n, __i._M_data, + __dst._M_data, __j._M_data); + } + + template<typename _Tp> + inline + _Array<_Tp>::_Array(size_t __n) + : _M_data(__valarray_get_storage<_Tp>(__n)) + { std::__valarray_default_construct(_M_data, _M_data + __n); } + + template<typename _Tp> + inline + _Array<_Tp>::_Array(_Tp* const __restrict__ __p) + : _M_data (__p) {} + + template<typename _Tp> + inline + _Array<_Tp>::_Array(const valarray<_Tp>& __v) + : _M_data (__v._M_data) {} + + template<typename _Tp> + inline + _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s) + : _M_data(__valarray_get_storage<_Tp>(__s)) + { std::__valarray_copy_construct(__b, __s, _M_data); } + + template<typename _Tp> + inline _Tp* + _Array<_Tp>::begin () const + { return _M_data; } + +#define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ + template<typename _Tp> \ + inline void \ + _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \ + { \ + for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p) \ + *__p _Op##= __t; \ + } \ + \ + template<typename _Tp> \ + inline void \ + _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ + { \ + _Tp* __p = __a._M_data; \ + for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \ + *__p _Op##= *__q; \ + } \ + \ + template<typename _Tp, class _Dom> \ + void \ + _Array_augmented_##_Name(_Array<_Tp> __a, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ + { \ + _Tp* __p(__a._M_data); \ + for (size_t __i = 0; __i < __n; ++__i, ++__p) \ + *__p _Op##= __e[__i]; \ + } \ + \ + template<typename _Tp> \ + inline void \ + _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s, \ + _Array<_Tp> __b) \ + { \ + _Tp* __q(__b._M_data); \ + for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n; \ + __p += __s, ++__q) \ + *__p _Op##= *__q; \ + } \ + \ + template<typename _Tp> \ + inline void \ + _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b, \ + size_t __n, size_t __s) \ + { \ + _Tp* __q(__b._M_data); \ + for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ + ++__p, __q += __s) \ + *__p _Op##= *__q; \ + } \ + \ + template<typename _Tp, class _Dom> \ + void \ + _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ + { \ + _Tp* __p(__a._M_data); \ + for (size_t __i = 0; __i < __n; ++__i, __p += __s) \ + *__p _Op##= __e[__i]; \ + } \ + \ + template<typename _Tp> \ + inline void \ + _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ + _Array<_Tp> __b, size_t __n) \ + { \ + _Tp* __q(__b._M_data); \ + for (size_t* __j = __i._M_data; __j < __i._M_data + __n; \ + ++__j, ++__q) \ + __a._M_data[*__j] _Op##= *__q; \ + } \ + \ + template<typename _Tp> \ + inline void \ + _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array<size_t> __i) \ + { \ + _Tp* __p(__a._M_data); \ + for (size_t* __j = __i._M_data; __j<__i._M_data + __n; \ + ++__j, ++__p) \ + *__p _Op##= __b._M_data[*__j]; \ + } \ + \ + template<typename _Tp, class _Dom> \ + void \ + _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ + { \ + size_t* __j(__i._M_data); \ + for (size_t __k = 0; __k<__n; ++__k, ++__j) \ + __a._M_data[*__j] _Op##= __e[__k]; \ + } \ + \ + template<typename _Tp> \ + void \ + _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ + _Array<_Tp> __b, size_t __n) \ + { \ + bool* __ok(__m._M_data); \ + _Tp* __p(__a._M_data); \ + for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; \ + ++__q, ++__ok, ++__p) \ + { \ + while (! *__ok) \ + { \ + ++__ok; \ + ++__p; \ + } \ + *__p _Op##= *__q; \ + } \ + } \ + \ + template<typename _Tp> \ + void \ + _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array<bool> __m) \ + { \ + bool* __ok(__m._M_data); \ + _Tp* __q(__b._M_data); \ + for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ + ++__p, ++__ok, ++__q) \ + { \ + while (! *__ok) \ + { \ + ++__ok; \ + ++__q; \ + } \ + *__p _Op##= *__q; \ + } \ + } \ + \ + template<typename _Tp, class _Dom> \ + void \ + _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ + { \ + bool* __ok(__m._M_data); \ + _Tp* __p(__a._M_data); \ + for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) \ + { \ + while (! *__ok) \ + { \ + ++__ok; \ + ++__p; \ + } \ + *__p _Op##= __e[__i]; \ + } \ + } + + _DEFINE_ARRAY_FUNCTION(+, __plus) + _DEFINE_ARRAY_FUNCTION(-, __minus) + _DEFINE_ARRAY_FUNCTION(*, __multiplies) + _DEFINE_ARRAY_FUNCTION(/, __divides) + _DEFINE_ARRAY_FUNCTION(%, __modulus) + _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor) + _DEFINE_ARRAY_FUNCTION(|, __bitwise_or) + _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) + _DEFINE_ARRAY_FUNCTION(<<, __shift_left) + _DEFINE_ARRAY_FUNCTION(>>, __shift_right) + +#undef _DEFINE_ARRAY_FUNCTION + +_GLIBCXX_END_NAMESPACE + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/valarray_array.tcc> +#endif + +#endif /* _ARRAY_H */ diff --git a/libstdc++/include/bits/valarray_array.tcc b/libstdc++/include/bits/valarray_array.tcc new file mode 100644 index 0000000..f00ffb4 --- /dev/null +++ b/libstdc++/include/bits/valarray_array.tcc @@ -0,0 +1,246 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file valarray_array.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _VALARRAY_ARRAY_TCC +#define _VALARRAY_ARRAY_TCC 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _Tp> + void + __valarray_fill(_Array<_Tp> __a, size_t __n, _Array<bool> __m, + const _Tp& __t) + { + _Tp* __p = __a._M_data; + bool* __ok (__m._M_data); + for (size_t __i=0; __i < __n; ++__i, ++__ok, ++__p) + { + while (!*__ok) + { + ++__ok; + ++__p; + } + *__p = __t; + } + } + + // Copy n elements of a into consecutive elements of b. When m is + // false, the corresponding element of a is skipped. m must contain + // at least n true elements. a must contain at least n elements and + // enough elements to match up with m through the nth true element + // of m. I.e. if n is 10, m has 15 elements with 5 false followed + // by 10 true, a must have 15 elements. + template<typename _Tp> + void + __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b, + size_t __n) + { + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; + ++__q, ++__ok, ++__p) + { + while (! *__ok) + { + ++__ok; + ++__p; + } + *__q = *__p; + } + } + + // Copy n consecutive elements from a into elements of b. Elements + // of b are skipped if the corresponding element of m is false. m + // must contain at least n true elements. b must have at least as + // many elements as the index of the nth true element of m. I.e. if + // m has 15 elements with 5 false followed by 10 true, b must have + // at least 15 elements. + template<typename _Tp> + void + __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + _Array<bool> __m) + { + _Tp* __q (__b._M_data); + bool* __ok (__m._M_data); + for (_Tp* __p = __a._M_data; __p < __a._M_data+__n; + ++__p, ++__ok, ++__q) + { + while (! *__ok) + { + ++__ok; + ++__q; + } + *__q = *__p; + } + } + + // Copy n elements from a into elements of b. Elements of a are + // skipped if the corresponding element of m is false. Elements of + // b are skipped if the corresponding element of k is false. m and + // k must contain at least n true elements. a and b must have at + // least as many elements as the index of the nth true element of m. + template<typename _Tp> + void + __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, size_t __n, + _Array<_Tp> __b, _Array<bool> __k) + { + _Tp* __p (__a._M_data); + _Tp* __q (__b._M_data); + bool* __srcok (__m._M_data); + bool* __dstok (__k._M_data); + for (size_t __i = 0; __i < __n; + ++__srcok, ++__p, ++__dstok, ++__q, ++__i) + { + while (! *__srcok) + { + ++__srcok; + ++__p; + } + while (! *__dstok) + { + ++__dstok; + ++__q; + } + *__q = *__p; + } + } + + // Copy n consecutive elements of e into consecutive elements of a. + // I.e. a[i] = e[i]. + template<typename _Tp, class _Dom> + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a) + { + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, ++__p) + *__p = __e[__i]; + } + + // Copy n consecutive elements of e into elements of a using stride + // s. I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2]. + template<typename _Tp, class _Dom> + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, size_t __s) + { + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, __p += __s) + *__p = __e[__i]; + } + + // Copy n consecutive elements of e into elements of a indexed by + // contents of i. I.e., a[i[0]] = e[0]. + template<typename _Tp, class _Dom> + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array<size_t> __i) + { + size_t* __j (__i._M_data); + for (size_t __k = 0; __k < __n; ++__k, ++__j) + __a._M_data[*__j] = __e[__k]; + } + + // Copy n elements of e indexed by contents of f into elements of a + // indexed by contents of i. I.e., a[i[0]] = e[f[0]]. + template<typename _Tp> + void + __valarray_copy(_Array<_Tp> __e, _Array<size_t> __f, + size_t __n, + _Array<_Tp> __a, _Array<size_t> __i) + { + size_t* __g (__f._M_data); + size_t* __j (__i._M_data); + for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g) + __a._M_data[*__j] = __e._M_data[*__g]; + } + + // Copy n consecutive elements of e into elements of a. Elements of + // a are skipped if the corresponding element of m is false. m must + // have at least n true elements and a must have at least as many + // elements as the index of the nth true element of m. I.e. if m + // has 5 false followed by 10 true elements and n == 10, a must have + // at least 15 elements. + template<typename _Tp, class _Dom> + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array<bool> __m) + { + bool* __ok (__m._M_data); + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) + { + while (! *__ok) + { + ++__ok; + ++__p; + } + *__p = __e[__i]; + } + } + + + template<typename _Tp, class _Dom> + void + __valarray_copy_construct(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a) + { + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, ++__p) + new (__p) _Tp(__e[__i]); + } + + + template<typename _Tp> + void + __valarray_copy_construct(_Array<_Tp> __a, _Array<bool> __m, + _Array<_Tp> __b, size_t __n) + { + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q = __b._M_data; __q < __b._M_data+__n; ++__q, ++__ok, ++__p) + { + while (! *__ok) + { + ++__ok; + ++__p; + } + new (__q) _Tp(*__p); + } + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _VALARRAY_ARRAY_TCC */ diff --git a/libstdc++/include/bits/valarray_before.h b/libstdc++/include/bits/valarray_before.h new file mode 100644 index 0000000..4e3b937 --- /dev/null +++ b/libstdc++/include/bits/valarray_before.h @@ -0,0 +1,735 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file valarray_before.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> + +#ifndef _VALARRAY_BEFORE_H +#define _VALARRAY_BEFORE_H 1 + +#pragma GCC system_header + +#include <bits/slice_array.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // + // Implementing a loosened valarray return value is tricky. + // First we need to meet 26.3.1/3: we should not add more than + // two levels of template nesting. Therefore we resort to template + // template to "flatten" loosened return value types. + // At some point we use partial specialization to remove one level + // template nesting due to _Expr<> + // + + // This class is NOT defined. It doesn't need to. + template<typename _Tp1, typename _Tp2> class _Constant; + + // Implementations of unary functions applied to valarray<>s. + // I use hard-coded object functions here instead of a generic + // approach like pointers to function: + // 1) correctness: some functions take references, others values. + // we can't deduce the correct type afterwards. + // 2) efficiency -- object functions can be easily inlined + // 3) be Koenig-lookup-friendly + + struct __abs + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return abs(__t); } + }; + + struct __cos + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return cos(__t); } + }; + + struct __acos + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return acos(__t); } + }; + + struct __cosh + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return cosh(__t); } + }; + + struct __sin + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return sin(__t); } + }; + + struct __asin + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return asin(__t); } + }; + + struct __sinh + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return sinh(__t); } + }; + + struct __tan + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return tan(__t); } + }; + + struct __atan + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return atan(__t); } + }; + + struct __tanh + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return tanh(__t); } + }; + + struct __exp + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return exp(__t); } + }; + + struct __log + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return log(__t); } + }; + + struct __log10 + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return log10(__t); } + }; + + struct __sqrt + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return sqrt(__t); } + }; + + // In the past, we used to tailor operator applications semantics + // to the specialization of standard function objects (i.e. plus<>, etc.) + // That is incorrect. Therefore we provide our own surrogates. + + struct __unary_plus + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return +__t; } + }; + + struct __negate + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return -__t; } + }; + + struct __bitwise_not + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const + { return ~__t; } + }; + + struct __plus + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + struct __minus + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + struct __multiplies + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + struct __divides + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + struct __modulus + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + struct __bitwise_xor + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x ^ __y; } + }; + + struct __bitwise_and + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x & __y; } + }; + + struct __bitwise_or + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x | __y; } + }; + + struct __shift_left + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x << __y; } + }; + + struct __shift_right + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x >> __y; } + }; + + struct __logical_and + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + struct __logical_or + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + struct __logical_not + { + template<typename _Tp> + bool operator()(const _Tp& __x) const { return !__x; } + }; + + struct __equal_to + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + struct __not_equal_to + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; + + struct __less + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + struct __greater + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + struct __less_equal + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + + struct __greater_equal + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + // The few binary functions we miss. + struct __atan2 + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return atan2(__x, __y); } + }; + + struct __pow + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return pow(__x, __y); } + }; + + + // We need these bits in order to recover the return type of + // some functions/operators now that we're no longer using + // function templates. + template<typename, typename _Tp> + struct __fun + { + typedef _Tp result_type; + }; + + // several specializations for relational operators. + template<typename _Tp> + struct __fun<__logical_not, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__logical_and, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__logical_or, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__less, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__greater, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__less_equal, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__greater_equal, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__equal_to, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__not_equal_to, _Tp> + { + typedef bool result_type; + }; + + // + // Apply function taking a value/const reference closure + // + + template<typename _Dom, typename _Arg> + class _FunBase + { + public: + typedef typename _Dom::value_type value_type; + + _FunBase(const _Dom& __e, value_type __f(_Arg)) + : _M_expr(__e), _M_func(__f) {} + + value_type operator[](size_t __i) const + { return _M_func (_M_expr[__i]); } + + size_t size() const { return _M_expr.size ();} + + private: + const _Dom& _M_expr; + value_type (*_M_func)(_Arg); + }; + + template<class _Dom> + struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> + { + typedef _FunBase<_Dom, typename _Dom::value_type> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} + }; + + template<typename _Tp> + struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp> + { + typedef _FunBase<valarray<_Tp>, _Tp> _Base; + typedef _Tp value_type; + + _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} + }; + + template<class _Dom> + struct _RefFunClos<_Expr, _Dom> + : _FunBase<_Dom, const typename _Dom::value_type&> + { + typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) + : _Base(__e, __f) {} + }; + + template<typename _Tp> + struct _RefFunClos<_ValArray, _Tp> + : _FunBase<valarray<_Tp>, const _Tp&> + { + typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; + typedef _Tp value_type; + + _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) + : _Base(__v, __f) {} + }; + + // + // Unary expression closure. + // + + template<class _Oper, class _Arg> + class _UnBase + { + public: + typedef typename _Arg::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _UnBase(const _Arg& __e) : _M_expr(__e) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr[__i]); } + + size_t size() const { return _M_expr.size(); } + + private: + const _Arg& _M_expr; + }; + + template<class _Oper, class _Dom> + struct _UnClos<_Oper, _Expr, _Dom> + : _UnBase<_Oper, _Dom> + { + typedef _Dom _Arg; + typedef _UnBase<_Oper, _Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnClos(const _Arg& __e) : _Base(__e) {} + }; + + template<class _Oper, typename _Tp> + struct _UnClos<_Oper, _ValArray, _Tp> + : _UnBase<_Oper, valarray<_Tp> > + { + typedef valarray<_Tp> _Arg; + typedef _UnBase<_Oper, valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _UnClos(const _Arg& __e) : _Base(__e) {} + }; + + + // + // Binary expression closure. + // + + template<class _Oper, class _FirstArg, class _SecondArg> + class _BinBase + { + public: + typedef typename _FirstArg::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) + : _M_expr1(__e1), _M_expr2(__e2) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } + + size_t size() const { return _M_expr1.size(); } + + private: + const _FirstArg& _M_expr1; + const _SecondArg& _M_expr2; + }; + + + template<class _Oper, class _Clos> + class _BinBase2 + { + public: + typedef typename _Clos::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase2(const _Clos& __e, const _Vt& __t) + : _M_expr1(__e), _M_expr2(__t) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1[__i], _M_expr2); } + + size_t size() const { return _M_expr1.size(); } + + private: + const _Clos& _M_expr1; + const _Vt& _M_expr2; + }; + + template<class _Oper, class _Clos> + class _BinBase1 + { + public: + typedef typename _Clos::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase1(const _Vt& __t, const _Clos& __e) + : _M_expr1(__t), _M_expr2(__e) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1, _M_expr2[__i]); } + + size_t size() const { return _M_expr2.size(); } + + private: + const _Vt& _M_expr1; + const _Clos& _M_expr2; + }; + + template<class _Oper, class _Dom1, class _Dom2> + struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> + : _BinBase<_Oper, _Dom1, _Dom2> + { + typedef _BinBase<_Oper, _Dom1, _Dom2> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} + }; + + template<class _Oper, typename _Tp> + struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp> + : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > + { + typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) + : _Base(__v, __w) {} + }; + + template<class _Oper, class _Dom> + struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type> + : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> > + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) + : _Base(__e1, __e2) {} + }; + + template<class _Oper, class _Dom> + struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom> + : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) + : _Base(__e1, __e2) {} + }; + + template<class _Oper, class _Dom> + struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type> + : _BinBase2<_Oper, _Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase2<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} + }; + + template<class _Oper, class _Dom> + struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom> + : _BinBase1<_Oper, _Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase1<_Oper, _Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} + }; + + template<class _Oper, typename _Tp> + struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp> + : _BinBase2<_Oper, valarray<_Tp> > + { + typedef _BinBase2<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} + }; + + template<class _Oper, typename _Tp> + struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp> + : _BinBase1<_Oper, valarray<_Tp> > + { + typedef _BinBase1<_Oper, valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} + }; + + // + // slice_array closure. + // + template<typename _Dom> + class _SBase + { + public: + typedef typename _Dom::value_type value_type; + + _SBase (const _Dom& __e, const slice& __s) + : _M_expr (__e), _M_slice (__s) {} + + value_type + operator[] (size_t __i) const + { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } + + size_t + size() const + { return _M_slice.size (); } + + private: + const _Dom& _M_expr; + const slice& _M_slice; + }; + + template<typename _Tp> + class _SBase<_Array<_Tp> > + { + public: + typedef _Tp value_type; + + _SBase (_Array<_Tp> __a, const slice& __s) + : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), + _M_stride (__s.stride()) {} + + value_type + operator[] (size_t __i) const + { return _M_array._M_data[__i * _M_stride]; } + + size_t + size() const + { return _M_size; } + + private: + const _Array<_Tp> _M_array; + const size_t _M_size; + const size_t _M_stride; + }; + + template<class _Dom> + struct _SClos<_Expr, _Dom> + : _SBase<_Dom> + { + typedef _SBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} + }; + + template<typename _Tp> + struct _SClos<_ValArray, _Tp> + : _SBase<_Array<_Tp> > + { + typedef _SBase<_Array<_Tp> > _Base; + typedef _Tp value_type; + + _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} + }; + +_GLIBCXX_END_NAMESPACE + +#endif /* _CPP_VALARRAY_BEFORE_H */ diff --git a/libstdc++/include/bits/vector.tcc b/libstdc++/include/bits/vector.tcc new file mode 100644 index 0000000..f476c46 --- /dev/null +++ b/libstdc++/include/bits/vector.tcc @@ -0,0 +1,496 @@ +// Vector implementation (out of line) -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file vector.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VECTOR_TCC +#define _VECTOR_TCC 1 + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + template<typename _Tp, typename _Alloc> + void + vector<_Tp, _Alloc>:: + reserve(size_type __n) + { + if (__n > this->max_size()) + __throw_length_error(__N("vector::reserve")); + if (this->capacity() < __n) + { + const size_type __old_size = size(); + pointer __tmp = _M_allocate_and_copy(__n, this->_M_impl._M_start, + this->_M_impl._M_finish); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_finish = __tmp + __old_size; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } + } + + template<typename _Tp, typename _Alloc> + typename vector<_Tp, _Alloc>::iterator + vector<_Tp, _Alloc>:: + insert(iterator __position, const value_type& __x) + { + const size_type __n = __position - begin(); + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage + && __position == end()) + { + this->_M_impl.construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(__position, __x); + return iterator(this->_M_impl._M_start + __n); + } + + template<typename _Tp, typename _Alloc> + typename vector<_Tp, _Alloc>::iterator + vector<_Tp, _Alloc>:: + erase(iterator __position) + { + if (__position + 1 != end()) + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + this->_M_impl.destroy(this->_M_impl._M_finish); + return __position; + } + + template<typename _Tp, typename _Alloc> + typename vector<_Tp, _Alloc>::iterator + vector<_Tp, _Alloc>:: + erase(iterator __first, iterator __last) + { + if (__last != end()) + std::copy(__last, end(), __first); + _M_erase_at_end(__first.base() + (end() - __last)); + return __first; + } + + template<typename _Tp, typename _Alloc> + vector<_Tp, _Alloc>& + vector<_Tp, _Alloc>:: + operator=(const vector<_Tp, _Alloc>& __x) + { + if (&__x != this) + { + const size_type __xlen = __x.size(); + if (__xlen > capacity()) + { + pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), + __x.end()); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; + } + else if (size() >= __xlen) + { + std::_Destroy(std::copy(__x.begin(), __x.end(), begin()), + end(), _M_get_Tp_allocator()); + } + else + { + std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(), + this->_M_impl._M_start); + std::__uninitialized_copy_a(__x._M_impl._M_start + size(), + __x._M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + } + this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; + } + return *this; + } + + template<typename _Tp, typename _Alloc> + void + vector<_Tp, _Alloc>:: + _M_fill_assign(size_t __n, const value_type& __val) + { + if (__n > capacity()) + { + vector __tmp(__n, __val, _M_get_Tp_allocator()); + __tmp.swap(*this); + } + else if (__n > size()) + { + std::fill(begin(), end(), __val); + std::__uninitialized_fill_n_a(this->_M_impl._M_finish, + __n - size(), __val, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n - size(); + } + else + _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val)); + } + + template<typename _Tp, typename _Alloc> + template<typename _InputIterator> + void + vector<_Tp, _Alloc>:: + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + pointer __cur(this->_M_impl._M_start); + for (; __first != __last && __cur != this->_M_impl._M_finish; + ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + _M_erase_at_end(__cur); + else + insert(end(), __first, __last); + } + + template<typename _Tp, typename _Alloc> + template<typename _ForwardIterator> + void + vector<_Tp, _Alloc>:: + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + + if (__len > capacity()) + { + pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_finish = this->_M_impl._M_start + __len; + this->_M_impl._M_end_of_storage = this->_M_impl._M_finish; + } + else if (size() >= __len) + _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start)); + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, this->_M_impl._M_start); + this->_M_impl._M_finish = + std::__uninitialized_copy_a(__mid, __last, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + } + } + + template<typename _Tp, typename _Alloc> + void + vector<_Tp, _Alloc>:: + _M_insert_aux(iterator __position, const _Tp& __x) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + this->_M_impl.construct(this->_M_impl._M_finish, + *(this->_M_impl._M_finish - 1)); + ++this->_M_impl._M_finish; + _Tp __x_copy = __x; + std::copy_backward(__position.base(), + this->_M_impl._M_finish - 2, + this->_M_impl._M_finish - 1); + *__position = __x_copy; + } + else + { + const size_type __old_size = size(); + if (__old_size == this->max_size()) + __throw_length_error(__N("vector::_M_insert_aux")); + + // When sizeof(value_type) == 1 and __old_size > size_type(-1)/2 + // __len overflows: if we don't notice and _M_allocate doesn't + // throw we crash badly later. + size_type __len = __old_size != 0 ? 2 * __old_size : 1; + if (__len < __old_size) + __len = this->max_size(); + + pointer __new_start(this->_M_allocate(__len)); + pointer __new_finish(__new_start); + try + { + __new_finish = + std::__uninitialized_copy_a(this->_M_impl._M_start, + __position.base(), __new_start, + _M_get_Tp_allocator()); + this->_M_impl.construct(__new_finish, __x); + ++__new_finish; + __new_finish = + std::__uninitialized_copy_a(__position.base(), + this->_M_impl._M_finish, + __new_finish, + _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); + _M_deallocate(__new_start, __len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start; + this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_end_of_storage = __new_start + __len; + } + } + + template<typename _Tp, typename _Alloc> + void + vector<_Tp, _Alloc>:: + _M_fill_insert(iterator __position, size_type __n, const value_type& __x) + { + if (__n != 0) + { + if (size_type(this->_M_impl._M_end_of_storage + - this->_M_impl._M_finish) >= __n) + { + value_type __x_copy = __x; + const size_type __elems_after = end() - __position; + pointer __old_finish(this->_M_impl._M_finish); + if (__elems_after > __n) + { + std::__uninitialized_copy_a(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n; + std::copy_backward(__position.base(), __old_finish - __n, + __old_finish); + std::fill(__position.base(), __position.base() + __n, + __x_copy); + } + else + { + std::__uninitialized_fill_n_a(this->_M_impl._M_finish, + __n - __elems_after, + __x_copy, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n - __elems_after; + std::__uninitialized_copy_a(__position.base(), __old_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __elems_after; + std::fill(__position.base(), __old_finish, __x_copy); + } + } + else + { + const size_type __old_size = size(); + if (this->max_size() - __old_size < __n) + __throw_length_error(__N("vector::_M_fill_insert")); + + // See _M_insert_aux above. + size_type __len = __old_size + std::max(__old_size, __n); + if (__len < __old_size) + __len = this->max_size(); + + pointer __new_start(this->_M_allocate(__len)); + pointer __new_finish(__new_start); + try + { + __new_finish = + std::__uninitialized_copy_a(this->_M_impl._M_start, + __position.base(), + __new_start, + _M_get_Tp_allocator()); + std::__uninitialized_fill_n_a(__new_finish, __n, __x, + _M_get_Tp_allocator()); + __new_finish += __n; + __new_finish = + std::__uninitialized_copy_a(__position.base(), + this->_M_impl._M_finish, + __new_finish, + _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(__new_start, __new_finish, + _M_get_Tp_allocator()); + _M_deallocate(__new_start, __len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start; + this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_end_of_storage = __new_start + __len; + } + } + } + + template<typename _Tp, typename _Alloc> template<typename _InputIterator> + void + vector<_Tp, _Alloc>:: + _M_range_insert(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag) + { + for (; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template<typename _Tp, typename _Alloc> + template<typename _ForwardIterator> + void + vector<_Tp, _Alloc>:: + _M_range_insert(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag) + { + if (__first != __last) + { + const size_type __n = std::distance(__first, __last); + if (size_type(this->_M_impl._M_end_of_storage + - this->_M_impl._M_finish) >= __n) + { + const size_type __elems_after = end() - __position; + pointer __old_finish(this->_M_impl._M_finish); + if (__elems_after > __n) + { + std::__uninitialized_copy_a(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n; + std::copy_backward(__position.base(), __old_finish - __n, + __old_finish); + std::copy(__first, __last, __position); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elems_after); + std::__uninitialized_copy_a(__mid, __last, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __n - __elems_after; + std::__uninitialized_copy_a(__position.base(), + __old_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish += __elems_after; + std::copy(__first, __mid, __position); + } + } + else + { + const size_type __old_size = size(); + if (this->max_size() - __old_size < __n) + __throw_length_error(__N("vector::_M_range_insert")); + + // See _M_insert_aux above. + size_type __len = __old_size + std::max(__old_size, __n); + if (__len < __old_size) + __len = this->max_size(); + + pointer __new_start(this->_M_allocate(__len)); + pointer __new_finish(__new_start); + try + { + __new_finish = + std::__uninitialized_copy_a(this->_M_impl._M_start, + __position.base(), + __new_start, + _M_get_Tp_allocator()); + __new_finish = + std::__uninitialized_copy_a(__first, __last, __new_finish, + _M_get_Tp_allocator()); + __new_finish = + std::__uninitialized_copy_a(__position.base(), + this->_M_impl._M_finish, + __new_finish, + _M_get_Tp_allocator()); + } + catch(...) + { + std::_Destroy(__new_start, __new_finish, + _M_get_Tp_allocator()); + _M_deallocate(__new_start, __len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start; + this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_end_of_storage = __new_start + __len; + } + } + } + +_GLIBCXX_END_NESTED_NAMESPACE + +#endif /* _VECTOR_TCC */ diff --git a/libstdc++/include/c/std_cassert.h b/libstdc++/include/c/std_cassert.h new file mode 100644 index 0000000..873eeef --- /dev/null +++ b/libstdc++/include/c/std_cassert.h @@ -0,0 +1,38 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 2002 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. + +// +// ISO C++ 14882: 19.2 Assertions +// + +// No include guards on this header... + +#pragma GCC system_header + +#include_next <assert.h> diff --git a/libstdc++/include/c/std_cctype.h b/libstdc++/include/c/std_cctype.h new file mode 100644 index 0000000..103dd37 --- /dev/null +++ b/libstdc++/include/c/std_cctype.h @@ -0,0 +1,41 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: <ccytpe> +// + +#ifndef _GLIBCXX_CCTYPE +#define _GLIBCXX_CCTYPE 1 + +#pragma GCC system_header + +#include_next <ctype.h> + +#endif diff --git a/libstdc++/include/c/std_cerrno.h b/libstdc++/include/c/std_cerrno.h new file mode 100644 index 0000000..e27c361 --- /dev/null +++ b/libstdc++/include/c/std_cerrno.h @@ -0,0 +1,55 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +/** @file cerrno + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c errno.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +// +// ISO C++ 14882: 19.3 Error numbers +// + +#ifndef _GLIBCXX_CERRNO +#define _GLIBCXX_CERRNO 1 + +#pragma GCC system_header + +#include_next <errno.h> + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef errno +#define errno errno +#endif + +#endif diff --git a/libstdc++/include/c/std_cfloat.h b/libstdc++/include/c/std_cfloat.h new file mode 100644 index 0000000..3cf6b9b --- /dev/null +++ b/libstdc++/include/c/std_cfloat.h @@ -0,0 +1,41 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +#ifndef _GLIBCXX_CFLOAT +#define _GLIBCXX_CFLOAT 1 + +#pragma GCC system_header + +#include_next <float.h> + +#endif diff --git a/libstdc++/include/c/std_ciso646.h b/libstdc++/include/c/std_ciso646.h new file mode 100644 index 0000000..4ffd3bb --- /dev/null +++ b/libstdc++/include/c/std_ciso646.h @@ -0,0 +1,37 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2001 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. + +/** @file ciso646 + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c iso646.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ diff --git a/libstdc++/include/c/std_climits.h b/libstdc++/include/c/std_climits.h new file mode 100644 index 0000000..ca9db69 --- /dev/null +++ b/libstdc++/include/c/std_climits.h @@ -0,0 +1,41 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +#ifndef _GLIBCXX_CLIMITS +#define _GLIBCXX_CLIMITS 1 + +#pragma GCC system_header + +#include_next <limits.h> + +#endif diff --git a/libstdc++/include/c/std_clocale.h b/libstdc++/include/c/std_clocale.h new file mode 100644 index 0000000..7642222 --- /dev/null +++ b/libstdc++/include/c/std_clocale.h @@ -0,0 +1,41 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +#ifndef _GLIBCXX_CLOCALE +#define _GLIBCXX_CLOCALE 1 + +#pragma GCC system_header + +#include_next <locale.h> + +#endif diff --git a/libstdc++/include/c/std_cmath.h b/libstdc++/include/c/std_cmath.h new file mode 100644 index 0000000..18c1fb2 --- /dev/null +++ b/libstdc++/include/c/std_cmath.h @@ -0,0 +1,124 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 26.5 C library +// + +#ifndef _GLIBCXX_CMATH +#define _GLIBCXX_CMATH 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +#include_next <math.h> + +// Get rid of those macros defined in <math.h> in lieu of real functions. +#undef abs +#undef div +#undef acos +#undef asin +#undef atan +#undef atan2 +#undef ceil +#undef cos +#undef cosh +#undef exp +#undef fabs +#undef floor +#undef fmod +#undef frexp +#undef ldexp +#undef log +#undef log10 +#undef modf +#undef pow +#undef sin +#undef sinh +#undef sqrt +#undef tan +#undef tanh + +#undef fpclassify +#undef isfinite +#undef isinf +#undef isnan +#undef isnormal +#undef signbit +#undef isgreater +#undef isgreaterequal +#undef isless +#undef islessequal +#undef islessgreater +#undef isunordered + +namespace std +{ + inline double + abs(double __x) + { return __builtin_fabs(__x); } + + inline float + abs(float __x) + { return __builtin_fabsf(__x); } + + inline long double + abs(long double __x) + { return __builtin_fabsl(__x); } + +#if _GLIBCXX_HAVE_MODFF + inline float + modf(float __x, float* __iptr) { return modff(__x, __iptr); } +#else + inline float + modf(float __x, float* __iptr) + { + double __tmp; + double __res = modf(static_cast<double>(__x), &__tmp); + *__iptr = static_cast<float>(__tmp); + return __res; + } +#endif + +#if _GLIBCXX_HAVE_MODFL + inline long double + modf(long double __x, long double* __iptr) { return modfl(__x, __iptr); } +#else + inline long double + modf(long double __x, long double* __iptr) + { + double __tmp; + double __res = modf(static_cast<double>(__x), &__tmp); + * __iptr = static_cast<long double>(__tmp); + return __res; + } +#endif +} +#endif diff --git a/libstdc++/include/c/std_csetjmp.h b/libstdc++/include/c/std_csetjmp.h new file mode 100644 index 0000000..1926bcc --- /dev/null +++ b/libstdc++/include/c/std_csetjmp.h @@ -0,0 +1,49 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSETJMP +#define _GLIBCXX_CSETJMP 1 + +#pragma GCC system_header + +#include_next <setjmp.h> + +// Get rid of those macros defined in <setjmp.h> in lieu of real functions. +#undef longjmp + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef setjmp +#define setjmp(env) std::setjmp (env) +#endif + +#endif diff --git a/libstdc++/include/c/std_csignal.h b/libstdc++/include/c/std_csignal.h new file mode 100644 index 0000000..37bacae --- /dev/null +++ b/libstdc++/include/c/std_csignal.h @@ -0,0 +1,41 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSIGNAL +#define _GLIBCXX_CSIGNAL 1 + +#pragma GCC system_header + +#include_next <signal.h> + +#endif diff --git a/libstdc++/include/c/std_cstdarg.h b/libstdc++/include/c/std_cstdarg.h new file mode 100644 index 0000000..00aa001 --- /dev/null +++ b/libstdc++/include/c/std_cstdarg.h @@ -0,0 +1,42 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSTDARG +#define _GLIBCXX_CSTDARG 1 + +#pragma GCC system_header + +#undef __need___va_list +#include_next <stdarg.h> + +#endif diff --git a/libstdc++/include/c/std_cstddef.h b/libstdc++/include/c/std_cstddef.h new file mode 100644 index 0000000..33269af --- /dev/null +++ b/libstdc++/include/c/std_cstddef.h @@ -0,0 +1,45 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 18.1 Types +// + +#ifndef _GLIBCXX_CSTDDEF +#define _GLIBCXX_CSTDDEF 1 + +#pragma GCC system_header + +#define __need_size_t +#define __need_ptrdiff_t +#define __need_NULL +#define __need_offsetof +#include_next <stddef.h> + +#endif diff --git a/libstdc++/include/c/std_cstdio.h b/libstdc++/include/c/std_cstdio.h new file mode 100644 index 0000000..5cb8bcf --- /dev/null +++ b/libstdc++/include/c/std_cstdio.h @@ -0,0 +1,84 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 27.8.2 C Library files +// + +#ifndef _GLIBCXX_CSTDIO +#define _GLIBCXX_CSTDIO 1 + +#pragma GCC system_header + +#include_next <stdio.h> + +// Get rid of those macros defined in <stdio.h> in lieu of real functions. +#undef clearerr +#undef fclose +#undef feof +#undef ferror +#undef fflush +#undef fgetc +#undef fgetpos +#undef fgets +#undef fopen +#undef fprintf +#undef fputc +#undef fputs +#undef fread +#undef freopen +#undef fscanf +#undef fseek +#undef fsetpos +#undef ftell +#undef fwrite +#undef getc +#undef getchar +#undef gets +#undef perror +#undef printf +#undef putc +#undef putchar +#undef puts +#undef remove +#undef rename +#undef rewind +#undef scanf +#undef setbuf +#undef setvbuf +#undef sprintf +#undef sscanf +#undef tmpfile +#undef tmpnam +#undef ungetc +#undef vfprintf +#undef vprintf +#undef vsprintf + +#endif diff --git a/libstdc++/include/c/std_cstdlib.h b/libstdc++/include/c/std_cstdlib.h new file mode 100644 index 0000000..85f5bf7 --- /dev/null +++ b/libstdc++/include/c/std_cstdlib.h @@ -0,0 +1,41 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSTDLIB +#define _GLIBCXX_CSTDLIB 1 + +#pragma GCC system_header + +#include_next <stdlib.h> + +#endif diff --git a/libstdc++/include/c/std_cstring.h b/libstdc++/include/c/std_cstring.h new file mode 100644 index 0000000..ed7719c --- /dev/null +++ b/libstdc++/include/c/std_cstring.h @@ -0,0 +1,41 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 2002 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. + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSTRING +#define _GLIBCXX_CSTRING 1 + +#pragma GCC system_header + +#include_next <string.h> + +#endif diff --git a/libstdc++/include/c/std_ctime.h b/libstdc++/include/c/std_ctime.h new file mode 100644 index 0000000..1d2bd3f --- /dev/null +++ b/libstdc++/include/c/std_ctime.h @@ -0,0 +1,41 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 20.5 Date and time +// + +#ifndef _GLIBCXX_CTIME +#define _GLIBCXX_CTIME 1 + +#pragma GCC system_header + +#include_next <time.h> + +#endif diff --git a/libstdc++/include/c/std_cwchar.h b/libstdc++/include/c/std_cwchar.h new file mode 100644 index 0000000..69576b5 --- /dev/null +++ b/libstdc++/include/c/std_cwchar.h @@ -0,0 +1,62 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: 21.4 +// + +#ifndef _GLIBCXX_CWCHAR +#define _GLIBCXX_CWCHAR 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <cstddef> +#include <ctime> + +#if _GLIBCXX_HAVE_WCHAR_H +#include_next <wchar.h> +#endif + +// Need to do a bit of trickery here with mbstate_t as char_traits +// assumes it is in wchar.h, regardless of wchar_t specializations. +#ifndef _GLIBCXX_HAVE_MBSTATE_T +namespace std +{ + extern "C" + { + typedef struct + { + int __fill[6]; + } mbstate_t; + } +} +#endif + +#endif diff --git a/libstdc++/include/c/std_cwctype.h b/libstdc++/include/c/std_cwctype.h new file mode 100644 index 0000000..a916760 --- /dev/null +++ b/libstdc++/include/c/std_cwctype.h @@ -0,0 +1,45 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2000, 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. + +// +// ISO C++ 14882: <cwctype> +// + +#ifndef _GLIBCXX_CWCTYPE +#define _GLIBCXX_CWCTYPE 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +#if _GLIBCXX_HAVE_WCTYPE_H +#include_next <wctype.h> +#endif + +#endif diff --git a/libstdc++/include/c_compatibility/assert.h b/libstdc++/include/c_compatibility/assert.h new file mode 100644 index 0000000..fc14c0f --- /dev/null +++ b/libstdc++/include/c_compatibility/assert.h @@ -0,0 +1,30 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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 <cassert> diff --git a/libstdc++/include/c_compatibility/ctype.h b/libstdc++/include/c_compatibility/ctype.h new file mode 100644 index 0000000..1bd379d --- /dev/null +++ b/libstdc++/include/c_compatibility/ctype.h @@ -0,0 +1,49 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_CTYPE_H +#define _GLIBCXX_CTYPE_H 1 + +#include <cctype> + +using std::isalnum; +using std::isalpha; +using std::iscntrl; +using std::isdigit; +using std::isgraph; +using std::islower; +using std::isprint; +using std::ispunct; +using std::isspace; +using std::isupper; +using std::isxdigit; +using std::tolower; +using std::toupper; + +#endif diff --git a/libstdc++/include/c_compatibility/errno.h b/libstdc++/include/c_compatibility/errno.h new file mode 100644 index 0000000..d7cc829 --- /dev/null +++ b/libstdc++/include/c_compatibility/errno.h @@ -0,0 +1,35 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_ERRNO_H +#define _GLIBCXX_ERRNO_H 1 + +#include <cerrno> + +#endif diff --git a/libstdc++/include/c_compatibility/float.h b/libstdc++/include/c_compatibility/float.h new file mode 100644 index 0000000..adeb73f --- /dev/null +++ b/libstdc++/include/c_compatibility/float.h @@ -0,0 +1,35 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_FLOAT_H +#define _GLIBCXX_FLOAT_H 1 + +#include <cfloat> + +#endif diff --git a/libstdc++/include/c_compatibility/iso646.h b/libstdc++/include/c_compatibility/iso646.h new file mode 100644 index 0000000..d5097ca --- /dev/null +++ b/libstdc++/include/c_compatibility/iso646.h @@ -0,0 +1,35 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_ISO646_H +#define _GLIBCXX_ISO646_H 1 + +#include <ciso646> + +#endif diff --git a/libstdc++/include/c_compatibility/limits.h b/libstdc++/include/c_compatibility/limits.h new file mode 100644 index 0000000..e7abd01 --- /dev/null +++ b/libstdc++/include/c_compatibility/limits.h @@ -0,0 +1,35 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_LIMITS_H +#define _GLIBCXX_LIMITS_H 1 + +#include <climits> + +#endif diff --git a/libstdc++/include/c_compatibility/locale.h b/libstdc++/include/c_compatibility/locale.h new file mode 100644 index 0000000..8baf041 --- /dev/null +++ b/libstdc++/include/c_compatibility/locale.h @@ -0,0 +1,39 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_LOCALE_H +#define _GLIBCXX_LOCALE_H 1 + +#include <clocale> + +using std::lconv; +using std::setlocale; +using std::localeconv; + +#endif diff --git a/libstdc++/include/c_compatibility/math.h b/libstdc++/include/c_compatibility/math.h new file mode 100644 index 0000000..38636e6 --- /dev/null +++ b/libstdc++/include/c_compatibility/math.h @@ -0,0 +1,74 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_MATH_H +#define _GLIBCXX_MATH_H 1 + +#include <cmath> + +using std::abs; +using std::acos; +using std::asin; +using std::atan; +using std::atan2; +using std::cos; +using std::sin; +using std::tan; +using std::cosh; +using std::sinh; +using std::tanh; +using std::exp; +using std::frexp; +using std::ldexp; +using std::log; +using std::log10; +using std::modf; +using std::pow; +using std::sqrt; +using std::ceil; +using std::fabs; +using std::floor; +using std::fmod; + +#if _GLIBCXX_USE_C99 +using std::fpclassify; +using std::isfinite; +using std::isinf; +using std::isnan; +using std::isnormal; +using std::signbit; +using std::isgreater; +using std::isgreaterequal; +using std::isless; +using std::islessequal; +using std::islessgreater; +using std::isunordered; +#endif + +#endif diff --git a/libstdc++/include/c_compatibility/setjmp.h b/libstdc++/include/c_compatibility/setjmp.h new file mode 100644 index 0000000..f2d481a --- /dev/null +++ b/libstdc++/include/c_compatibility/setjmp.h @@ -0,0 +1,38 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_SETJMP_H +#define _GLIBCXX_SETJMP_H 1 + +#include <csetjmp> + +using std::jmp_buf; +using std::longjmp; + +#endif diff --git a/libstdc++/include/c_compatibility/signal.h b/libstdc++/include/c_compatibility/signal.h new file mode 100644 index 0000000..ae1d23d --- /dev/null +++ b/libstdc++/include/c_compatibility/signal.h @@ -0,0 +1,40 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_SIGNAL_H +#define _GLIBCXX_SIGNAL_H 1 + +#include <csignal> + +using std::sig_atomic_t; + +using std::raise; +using std::signal; + +#endif diff --git a/libstdc++/include/c_compatibility/stdarg.h b/libstdc++/include/c_compatibility/stdarg.h new file mode 100644 index 0000000..9b92a93 --- /dev/null +++ b/libstdc++/include/c_compatibility/stdarg.h @@ -0,0 +1,37 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_STDARG_H +#define _GLIBCXX_STDARG_H 1 + +#include <cstdarg> + +using std::va_list; + +#endif diff --git a/libstdc++/include/c_compatibility/stddef.h b/libstdc++/include/c_compatibility/stddef.h new file mode 100644 index 0000000..457cd00 --- /dev/null +++ b/libstdc++/include/c_compatibility/stddef.h @@ -0,0 +1,38 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_STDDEF_H +#define _GLIBCXX_STDDEF_H 1 + +#include <cstddef> + +using std::size_t; +using std::ptrdiff_t; + +#endif diff --git a/libstdc++/include/c_compatibility/stdio.h b/libstdc++/include/c_compatibility/stdio.h new file mode 100644 index 0000000..270852f --- /dev/null +++ b/libstdc++/include/c_compatibility/stdio.h @@ -0,0 +1,85 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_STDIO_H +#define _GLIBCXX_STDIO_H 1 + +#include <cstdio> + +using std::FILE; +using std::fpos_t; + +using std::remove; +using std::rename; +using std::tmpfile; +using std::tmpnam; +using std::fclose; +using std::fflush; +using std::fopen; +using std::freopen; +using std::setbuf; +using std::setvbuf; +using std::fprintf; +using std::fscanf; +using std::printf; +using std::scanf; +using std::snprintf; +using std::sprintf; +using std::sscanf; +using std::vfprintf; +using std::vfscanf; +using std::vprintf; +using std::vscanf; +using std::vsnprintf; +using std::vsprintf; +using std::vsscanf; +using std::fgetc; +using std::fgets; +using std::fputc; +using std::fputs; +using std::getc; +using std::getchar; +using std::gets; +using std::putc; +using std::putchar; +using std::puts; +using std::ungetc; +using std::fread; +using std::fwrite; +using std::fgetpos; +using std::fseek; +using std::fsetpos; +using std::ftell; +using std::rewind; +using std::clearerr; +using std::feof; +using std::ferror; +using std::perror; + +#endif diff --git a/libstdc++/include/c_compatibility/stdlib.h b/libstdc++/include/c_compatibility/stdlib.h new file mode 100644 index 0000000..dbf99b4 --- /dev/null +++ b/libstdc++/include/c_compatibility/stdlib.h @@ -0,0 +1,67 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_STDLIB_H +#define _GLIBCXX_STDLIB_H 1 + +#include <cstdlib> + +using std::div_t; +using std::ldiv_t; + +using std::abort; +using std::abs; +using std::atexit; +using std::atof; +using std::atoi; +using std::atol; +using std::bsearch; +using std::calloc; +using std::div; +using std::exit; +using std::free; +using std::getenv; +using std::labs; +using std::ldiv; +using std::malloc; +using std::mblen; +using std::mbstowcs; +using std::mbtowc; +using std::qsort; +using std::rand; +using std::realloc; +using std::srand; +using std::strtod; +using std::strtol; +using std::strtoul; +using std::system; +using std::wcstombs; +using std::wctomb; + +#endif diff --git a/libstdc++/include/c_compatibility/string.h b/libstdc++/include/c_compatibility/string.h new file mode 100644 index 0000000..09e59cf --- /dev/null +++ b/libstdc++/include/c_compatibility/string.h @@ -0,0 +1,58 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_STRING_H +#define _GLIBCXX_STRING_H 1 + +#include <cstring> + +using std::memcpy; +using std::memmove; +using std::strcpy; +using std::strncpy; +using std::strcat; +using std::strncat; +using std::memcmp; +using std::strcmp; +using std::strcoll; +using std::strncmp; +using std::strxfrm; +using std::memchr; +using std::strchr; +using std::strcspn; +using std::strpbrk; +using std::strrchr; +using std::strspn; +using std::strstr; +using std::strtok; +using std::memset; +using std::strerror; +using std::strlen; + +#endif diff --git a/libstdc++/include/c_compatibility/time.h b/libstdc++/include/c_compatibility/time.h new file mode 100644 index 0000000..d5684ad --- /dev/null +++ b/libstdc++/include/c_compatibility/time.h @@ -0,0 +1,60 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_TIME_H +#define _GLIBCXX_TIME_H 1 + +#include <ctime> + +// Get rid of those macros defined in <time.h> in lieu of real functions. +#undef clock +#undef difftime +#undef mktime +#undef time +#undef asctime +#undef ctime +#undef gmtime +#undef localtime +#undef strftime + +using std::clock_t; +using std::time_t; +using std::tm; + +using std::clock; +using std::difftime; +using std::mktime; +using std::time; +using std::asctime; +using std::ctime; +using std::gmtime; +using std::localtime; +using std::strftime; + +#endif diff --git a/libstdc++/include/c_compatibility/wchar.h b/libstdc++/include/c_compatibility/wchar.h new file mode 100644 index 0000000..2071ae4 --- /dev/null +++ b/libstdc++/include/c_compatibility/wchar.h @@ -0,0 +1,114 @@ +// -*- C++ -*- compatibility header. + +// 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. + +#ifndef _GLIBCXX_WCHAR_H +#define _GLIBCXX_WCHAR_H 1 + +#include <cwchar> + +using std::mbstate_t; + +#if _GLIBCXX_USE_WCHAR_T +using std::wint_t; + +using std::btowc; +using std::wctob; +using std::fgetwc; +using std::fgetwc; +using std::fgetws; +using std::fputwc; +using std::fputws; +using std::fwide; +using std::fwprintf; +using std::fwscanf; +using std::swprintf; +using std::swscanf; +using std::vfwprintf; +#if _GLIBCXX_HAVE_VFWSCANF +using std::vfwscanf; +#endif +using std::vswprintf; +#if _GLIBCXX_HAVE_VSWSCANF +using std::vswscanf; +#endif +using std::vwprintf; +#if _GLIBCXX_HAVE_VWSCANF +using std::vwscanf; +#endif +using std::wprintf; +using std::wscanf; +using std::getwc; +using std::getwchar; +using std::mbsinit; +using std::mbrlen; +using std::mbrtowc; +using std::mbsrtowcs; +using std::wcsrtombs; +using std::putwc; +using std::putwchar; +using std::ungetwc; +using std::wcrtomb; +using std::wcstod; +#if _GLIBCXX_HAVE_WCSTOF +using std::wcstof; +#endif +using std::wcstol; +using std::wcstoul; +using std::wcscpy; +using std::wcsncpy; +using std::wcscat; +using std::wcsncat; +using std::wcscmp; +using std::wcscoll; +using std::wcsncmmp; +using std::wcsxfrm; +using std::wcschr; +using std::wcscspn; +using std::wcslen; +using std::wcspbrk; +using std::wcsrchr; +using std::wcsspn; +using std::wcsstr; +using std::wcstok; +using std::wmemchr; +using std::wmemcmp; +using std::wmemcpy; +using std::wmemmove; +using std::wmemset; +using std::wcsftime; + +#if _GLIBCXX_USE_C99 +using std::wcstold; +using std::wcstoll; +using std::wcstoull; +#endif + +#endif //_GLIBCXX_USE_WCHAR_T + +#endif diff --git a/libstdc++/include/c_compatibility/wctype.h b/libstdc++/include/c_compatibility/wctype.h new file mode 100644 index 0000000..c7ddc90 --- /dev/null +++ b/libstdc++/include/c_compatibility/wctype.h @@ -0,0 +1,55 @@ +// -*- C++ -*- compatibility header. + +// Copyright (C) 2002 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_CWCTYPE_H +#define _GLIBCXX_CWCTYPE_H 1 + +#include <cwctype> + +using std::wctype_t; +using std::wctrans_t; +using std::iswalpha; +using std::iswupper; +using std::iswlower; +using std::iswdigit; +using std::iswxdigit; +using std::iswalnum; +using std::iswspace; +using std::iswpunct; +using std::iswprint; +using std::iswgraph; +using std::iswcntrl; +using std::iswctype; +using std::towctrans; +using std::towlower; +using std::towupper; +using std::wctrans; +using std::wctype; + +#endif diff --git a/libstdc++/include/c_std/cmath.tcc b/libstdc++/include/c_std/cmath.tcc new file mode 100644 index 0000000..472324a --- /dev/null +++ b/libstdc++/include/c_std/cmath.tcc @@ -0,0 +1,59 @@ +// -*- C++ -*- C math library. + +// Copyright (C) 2000, 2003, 2004, 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 was written by Gabriel Dos Reis <gdr@codesourcery.com> + +/** @file cmath.tcc + * This is a Standard C++ Library file. + */ + +#ifndef _GLIBCXX_CMATH_TCC +#define _GLIBCXX_CMATH_TCC 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _Tp> + inline _Tp + __cmath_power(_Tp __x, unsigned int __n) + { + _Tp __y = __n % 2 ? __x : 1; + + while (__n >>= 1) + { + __x = __x * __x; + if (__n % 2) + __y = __y * __x; + } + + return __y; + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/c_std/std_cassert.h b/libstdc++/include/c_std/std_cassert.h new file mode 100644 index 0000000..0e5c77a --- /dev/null +++ b/libstdc++/include/c_std/std_cassert.h @@ -0,0 +1,49 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file cassert + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c assert.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 19.2 Assertions +// + +// No include guards on this header... + +#pragma GCC system_header + +#include <assert.h> diff --git a/libstdc++/include/c_std/std_cctype.h b/libstdc++/include/c_std/std_cctype.h new file mode 100644 index 0000000..61a55cb --- /dev/null +++ b/libstdc++/include/c_std/std_cctype.h @@ -0,0 +1,86 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file include/cctype + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c ctype.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: <ccytpe> +// + +#ifndef _GLIBCXX_CCTYPE +#define _GLIBCXX_CCTYPE 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <ctype.h> + +// Get rid of those macros defined in <ctype.h> in lieu of real functions. +#undef isalnum +#undef isalpha +#undef iscntrl +#undef isdigit +#undef isgraph +#undef islower +#undef isprint +#undef ispunct +#undef isspace +#undef isupper +#undef isxdigit +#undef tolower +#undef toupper + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::isalnum; + using ::isalpha; + using ::iscntrl; + using ::isdigit; + using ::isgraph; + using ::islower; + using ::isprint; + using ::ispunct; + using ::isspace; + using ::isupper; + using ::isxdigit; + using ::tolower; + using ::toupper; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/c_std/std_cerrno.h b/libstdc++/include/c_std/std_cerrno.h new file mode 100644 index 0000000..e597b8f --- /dev/null +++ b/libstdc++/include/c_std/std_cerrno.h @@ -0,0 +1,57 @@ +// The -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file cerrno + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c errno.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 19.3 Error numbers +// + +#ifndef _GLIBCXX_CERRNO +#define _GLIBCXX_CERRNO 1 + +#pragma GCC system_header + +#include <errno.h> + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef errno +#define errno errno +#endif + +#endif diff --git a/libstdc++/include/c_std/std_cfloat.h b/libstdc++/include/c_std/std_cfloat.h new file mode 100644 index 0000000..2b51449 --- /dev/null +++ b/libstdc++/include/c_std/std_cfloat.h @@ -0,0 +1,52 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file include/cfloat + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c float.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +#ifndef _GLIBCXX_CFLOAT +#define _GLIBCXX_CFLOAT 1 + +#pragma GCC system_header + +#include <float.h> + +#endif diff --git a/libstdc++/include/c_std/std_ciso646.h b/libstdc++/include/c_std/std_ciso646.h new file mode 100644 index 0000000..3e391b4 --- /dev/null +++ b/libstdc++/include/c_std/std_ciso646.h @@ -0,0 +1,38 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2001, 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. + +/** @file ciso646 + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c iso646.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ diff --git a/libstdc++/include/c_std/std_climits.h b/libstdc++/include/c_std/std_climits.h new file mode 100644 index 0000000..e85869f --- /dev/null +++ b/libstdc++/include/c_std/std_climits.h @@ -0,0 +1,52 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file include/climits + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c limits.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +#ifndef _GLIBCXX_CLIMITS +#define _GLIBCXX_CLIMITS 1 + +#pragma GCC system_header + +#include <limits.h> + +#endif diff --git a/libstdc++/include/c_std/std_clocale.h b/libstdc++/include/c_std/std_clocale.h new file mode 100644 index 0000000..51e6440 --- /dev/null +++ b/libstdc++/include/c_std/std_clocale.h @@ -0,0 +1,65 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file clocale + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c locale.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +#ifndef _GLIBCXX_CLOCALE +#define _GLIBCXX_CLOCALE 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <locale.h> + +// Get rid of those macros defined in <locale.h> in lieu of real functions. +#undef setlocale +#undef localeconv + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::lconv; + using ::setlocale; + using ::localeconv; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/c_std/std_cmath.h b/libstdc++/include/c_std/std_cmath.h new file mode 100644 index 0000000..897290a --- /dev/null +++ b/libstdc++/include/c_std/std_cmath.h @@ -0,0 +1,600 @@ +// -*- C++ -*- C forwarding header. + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file include/cmath + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c math.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 26.5 C library +// + +#ifndef _GLIBCXX_CMATH +#define _GLIBCXX_CMATH 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/cpp_type_traits.h> +#include <ext/type_traits.h> + +#include <math.h> + +// Get rid of those macros defined in <math.h> in lieu of real functions. +#undef abs +#undef div +#undef acos +#undef asin +#undef atan +#undef atan2 +#undef ceil +#undef cos +#undef cosh +#undef exp +#undef fabs +#undef floor +#undef fmod +#undef frexp +#undef ldexp +#undef log +#undef log10 +#undef modf +#undef pow +#undef sin +#undef sinh +#undef sqrt +#undef tan +#undef tanh + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Forward declaration of a helper function. This really should be + // an `exported' forward declaration. + template<typename _Tp> _Tp __cmath_power(_Tp, unsigned int); + + inline double + abs(double __x) + { return __builtin_fabs(__x); } + + inline float + abs(float __x) + { return __builtin_fabsf(__x); } + + inline long double + abs(long double __x) + { return __builtin_fabsl(__x); } + + using ::acos; + + inline float + acos(float __x) + { return __builtin_acosf(__x); } + + inline long double + acos(long double __x) + { return __builtin_acosl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + acos(_Tp __x) + { return __builtin_acos(__x); } + + using ::asin; + + inline float + asin(float __x) + { return __builtin_asinf(__x); } + + inline long double + asin(long double __x) + { return __builtin_asinl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + asin(_Tp __x) + { return __builtin_asin(__x); } + + using ::atan; + + inline float + atan(float __x) + { return __builtin_atanf(__x); } + + inline long double + atan(long double __x) + { return __builtin_atanl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + atan(_Tp __x) + { return __builtin_atan(__x); } + + using ::atan2; + + inline float + atan2(float __y, float __x) + { return __builtin_atan2f(__y, __x); } + + inline long double + atan2(long double __y, long double __x) + { return __builtin_atan2l(__y, __x); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value + && __is_integer<_Up>::__value, + double>::__type + atan2(_Tp __y, _Up __x) + { return __builtin_atan2(__y, __x); } + + using ::ceil; + + inline float + ceil(float __x) + { return __builtin_ceilf(__x); } + + inline long double + ceil(long double __x) + { return __builtin_ceill(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + ceil(_Tp __x) + { return __builtin_ceil(__x); } + + using ::cos; + + inline float + cos(float __x) + { return __builtin_cosf(__x); } + + inline long double + cos(long double __x) + { return __builtin_cosl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + cos(_Tp __x) + { return __builtin_cos(__x); } + + using ::cosh; + + inline float + cosh(float __x) + { return __builtin_coshf(__x); } + + inline long double + cosh(long double __x) + { return __builtin_coshl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + cosh(_Tp __x) + { return __builtin_cosh(__x); } + + using ::exp; + + inline float + exp(float __x) + { return __builtin_expf(__x); } + + inline long double + exp(long double __x) + { return __builtin_expl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + exp(_Tp __x) + { return __builtin_exp(__x); } + + using ::fabs; + + inline float + fabs(float __x) + { return __builtin_fabsf(__x); } + + inline long double + fabs(long double __x) + { return __builtin_fabsl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + fabs(_Tp __x) + { return __builtin_fabs(__x); } + + using ::floor; + + inline float + floor(float __x) + { return __builtin_floorf(__x); } + + inline long double + floor(long double __x) + { return __builtin_floorl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + floor(_Tp __x) + { return __builtin_floor(__x); } + + using ::fmod; + + inline float + fmod(float __x, float __y) + { return __builtin_fmodf(__x, __y); } + + inline long double + fmod(long double __x, long double __y) + { return __builtin_fmodl(__x, __y); } + + using ::frexp; + + inline float + frexp(float __x, int* __exp) + { return __builtin_frexpf(__x, __exp); } + + inline long double + frexp(long double __x, int* __exp) + { return __builtin_frexpl(__x, __exp); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + frexp(_Tp __x, int* __exp) + { return __builtin_frexp(__x, __exp); } + + using ::ldexp; + + inline float + ldexp(float __x, int __exp) + { return __builtin_ldexpf(__x, __exp); } + + inline long double + ldexp(long double __x, int __exp) + { return __builtin_ldexpl(__x, __exp); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + ldexp(_Tp __x, int __exp) + { return __builtin_ldexp(__x, __exp); } + + using ::log; + + inline float + log(float __x) + { return __builtin_logf(__x); } + + inline long double + log(long double __x) + { return __builtin_logl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + log(_Tp __x) + { return __builtin_log(__x); } + + using ::log10; + + inline float + log10(float __x) + { return __builtin_log10f(__x); } + + inline long double + log10(long double __x) + { return __builtin_log10l(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + log10(_Tp __x) + { return __builtin_log10(__x); } + + using ::modf; + + inline float + modf(float __x, float* __iptr) + { return __builtin_modff(__x, __iptr); } + + inline long double + modf(long double __x, long double* __iptr) + { return __builtin_modfl(__x, __iptr); } + + template<typename _Tp> + inline _Tp + __pow_helper(_Tp __x, int __n) + { + return __n < 0 + ? _Tp(1)/__cmath_power(__x, -__n) + : __cmath_power(__x, __n); + } + + using ::pow; + + inline float + pow(float __x, float __y) + { return __builtin_powf(__x, __y); } + + inline long double + pow(long double __x, long double __y) + { return __builtin_powl(__x, __y); } + + inline double + pow(double __x, int __i) + { return __builtin_powi(__x, __i); } + + inline float + pow(float __x, int __n) + { return __builtin_powif(__x, __n); } + + inline long double + pow(long double __x, int __n) + { return __builtin_powil(__x, __n); } + + using ::sin; + + inline float + sin(float __x) + { return __builtin_sinf(__x); } + + inline long double + sin(long double __x) + { return __builtin_sinl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + sin(_Tp __x) + { return __builtin_sin(__x); } + + using ::sinh; + + inline float + sinh(float __x) + { return __builtin_sinhf(__x); } + + inline long double + sinh(long double __x) + { return __builtin_sinhl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + sinh(_Tp __x) + { return __builtin_sinh(__x); } + + using ::sqrt; + + inline float + sqrt(float __x) + { return __builtin_sqrtf(__x); } + + inline long double + sqrt(long double __x) + { return __builtin_sqrtl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + sqrt(_Tp __x) + { return __builtin_sqrt(__x); } + + using ::tan; + + inline float + tan(float __x) + { return __builtin_tanf(__x); } + + inline long double + tan(long double __x) + { return __builtin_tanl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + tan(_Tp __x) + { return __builtin_tan(__x); } + + using ::tanh; + + inline float + tanh(float __x) + { return __builtin_tanhf(__x); } + + inline long double + tanh(long double __x) + { return __builtin_tanhl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + tanh(_Tp __x) + { return __builtin_tanh(__x); } + +_GLIBCXX_END_NAMESPACE + +#if _GLIBCXX_USE_C99_MATH +#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +// These are possible macros imported from C99-land. For strict +// conformance, remove possible C99-injected names from the global +// namespace, and sequester them in the __gnu_cxx extension namespace. + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _Tp> + inline int + __capture_fpclassify(_Tp __f) { return fpclassify(__f); } + + template<typename _Tp> + inline int + __capture_isfinite(_Tp __f) { return isfinite(__f); } + + template<typename _Tp> + inline int + __capture_isinf(_Tp __f) { return isinf(__f); } + + template<typename _Tp> + inline int + __capture_isnan(_Tp __f) { return isnan(__f); } + + template<typename _Tp> + inline int + __capture_isnormal(_Tp __f) { return isnormal(__f); } + + template<typename _Tp> + inline int + __capture_signbit(_Tp __f) { return signbit(__f); } + + template<typename _Tp> + inline int + __capture_isgreater(_Tp __f1, _Tp __f2) + { return isgreater(__f1, __f2); } + + template<typename _Tp> + inline int + __capture_isgreaterequal(_Tp __f1, _Tp __f2) + { return isgreaterequal(__f1, __f2); } + + template<typename _Tp> + inline int + __capture_isless(_Tp __f1, _Tp __f2) { return isless(__f1, __f2); } + + template<typename _Tp> + inline int + __capture_islessequal(_Tp __f1, _Tp __f2) + { return islessequal(__f1, __f2); } + + template<typename _Tp> + inline int + __capture_islessgreater(_Tp __f1, _Tp __f2) + { return islessgreater(__f1, __f2); } + + template<typename _Tp> + inline int + __capture_isunordered(_Tp __f1, _Tp __f2) + { return isunordered(__f1, __f2); } + +_GLIBCXX_END_NAMESPACE + +// Only undefine the C99 FP macros, if actually captured for namespace movement +#undef fpclassify +#undef isfinite +#undef isinf +#undef isnan +#undef isnormal +#undef signbit +#undef isgreater +#undef isgreaterequal +#undef isless +#undef islessequal +#undef islessgreater +#undef isunordered + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _Tp> + inline int + fpclassify(_Tp __f) { return ::__gnu_cxx::__capture_fpclassify(__f); } + + template<typename _Tp> + inline int + isfinite(_Tp __f) { return ::__gnu_cxx::__capture_isfinite(__f); } + + template<typename _Tp> + inline int + isinf(_Tp __f) { return ::__gnu_cxx::__capture_isinf(__f); } + + template<typename _Tp> + inline int + isnan(_Tp __f) { return ::__gnu_cxx::__capture_isnan(__f); } + + template<typename _Tp> + inline int + isnormal(_Tp __f) { return ::__gnu_cxx::__capture_isnormal(__f); } + + template<typename _Tp> + inline int + signbit(_Tp __f) { return ::__gnu_cxx::__capture_signbit(__f); } + + template<typename _Tp> + inline int + isgreater(_Tp __f1, _Tp __f2) + { return ::__gnu_cxx::__capture_isgreater(__f1, __f2); } + + template<typename _Tp> + inline int + isgreaterequal(_Tp __f1, _Tp __f2) + { return ::__gnu_cxx::__capture_isgreaterequal(__f1, __f2); } + + template<typename _Tp> + inline int + isless(_Tp __f1, _Tp __f2) + { return ::__gnu_cxx::__capture_isless(__f1, __f2); } + + template<typename _Tp> + inline int + islessequal(_Tp __f1, _Tp __f2) + { return ::__gnu_cxx::__capture_islessequal(__f1, __f2); } + + template<typename _Tp> + inline int + islessgreater(_Tp __f1, _Tp __f2) + { return ::__gnu_cxx::__capture_islessgreater(__f1, __f2); } + + template<typename _Tp> + inline int + isunordered(_Tp __f1, _Tp __f2) + { return ::__gnu_cxx::__capture_isunordered(__f1, __f2); } + +_GLIBCXX_END_NAMESPACE + +#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ +#endif + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/cmath.tcc> +#endif + +#endif diff --git a/libstdc++/include/c_std/std_csetjmp.h b/libstdc++/include/c_std/std_csetjmp.h new file mode 100644 index 0000000..946e7e3 --- /dev/null +++ b/libstdc++/include/c_std/std_csetjmp.h @@ -0,0 +1,68 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file csetjmp + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c setjmp.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSETJMP +#define _GLIBCXX_CSETJMP 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <setjmp.h> + +// Get rid of those macros defined in <setjmp.h> in lieu of real functions. +#undef longjmp + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef setjmp +#define setjmp(env) setjmp (env) +#endif + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::jmp_buf; + using ::longjmp; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/c_std/std_csignal.h b/libstdc++/include/c_std/std_csignal.h new file mode 100644 index 0000000..0ce5e2f --- /dev/null +++ b/libstdc++/include/c_std/std_csignal.h @@ -0,0 +1,64 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file csignal + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c signal.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSIGNAL +#define _GLIBCXX_CSIGNAL 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <signal.h> + +// Get rid of those macros defined in <signal.h> in lieu of real functions. +#undef raise + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::sig_atomic_t; + using ::signal; + using ::raise; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/c_std/std_cstdarg.h b/libstdc++/include/c_std/std_cstdarg.h new file mode 100644 index 0000000..53c29c8 --- /dev/null +++ b/libstdc++/include/c_std/std_cstdarg.h @@ -0,0 +1,64 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file include/cstdarg + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stdarg.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSTDARG +#define _GLIBCXX_CSTDARG 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <stdarg.h> + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef va_end +#define va_end(ap) va_end (ap) +#endif + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::va_list; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/c_std/std_cstddef.h b/libstdc++/include/c_std/std_cstddef.h new file mode 100644 index 0000000..bfa8388 --- /dev/null +++ b/libstdc++/include/c_std/std_cstddef.h @@ -0,0 +1,60 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file cstddef + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stddef.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 18.1 Types +// + +#ifndef _GLIBCXX_CSTDDEF +#define _GLIBCXX_CSTDDEF 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <stddef.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::ptrdiff_t; + using ::size_t; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/c_std/std_cstdio.h b/libstdc++/include/c_std/std_cstdio.h new file mode 100644 index 0000000..3935ef4 --- /dev/null +++ b/libstdc++/include/c_std/std_cstdio.h @@ -0,0 +1,191 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file include/cstdio + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stdio.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 27.8.2 C Library files +// + +#ifndef _GLIBCXX_CSTDIO +#define _GLIBCXX_CSTDIO 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <cstddef> + +#include <stdio.h> + +// Get rid of those macros defined in <stdio.h> in lieu of real functions. +#undef clearerr +#undef fclose +#undef feof +#undef ferror +#undef fflush +#undef fgetc +#undef fgetpos +#undef fgets +#undef fopen +#undef fprintf +#undef fputc +#undef fputs +#undef fread +#undef freopen +#undef fscanf +#undef fseek +#undef fsetpos +#undef ftell +#undef fwrite +#undef getc +#undef getchar +#undef gets +#undef perror +#undef printf +#undef putc +#undef putchar +#undef puts +#undef remove +#undef rename +#undef rewind +#undef scanf +#undef setbuf +#undef setvbuf +#undef sprintf +#undef sscanf +#undef tmpfile +#undef tmpnam +#undef ungetc +#undef vfprintf +#undef vprintf +#undef vsprintf + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::FILE; + using ::fpos_t; + + using ::clearerr; + using ::fclose; + using ::feof; + using ::ferror; + using ::fflush; + using ::fgetc; + using ::fgetpos; + using ::fgets; + using ::fopen; + using ::fprintf; + using ::fputc; + using ::fputs; + using ::fread; + using ::freopen; + using ::fscanf; + using ::fseek; + using ::fsetpos; + using ::ftell; + using ::fwrite; + using ::getc; + using ::getchar; + using ::gets; + using ::perror; + using ::printf; + using ::putc; + using ::putchar; + using ::puts; + using ::remove; + using ::rename; + using ::rewind; + using ::scanf; + using ::setbuf; + using ::setvbuf; + using ::sprintf; + using ::sscanf; + using ::tmpfile; + using ::tmpnam; + using ::ungetc; + using ::vfprintf; + using ::vprintf; + using ::vsprintf; + +_GLIBCXX_END_NAMESPACE + +#if _GLIBCXX_USE_C99 + +#undef snprintf +#undef vfscanf +#undef vscanf +#undef vsnprintf +#undef vsscanf + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC + extern "C" int + (snprintf)(char * restrict, size_t, const char * restrict, ...); + extern "C" int + (vfscanf)(FILE * restrict, const char * restrict, __gnuc_va_list); + extern "C" int (vscanf)(const char * restrict, __gnuc_va_list); + extern "C" int + (vsnprintf)(char * restrict, size_t, const char * restrict, __gnuc_va_list); + extern "C" int + (vsscanf)(const char * restrict, const char * restrict, __gnuc_va_list); +#endif + +#if !_GLIBCXX_USE_C99_DYNAMIC + using ::snprintf; + using ::vfscanf; + using ::vscanf; + using ::vsnprintf; + using ::vsscanf; +#endif + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::__gnu_cxx::snprintf; + using ::__gnu_cxx::vfscanf; + using ::__gnu_cxx::vscanf; + using ::__gnu_cxx::vsnprintf; + using ::__gnu_cxx::vsscanf; + +_GLIBCXX_END_NAMESPACE + +#endif + +#endif diff --git a/libstdc++/include/c_std/std_cstdlib.h b/libstdc++/include/c_std/std_cstdlib.h new file mode 100644 index 0000000..5c3d586 --- /dev/null +++ b/libstdc++/include/c_std/std_cstdlib.h @@ -0,0 +1,227 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file include/cstdlib + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stdlib.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSTDLIB +#define _GLIBCXX_CSTDLIB 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <cstddef> + +#if !_GLIBCXX_HOSTED +// The C standard does not require a freestanding implementation to +// provide <stdlib.h>. However, the C++ standard does still require +// <cstdlib> -- but only the functionality mentioned in +// [lib.support.start.term]. + +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + extern "C" void abort(void); + extern "C" int atexit(void (*)()); + extern "C" void exit(int); + +_GLIBCXX_END_NAMESPACE + +#else + +#include <stdlib.h> + +// Get rid of those macros defined in <stdlib.h> in lieu of real functions. +#undef abort +#undef abs +#undef atexit +#undef atof +#undef atoi +#undef atol +#undef bsearch +#undef calloc +#undef div +#undef exit +#undef free +#undef getenv +#undef labs +#undef ldiv +#undef malloc +#undef mblen +#undef mbstowcs +#undef mbtowc +#undef qsort +#undef rand +#undef realloc +#undef srand +#undef strtod +#undef strtol +#undef strtoul +#undef system +#undef wcstombs +#undef wctomb + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::div_t; + using ::ldiv_t; + + using ::abort; + using ::abs; + using ::atexit; + using ::atof; + using ::atoi; + using ::atol; + using ::bsearch; + using ::calloc; + using ::div; + using ::exit; + using ::free; + using ::getenv; + using ::labs; + using ::ldiv; + using ::malloc; +#ifdef _GLIBCXX_HAVE_MBSTATE_T + using ::mblen; + using ::mbstowcs; + using ::mbtowc; +#endif // _GLIBCXX_HAVE_MBSTATE_T + using ::qsort; + using ::rand; + using ::realloc; + using ::srand; + using ::strtod; + using ::strtol; + using ::strtoul; + using ::system; +#ifdef _GLIBCXX_USE_WCHAR_T + using ::wcstombs; + using ::wctomb; +#endif // _GLIBCXX_USE_WCHAR_T + + inline long + abs(long __i) { return labs(__i); } + + inline ldiv_t + div(long __i, long __j) { return ldiv(__i, __j); } + +_GLIBCXX_END_NAMESPACE + +#if _GLIBCXX_USE_C99 + +#undef _Exit +#undef llabs +#undef lldiv +#undef atoll +#undef strtoll +#undef strtoull +#undef strtof +#undef strtold + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::lldiv_t; +#endif +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC + extern "C" void (_Exit)(int); +#endif +#if !_GLIBCXX_USE_C99_DYNAMIC + using ::_Exit; +#endif + + inline long long + abs(long long __x) { return __x >= 0 ? __x : -__x; } + +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::llabs; + + inline lldiv_t + div(long long __n, long long __d) + { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } + + using ::lldiv; +#endif + +#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + extern "C" long long int (atoll)(const char *); + extern "C" long long int + (strtoll)(const char * restrict, char ** restrict, int); + extern "C" unsigned long long int + (strtoull)(const char * restrict, char ** restrict, int); +#endif +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::atoll; + using ::strtoll; + using ::strtoull; +#endif + using ::strtof; + using ::strtold; + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::__gnu_cxx::lldiv_t; +#endif + using ::__gnu_cxx::_Exit; + using ::__gnu_cxx::abs; +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::__gnu_cxx::llabs; + using ::__gnu_cxx::div; + using ::__gnu_cxx::lldiv; +#endif + using ::__gnu_cxx::atoll; + using ::__gnu_cxx::strtof; + using ::__gnu_cxx::strtoll; + using ::__gnu_cxx::strtoull; + using ::__gnu_cxx::strtold; + +_GLIBCXX_END_NAMESPACE + +#endif // _GLIBCXX_USE_C99 + +#endif // !_GLIBCXX_HOSTED + +#endif diff --git a/libstdc++/include/c_std/std_cstring.h b/libstdc++/include/c_std/std_cstring.h new file mode 100644 index 0000000..5fef6b0 --- /dev/null +++ b/libstdc++/include/c_std/std_cstring.h @@ -0,0 +1,130 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file cstring + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c string.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 20.4.6 C library +// + +#ifndef _GLIBCXX_CSTRING +#define _GLIBCXX_CSTRING 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <cstddef> +#include <string.h> + +// Get rid of those macros defined in <string.h> in lieu of real functions. +#undef memcpy +#undef memmove +#undef strcpy +#undef strncpy +#undef strcat +#undef strncat +#undef memcmp +#undef strcmp +#undef strcoll +#undef strncmp +#undef strxfrm +#undef memchr +#undef strchr +#undef strcspn +#undef strpbrk +#undef strrchr +#undef strspn +#undef strstr +#undef strtok +#undef memset +#undef strerror +#undef strlen + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::memcpy; + using ::memmove; + using ::strcpy; + using ::strncpy; + using ::strcat; + using ::strncat; + using ::memcmp; + using ::strcmp; + using ::strcoll; + using ::strncmp; + using ::strxfrm; + using ::strcspn; + using ::strspn; + using ::strtok; + using ::memset; + using ::strerror; + using ::strlen; + + using ::memchr; + + inline void* + memchr(void* __p, int __c, size_t __n) + { return memchr(const_cast<const void*>(__p), __c, __n); } + + using ::strchr; + + inline char* + strchr(char* __s1, int __n) + { return __builtin_strchr(const_cast<const char*>(__s1), __n); } + + using ::strpbrk; + + inline char* + strpbrk(char* __s1, const char* __s2) + { return __builtin_strpbrk(const_cast<const char*>(__s1), __s2); } + + using ::strrchr; + + inline char* + strrchr(char* __s1, int __n) + { return __builtin_strrchr(const_cast<const char*>(__s1), __n); } + + using ::strstr; + + inline char* + strstr(char* __s1, const char* __s2) + { return __builtin_strstr(const_cast<const char*>(__s1), __s2); } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/c_std/std_ctime.h b/libstdc++/include/c_std/std_ctime.h new file mode 100644 index 0000000..9f7f15c --- /dev/null +++ b/libstdc++/include/c_std/std_ctime.h @@ -0,0 +1,82 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file include/ctime + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c time.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 20.5 Date and time +// + +#ifndef _GLIBCXX_CTIME +#define _GLIBCXX_CTIME 1 + +#pragma GCC system_header + +#include <cstddef> +#include <time.h> + +// Get rid of those macros defined in <time.h> in lieu of real functions. +#undef clock +#undef difftime +#undef mktime +#undef time +#undef asctime +#undef ctime +#undef gmtime +#undef localtime +#undef strftime + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::clock_t; + using ::time_t; + using ::tm; + + using ::clock; + using ::difftime; + using ::mktime; + using ::time; + using ::asctime; + using ::ctime; + using ::gmtime; + using ::localtime; + using ::strftime; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/c_std/std_cwchar.h b/libstdc++/include/c_std/std_cwchar.h new file mode 100644 index 0000000..20cb804 --- /dev/null +++ b/libstdc++/include/c_std/std_cwchar.h @@ -0,0 +1,280 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file include/cwchar + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c wchar.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: 21.4 +// + +#ifndef _GLIBCXX_CWCHAR +#define _GLIBCXX_CWCHAR 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <cstddef> +#include <ctime> + +#if _GLIBCXX_HAVE_WCHAR_H +#include <wchar.h> +#endif + +// Need to do a bit of trickery here with mbstate_t as char_traits +// assumes it is in wchar.h, regardless of wchar_t specializations. +#ifndef _GLIBCXX_HAVE_MBSTATE_T +extern "C" +{ + typedef struct + { + int __fill[6]; + } mbstate_t; +} +#endif + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::mbstate_t; + +_GLIBCXX_END_NAMESPACE + +// Get rid of those macros defined in <wchar.h> in lieu of real functions. +#undef btowc +#undef fgetwc +#undef fgetws +#undef fputwc +#undef fputws +#undef fwide +#undef fwprintf +#undef fwscanf +#undef getwc +#undef getwchar +#undef mbrlen +#undef mbrtowc +#undef mbsinit +#undef mbsrtowcs +#undef putwc +#undef putwchar +#undef swprintf +#undef swscanf +#undef ungetwc +#undef vfwprintf +#if _GLIBCXX_HAVE_VFWSCANF +# undef vfwscanf +#endif +#undef vswprintf +#if _GLIBCXX_HAVE_VSWSCANF +# undef vswscanf +#endif +#undef vwprintf +#if _GLIBCXX_HAVE_VWSCANF +# undef vwscanf +#endif +#undef wcrtomb +#undef wcscat +#undef wcschr +#undef wcscmp +#undef wcscoll +#undef wcscpy +#undef wcscspn +#undef wcsftime +#undef wcslen +#undef wcsncat +#undef wcsncmp +#undef wcsncpy +#undef wcspbrk +#undef wcsrchr +#undef wcsrtombs +#undef wcsspn +#undef wcsstr +#undef wcstod +#if _GLIBCXX_HAVE_WCSTOF +# undef wcstof +#endif +#undef wcstok +#undef wcstol +#undef wcstoul +#undef wcsxfrm +#undef wctob +#undef wmemchr +#undef wmemcmp +#undef wmemcpy +#undef wmemmove +#undef wmemset +#undef wprintf +#undef wscanf + +#if _GLIBCXX_USE_WCHAR_T + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::wint_t; + + using ::btowc; + using ::fgetwc; + using ::fgetws; + using ::fputwc; + using ::fputws; + using ::fwide; + using ::fwprintf; + using ::fwscanf; + using ::getwc; + using ::getwchar; + using ::mbrlen; + using ::mbrtowc; + using ::mbsinit; + using ::mbsrtowcs; + using ::putwc; + using ::putwchar; + using ::swprintf; + using ::swscanf; + using ::ungetwc; + using ::vfwprintf; +#if _GLIBCXX_HAVE_VFWSCANF + using ::vfwscanf; +#endif + using ::vswprintf; +#if _GLIBCXX_HAVE_VSWSCANF + using ::vswscanf; +#endif + using ::vwprintf; +#if _GLIBCXX_HAVE_VWSCANF + using ::vwscanf; +#endif + using ::wcrtomb; + using ::wcscat; + using ::wcscmp; + using ::wcscoll; + using ::wcscpy; + using ::wcscspn; + using ::wcsftime; + using ::wcslen; + using ::wcsncat; + using ::wcsncmp; + using ::wcsncpy; + using ::wcsrtombs; + using ::wcsspn; + using ::wcstod; +#if _GLIBCXX_HAVE_WCSTOF + using ::wcstof; +#endif + using ::wcstok; + using ::wcstol; + using ::wcstoul; + using ::wcsxfrm; + using ::wctob; + using ::wmemcmp; + using ::wmemcpy; + using ::wmemmove; + using ::wmemset; + using ::wprintf; + using ::wscanf; + + using ::wcschr; + + inline wchar_t* + wcschr(wchar_t* __p, wchar_t __c) + { return wcschr(const_cast<const wchar_t*>(__p), __c); } + + using ::wcspbrk; + + inline wchar_t* + wcspbrk(wchar_t* __s1, const wchar_t* __s2) + { return wcspbrk(const_cast<const wchar_t*>(__s1), __s2); } + + using ::wcsrchr; + + inline wchar_t* + wcsrchr(wchar_t* __p, wchar_t __c) + { return wcsrchr(const_cast<const wchar_t*>(__p), __c); } + + using ::wcsstr; + + inline wchar_t* + wcsstr(wchar_t* __s1, const wchar_t* __s2) + { return wcsstr(const_cast<const wchar_t*>(__s1), __s2); } + + using ::wmemchr; + + inline wchar_t* + wmemchr(wchar_t* __p, wchar_t __c, size_t __n) + { return wmemchr(const_cast<const wchar_t*>(__p), __c, __n); } + +_GLIBCXX_END_NAMESPACE + +#if _GLIBCXX_USE_C99 + +#undef wcstold +#undef wcstoll +#undef wcstoull + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC + extern "C" long double + (wcstold)(const wchar_t * restrict, wchar_t ** restrict); +#endif +#if !_GLIBCXX_USE_C99_DYNAMIC + using ::wcstold; +#endif +#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + extern "C" long long int + (wcstoll)(const wchar_t * restrict, wchar_t ** restrict, int); + extern "C" unsigned long long int + (wcstoull)(const wchar_t * restrict, wchar_t ** restrict, int); +#endif +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::wcstoll; + using ::wcstoull; +#endif + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::__gnu_cxx::wcstold; + using ::__gnu_cxx::wcstoll; + using ::__gnu_cxx::wcstoull; + +_GLIBCXX_END_NAMESPACE + +#endif + +#endif //_GLIBCXX_USE_WCHAR_T + +#endif diff --git a/libstdc++/include/c_std/std_cwctype.h b/libstdc++/include/c_std/std_cwctype.h new file mode 100644 index 0000000..dd0032f --- /dev/null +++ b/libstdc++/include/c_std/std_cwctype.h @@ -0,0 +1,112 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file include/cwctype + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c wctype.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std (except for names which are defined + * as macros in C). + */ + +// +// ISO C++ 14882: <cwctype> +// + +#ifndef _GLIBCXX_CWCTYPE +#define _GLIBCXX_CWCTYPE 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +#if _GLIBCXX_HAVE_WCTYPE_H +#include <wctype.h> +#endif + +// Get rid of those macros defined in <wctype.h> in lieu of real functions. +#undef iswalnum +#undef iswalpha +#if _GLIBCXX_HAVE_ISWBLANK +# undef iswblank +#endif +#undef iswcntrl +#undef iswctype +#undef iswdigit +#undef iswgraph +#undef iswlower +#undef iswprint +#undef iswpunct +#undef iswspace +#undef iswupper +#undef iswxdigit +#undef towctrans +#undef towlower +#undef towupper +#undef wctrans +#undef wctype + +#if _GLIBCXX_USE_WCHAR_T + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using ::wint_t; // cwchar + + using ::wctype_t; + using ::wctrans_t; + + using ::iswalnum; + using ::iswalpha; +#if _GLIBCXX_HAVE_ISWBLANK + using ::iswblank; +#endif + using ::iswcntrl; + using ::iswctype; + using ::iswdigit; + using ::iswgraph; + using ::iswlower; + using ::iswprint; + using ::iswpunct; + using ::iswspace; + using ::iswupper; + using ::iswxdigit; + using ::towctrans; + using ::towlower; + using ::towupper; + using ::wctrans; + using ::wctype; + +_GLIBCXX_END_NAMESPACE + +#endif //_GLIBCXX_USE_WCHAR_T + +#endif diff --git a/libstdc++/include/debug/bitset b/libstdc++/include/debug/bitset new file mode 100644 index 0000000..58d4e6b --- /dev/null +++ b/libstdc++/include/debug/bitset @@ -0,0 +1,328 @@ +// Debugging bitset implementation -*- C++ -*- + +// 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. + +/** @file debug/bitset + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_BITSET +#define _GLIBCXX_DEBUG_BITSET + +#include <bitset> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace std +{ +namespace __debug +{ + template<size_t _Nb> + class bitset + : public _GLIBCXX_STD::bitset<_Nb>, + public __gnu_debug::_Safe_sequence_base + { + typedef _GLIBCXX_STD::bitset<_Nb> _Base; + typedef __gnu_debug::_Safe_sequence_base _Safe_base; + + public: + // bit reference: + class reference + : private _Base::reference, public __gnu_debug::_Safe_iterator_base + { + typedef typename _Base::reference _Base_ref; + + friend class bitset; + reference(); + + reference(const _Base_ref& __base, bitset* __seq) + : _Base_ref(__base), _Safe_iterator_base(__seq, false) + { } + + public: + reference(const reference& __x) + : _Base_ref(__x), _Safe_iterator_base(__x, false) + { } + + reference& + operator=(bool __x) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__gnu_debug::__msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + reference& + operator=(const reference& __x) + { + _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(), + _M_message(__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(__x)); + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__gnu_debug::__msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + bool + operator~() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(*this)); + return ~(*static_cast<const _Base_ref*>(this)); + } + + operator bool() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(*this)); + return *static_cast<const _Base_ref*>(this); + } + + reference& + flip() + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__gnu_debug::__msg_bad_bitset_flip) + ._M_iterator(*this)); + _Base_ref::flip(); + return *this; + } + }; + + // 23.3.5.1 constructors: + bitset() : _Base() { } + + bitset(unsigned long __val) : _Base(__val) { } + + template<typename _CharT, typename _Traits, typename _Allocator> + explicit + bitset(const std::basic_string<_CharT,_Traits,_Allocator>& __str, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __pos = 0, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __n = (std::basic_string<_CharT,_Traits,_Allocator>::npos)) + : _Base(__str, __pos, __n) { } + + bitset(const _Base& __x) : _Base(__x), _Safe_base() { } + + // 23.3.5.2 bitset operations: + bitset<_Nb>& + operator&=(const bitset<_Nb>& __rhs) + { + _M_base() &= __rhs; + return *this; + } + + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) + { + _M_base() |= __rhs; + return *this; + } + + bitset<_Nb>& + operator^=(const bitset<_Nb>& __rhs) + { + _M_base() ^= __rhs; + return *this; + } + + bitset<_Nb>& + operator<<=(size_t __pos) + { + _M_base() <<= __pos; + return *this; + } + + bitset<_Nb>& + operator>>=(size_t __pos) + { + _M_base() >>= __pos; + return *this; + } + + bitset<_Nb>& + set() + { + _Base::set(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 186. bitset::set() second parameter should be bool + bitset<_Nb>& + set(size_t __pos, bool __val = true) + { + _Base::set(__pos, __val); + return *this; + } + + bitset<_Nb>& + reset() + { + _Base::reset(); + return *this; + } + + bitset<_Nb>& + reset(size_t __pos) + { + _Base::reset(__pos); + return *this; + } + + bitset<_Nb> operator~() const { return bitset(~_M_base()); } + + bitset<_Nb>& + flip() + { + _Base::flip(); + return *this; + } + + bitset<_Nb>& + flip(size_t __pos) + { + _Base::flip(__pos); + return *this; + } + + // element access: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + reference + operator[](size_t __pos) + { + __glibcxx_check_subscript(__pos); + return reference(_M_base()[__pos], this); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + bool + operator[](size_t __pos) const + { + __glibcxx_check_subscript(__pos); + return _M_base()[__pos]; + } + + using _Base::to_ulong; + + template <typename _CharT, typename _Traits, typename _Allocator> + std::basic_string<_CharT, _Traits, _Allocator> + to_string() const + { return _M_base().template to_string<_CharT, _Traits, _Allocator>(); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 434. bitset::to_string() hard to use. + template<typename _CharT, typename _Traits> + std::basic_string<_CharT, _Traits, std::allocator<_CharT> > + to_string() const + { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); } + + template<typename _CharT> + std::basic_string<_CharT, std::char_traits<_CharT>, + std::allocator<_CharT> > + to_string() const + { + return to_string<_CharT, std::char_traits<_CharT>, + std::allocator<_CharT> >(); + } + + std::basic_string<char, std::char_traits<char>, std::allocator<char> > + to_string() const + { + return to_string<char,std::char_traits<char>,std::allocator<char> >(); + } + + using _Base::count; + using _Base::size; + + bool + operator==(const bitset<_Nb>& __rhs) const + { return _M_base() == __rhs; } + + bool + operator!=(const bitset<_Nb>& __rhs) const + { return _M_base() != __rhs; } + + using _Base::test; + using _Base::any; + using _Base::none; + + bitset<_Nb> + operator<<(size_t __pos) const + { return bitset<_Nb>(_M_base() << __pos); } + + bitset<_Nb> + operator>>(size_t __pos) const + { return bitset<_Nb>(_M_base() >> __pos); } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + }; + + template<size_t _Nb> + bitset<_Nb> + operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) &= __y; } + + template<size_t _Nb> + bitset<_Nb> + operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) |= __y; } + + template<size_t _Nb> + bitset<_Nb> + operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) ^= __y; } + + template<typename _CharT, typename _Traits, size_t _Nb> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + { return __is >> __x._M_base(); } + + template<typename _CharT, typename _Traits, size_t _Nb> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bitset<_Nb>& __x) + { return __os << __x._M_base(); } +} // namespace __debug +} // namespace std + +#endif diff --git a/libstdc++/include/debug/debug.h b/libstdc++/include/debug/debug.h new file mode 100644 index 0000000..b914a2c --- /dev/null +++ b/libstdc++/include/debug/debug.h @@ -0,0 +1,145 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2003, 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. + +/** @file debug/debug.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_MACRO_SWITCH_H +#define _GLIBCXX_DEBUG_MACRO_SWITCH_H 1 + +/** Macros and namespaces used by the implementation outside of debug + * wrappers to verify certain properties. The __glibcxx_requires_xxx + * macros are merely wrappers around the __glibcxx_check_xxx wrappers + * when we are compiling with debug mode, but disappear when we are + * in release mode so that there is no checking performed in, e.g., + * the standard library algorithms. +*/ + +// Debug mode namespaces. +namespace std +{ + namespace __debug { } +} + +namespace __gnu_cxx +{ + namespace __debug { }; +} + +namespace __gnu_debug +{ + using namespace std::__debug; + using namespace __gnu_cxx::__debug; +} + +#ifndef _GLIBCXX_DEBUG + +# define _GLIBCXX_DEBUG_ASSERT(_Condition) +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# define _GLIBCXX_DEBUG_ONLY(_Statement) ; +# define __glibcxx_requires_cond(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() +# define __glibcxx_requires_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) + +#else + +# include <cstdlib> +# include <cstdio> +# include <debug/macros.h> + +namespace std +{ + namespace __debug + { + // Avoid the use of assert, because we're trying to keep the <cassert> + // include out of the mix. + inline void + __replacement_assert(const char* __file, int __line, + const char* __function, const char* __condition) + { + printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, + __function, __condition); + abort(); + } + } // namespace __debug +} // namespace std + +#define _GLIBCXX_DEBUG_ASSERT(_Condition) \ + do \ + { \ + if (! (_Condition)) \ + std::__debug::__replacement_assert(__FILE__, __LINE__, \ + __PRETTY_FUNCTION__, #_Condition); \ + } while (false) + +#ifdef _GLIBCXX_DEBUG_PEDANTIC +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) _GLIBCXX_DEBUG_ASSERT(_Condition) +#else +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +#endif +# define _GLIBCXX_DEBUG_ONLY(_Statement) _Statement + +# define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) \ + __glibcxx_check_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \ + __glibcxx_check_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) \ + __glibcxx_check_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) \ + __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) \ + __glibcxx_check_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \ + __glibcxx_check_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() __glibcxx_check_nonempty() +# define __glibcxx_requires_string(_String) __glibcxx_check_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) \ + __glibcxx_check_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N) + +# include <debug/functions.h> +# include <debug/formatter.h> + +#endif + +#endif // _GLIBCXX_DEBUG_MACRO_SWITCH_H diff --git a/libstdc++/include/debug/deque b/libstdc++/include/debug/deque new file mode 100644 index 0000000..79142d9 --- /dev/null +++ b/libstdc++/include/debug/deque @@ -0,0 +1,393 @@ +// Debugging deque implementation -*- C++ -*- + +// 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. + +/** @file debug/deque + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_DEQUE +#define _GLIBCXX_DEBUG_DEQUE 1 + +#include <deque> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace std +{ +namespace __debug +{ + template<typename _Tp, typename _Allocator = std::allocator<_Tp> > + class deque + : public _GLIBCXX_STD::deque<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> > + { + typedef _GLIBCXX_STD::deque<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<deque> _Safe_base; + + public: + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.2.1.1 construct/copy/destroy: + explicit deque(const _Allocator& __a = _Allocator()) + : _Base(__a) { } + + explicit deque(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) { } + + template<class _InputIterator> + deque(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { } + + deque(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~deque() { } + + deque<_Tp,_Allocator>& + operator=(const deque<_Tp,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template<class _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.1.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + bool __invalidate_all = __sz > this->size(); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + + _Base::resize(__sz, __c); + + if (__invalidate_all) + this->_M_invalidate_all(); + } + + using _Base::empty; + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.1.3 modifiers: + void + push_front(const _Tp& __x) + { + _Base::push_front(__x); + this->_M_invalidate_all(); + } + + void + push_back(const _Tp& __x) + { + _Base::push_back(__x); + this->_M_invalidate_all(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + typename _Base::iterator __res = _Base::insert(__position.base(), __x); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + this->_M_invalidate_all(); + } + + template<class _InputIterator> + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + this->_M_invalidate_all(); + } + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + if (__position == begin() || __position == end()-1) + { + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + else + { + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + if (__first == begin() || __last == end()) + { + this->_M_detach_singular(); + for (iterator __position = __first; __position != __last; ) + { + iterator __victim = __position++; + __victim._M_invalidate(); + } + try + { + return iterator(_Base::erase(__first.base(), __last.base()), + this); + } + catch (...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + else + { + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + } + + void + swap(deque<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + }; + + template<typename _Tp, typename _Alloc> + inline bool + operator==(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline void + swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __debug +} // namespace std + +#endif diff --git a/libstdc++/include/debug/formatter.h b/libstdc++/include/debug/formatter.h new file mode 100644 index 0000000..8975285 --- /dev/null +++ b/libstdc++/include/debug/formatter.h @@ -0,0 +1,394 @@ +// Debug-mode error formatting implementation -*- C++ -*- + +// Copyright (C) 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. + +/** @file debug/formatter.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_FORMATTER_H +#define _GLIBCXX_DEBUG_FORMATTER_H 1 + +#include <typeinfo> +#include <debug/debug.h> + +namespace __gnu_debug +{ + using std::type_info; + + /** Determine if the two types are the same. */ + template<typename _Type1, typename _Type2> + struct __is_same + { + static const bool value = false; + }; + + template<typename _Type> + struct __is_same<_Type, _Type> + { + static const bool value = true; + }; + + template<bool> struct __truth { }; + + class _Safe_sequence_base; + + template<typename _Iterator, typename _Sequence> + class _Safe_iterator; + + template<typename _Sequence> + class _Safe_sequence; + + enum _Debug_msg_id + { + // General checks + __msg_valid_range, + __msg_insert_singular, + __msg_insert_different, + __msg_erase_bad, + __msg_erase_different, + __msg_subscript_oob, + __msg_empty, + __msg_unpartitioned, + __msg_unpartitioned_pred, + __msg_unsorted, + __msg_unsorted_pred, + __msg_not_heap, + __msg_not_heap_pred, + // std::bitset checks + __msg_bad_bitset_write, + __msg_bad_bitset_read, + __msg_bad_bitset_flip, + // std::list checks + __msg_self_splice, + __msg_splice_alloc, + __msg_splice_bad, + __msg_splice_other, + __msg_splice_overlap, + // iterator checks + __msg_init_singular, + __msg_init_copy_singular, + __msg_init_const_singular, + __msg_copy_singular, + __msg_bad_deref, + __msg_bad_inc, + __msg_bad_dec, + __msg_iter_subscript_oob, + __msg_advance_oob, + __msg_retreat_oob, + __msg_iter_compare_bad, + __msg_compare_different, + __msg_iter_order_bad, + __msg_order_different, + __msg_distance_bad, + __msg_distance_different, + // istream_iterator + __msg_deref_istream, + __msg_inc_istream, + // ostream_iterator + __msg_output_ostream, + // istreambuf_iterator + __msg_deref_istreambuf, + __msg_inc_istreambuf + }; + + class _Error_formatter + { + /// Whether an iterator is constant, mutable, or unknown + enum _Constness + { + __unknown_constness, + __const_iterator, + __mutable_iterator, + __last_constness + }; + + // The state of the iterator (fine-grained), if we know it. + enum _Iterator_state + { + __unknown_state, + __singular, // singular, may still be attached to a sequence + __begin, // dereferenceable, and at the beginning + __middle, // dereferenceable, not at the beginning + __end, // past-the-end, may be at beginning if sequence empty + __last_state + }; + + // Tags denoting the type of parameter for construction + struct _Is_iterator { }; + struct _Is_sequence { }; + + // A parameter that may be referenced by an error message + struct _Parameter + { + enum + { + __unused_param, + __iterator, + __sequence, + __integer, + __string + } _M_kind; + + union + { + // When _M_kind == __iterator + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + _Constness _M_constness; + _Iterator_state _M_state; + const void* _M_sequence; + const type_info* _M_seq_type; + } _M_iterator; + + // When _M_kind == __sequence + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + } _M_sequence; + + // When _M_kind == __integer + struct + { + const char* _M_name; + long _M_value; + } _M_integer; + + // When _M_kind == __string + struct + { + const char* _M_name; + const char* _M_value; + } _M_string; + } _M_variant; + + _Parameter() : _M_kind(__unused_param), _M_variant() { } + + _Parameter(long __value, const char* __name) + : _M_kind(__integer), _M_variant() + { + _M_variant._M_integer._M_name = __name; + _M_variant._M_integer._M_value = __value; + } + + _Parameter(const char* __value, const char* __name) + : _M_kind(__string), _M_variant() + { + _M_variant._M_string._M_name = __name; + _M_variant._M_string._M_value = __value; + } + + template<typename _Iterator, typename _Sequence> + _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it, + const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = + __is_same<_Safe_iterator<_Iterator, _Sequence>, + typename _Sequence::iterator>:: + value? __mutable_iterator : __const_iterator; + _M_variant._M_iterator._M_sequence = __it._M_get_sequence(); + _M_variant._M_iterator._M_seq_type = &typeid(_Sequence); + + if (__it._M_singular()) + _M_variant._M_iterator._M_state = __singular; + else + { + bool __is_begin = __it._M_is_begin(); + bool __is_end = __it._M_is_end(); + if (__is_end) + _M_variant._M_iterator._M_state = __end; + else if (__is_begin) + _M_variant._M_iterator._M_state = __begin; + else + _M_variant._M_iterator._M_state = __middle; + } + } + + template<typename _Type> + _Parameter(const _Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __mutable_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template<typename _Type> + _Parameter(_Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __const_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template<typename _Iterator> + _Parameter(const _Iterator& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __unknown_constness; + _M_variant._M_iterator._M_state = + __gnu_debug::__check_singular(__it)? __singular : __unknown_state; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template<typename _Sequence> + _Parameter(const _Safe_sequence<_Sequence>& __seq, + const char* __name, _Is_sequence) + : _M_kind(__sequence), _M_variant() + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = + static_cast<const _Sequence*>(&__seq); + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + template<typename _Sequence> + _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence) + : _M_kind(__sequence), _M_variant() + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = &__seq; + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + void + _M_print_field(const _Error_formatter* __formatter, + const char* __name) const; + + void + _M_print_description(const _Error_formatter* __formatter) const; + }; + + friend struct _Parameter; + + public: + template<typename _Iterator> + const _Error_formatter& + _M_iterator(const _Iterator& __it, const char* __name = 0) const + { + if (_M_num_parameters < size_t(__max_parameters)) + _M_parameters[_M_num_parameters++] = _Parameter(__it, __name, + _Is_iterator()); + return *this; + } + + const _Error_formatter& + _M_integer(long __value, const char* __name = 0) const + { + if (_M_num_parameters < size_t(__max_parameters)) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + const _Error_formatter& + _M_string(const char* __value, const char* __name = 0) const + { + if (_M_num_parameters < size_t(__max_parameters)) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + template<typename _Sequence> + const _Error_formatter& + _M_sequence(const _Sequence& __seq, const char* __name = 0) const + { + if (_M_num_parameters < size_t(__max_parameters)) + _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name, + _Is_sequence()); + return *this; + } + + const _Error_formatter& + _M_message(const char* __text) const + { _M_text = __text; return *this; } + + const _Error_formatter& + _M_message(_Debug_msg_id __id) const; + + void + _M_error() const; + + private: + _Error_formatter(const char* __file, size_t __line) + : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0), + _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) + { } + + template<typename _Tp> + void + _M_format_word(char*, int, const char*, _Tp) const; + + void + _M_print_word(const char* __word) const; + + void + _M_print_string(const char* __string) const; + + enum { __max_parameters = 9 }; + + const char* _M_file; + size_t _M_line; + mutable _Parameter _M_parameters[__max_parameters]; + mutable size_t _M_num_parameters; + mutable const char* _M_text; + mutable size_t _M_max_length; + enum { _M_indent = 4 } ; + mutable size_t _M_column; + mutable bool _M_first_line; + mutable bool _M_wordwrap; + + public: + static _Error_formatter + _M_at(const char* __file, size_t __line) + { return _Error_formatter(__file, __line); } + }; +} // namespace __gnu_debug + +#endif diff --git a/libstdc++/include/debug/functions.h b/libstdc++/include/debug/functions.h new file mode 100644 index 0000000..a61c0b9 --- /dev/null +++ b/libstdc++/include/debug/functions.h @@ -0,0 +1,293 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2003, 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. + +/** @file debug/functions.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_FUNCTIONS_H +#define _GLIBCXX_DEBUG_FUNCTIONS_H 1 + +#include <bits/c++config.h> +#include <stddef.h> // for ptrdiff_t +#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories +#include <bits/cpp_type_traits.h> // for __is_integer + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + class _Safe_iterator; + + // An arbitrary iterator pointer is not singular. + inline bool + __check_singular_aux(const void*) { return false; } + + // We may have an iterator that derives from _Safe_iterator_base but isn't + // a _Safe_iterator. + template<typename _Iterator> + inline bool + __check_singular(_Iterator& __x) + { return __check_singular_aux(&__x); } + + /** Non-NULL pointers are nonsingular. */ + template<typename _Tp> + inline bool + __check_singular(const _Tp* __ptr) + { return __ptr == 0; } + + /** Safe iterators know if they are singular. */ + template<typename _Iterator, typename _Sequence> + inline bool + __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_singular(); } + + /** Assume that some arbitrary iterator is dereferenceable, because we + can't prove that it isn't. */ + template<typename _Iterator> + inline bool + __check_dereferenceable(_Iterator&) + { return true; } + + /** Non-NULL pointers are dereferenceable. */ + template<typename _Tp> + inline bool + __check_dereferenceable(const _Tp* __ptr) + { return __ptr; } + + /** Safe iterators know if they are singular. */ + template<typename _Iterator, typename _Sequence> + inline bool + __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_dereferenceable(); } + + /** If the distance between two random access iterators is + * nonnegative, assume the range is valid. + */ + template<typename _RandomAccessIterator> + inline bool + __valid_range_aux2(const _RandomAccessIterator& __first, + const _RandomAccessIterator& __last, + std::random_access_iterator_tag) + { return __last - __first >= 0; } + + /** Can't test for a valid range with input iterators, because + * iteration may be destructive. So we just assume that the range + * is valid. + */ + template<typename _InputIterator> + inline bool + __valid_range_aux2(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + /** We say that integral types for a valid range, and defer to other + * routines to realize what to do with integral types instead of + * iterators. + */ + template<typename _Integral> + inline bool + __valid_range_aux(const _Integral&, const _Integral&, std::__true_type) + { return true; } + + /** We have iterators, so figure out what kind of iterators that are + * to see if we can check the range ahead of time. + */ + template<typename _InputIterator> + inline bool + __valid_range_aux(const _InputIterator& __first, + const _InputIterator& __last, std::__false_type) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __valid_range_aux2(__first, __last, _Category()); + } + + /** Don't know what these iterators are, or if they are even + * iterators (we may get an integral type for InputIterator), so + * see if they are integral and pass them on to the next phase + * otherwise. + */ + template<typename _InputIterator> + inline bool + __valid_range(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return __valid_range_aux(__first, __last, _Integral()); + } + + /** Safe iterators know how to check if they form a valid range. */ + template<typename _Iterator, typename _Sequence> + inline bool + __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, + const _Safe_iterator<_Iterator, _Sequence>& __last) + { return __first._M_valid_range(__last); } + + /* Checks that [first, last) is a valid range, and then returns + * __first. This routine is useful when we can't use a separate + * assertion statement because, e.g., we are in a constructor. + */ + template<typename _InputIterator> + inline _InputIterator + __check_valid_range(const _InputIterator& __first, + const _InputIterator& __last + __attribute__((__unused__))) + { + _GLIBCXX_DEBUG_ASSERT(__valid_range(__first, __last)); + return __first; + } + + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ + template<typename _CharT, typename _Integer> + inline const _CharT* + __check_string(const _CharT* __s, + const _Integer& __n __attribute__((__unused__))) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0); +#endif + return __s; + } + + /** Checks that __s is non-NULL and then returns __s. */ + template<typename _CharT> + inline const _CharT* + __check_string(const _CharT* __s) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0); +#endif + return __s; + } + + // Can't check if an input iterator sequence is sorted, because we + // can't step through the sequence. + template<typename _InputIterator> + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template<typename _ForwardIterator> + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; + } + + // Can't check if an input iterator sequence is sorted, because we can't step + // through the sequence. + template<typename _InputIterator, typename _Predicate> + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + _Predicate, std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template<typename _ForwardIterator, typename _Predicate> + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__pred(*__next, *__first)) + return false; + } + + return true; + } + + // Determine if a sequence is sorted. + template<typename _InputIterator> + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __check_sorted_aux(__first, __last, _Category()); + } + + template<typename _InputIterator, typename _Predicate> + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last, + _Predicate __pred) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __check_sorted_aux(__first, __last, __pred, + _Category()); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 270. Binary search requirements overly strict + // Determine if a sequence is partitioned w.r.t. this element. + template<typename _ForwardIterator, typename _Tp> + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + while (__first != __last && *__first < __value) + ++__first; + while (__first != __last && !(*__first < __value)) + ++__first; + return __first == __last; + } + + // Determine if a sequence is partitioned w.r.t. this element. + template<typename _ForwardIterator, typename _Tp, typename _Pred> + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value, _Pred __pred) + { + while (__first != __last && __pred(*__first, __value)) + ++__first; + while (__first != __last && !__pred(*__first, __value)) + ++__first; + return __first == __last; + } +} // namespace __gnu_debug + +#endif diff --git a/libstdc++/include/debug/hash_map b/libstdc++/include/debug/hash_map new file mode 100644 index 0000000..f44586b --- /dev/null +++ b/libstdc++/include/debug/hash_map @@ -0,0 +1,42 @@ +// Debugging hash_map/hash_multimap implementation -*- C++ -*- + +// 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. + +/** @file debug/hash_map + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_HASH_MAP +#define _GLIBCXX_DEBUG_HASH_MAP 1 + +#include <ext/hash_map> +#include <debug/hash_map.h> +#include <debug/hash_multimap.h> + +#endif diff --git a/libstdc++/include/debug/hash_map.h b/libstdc++/include/debug/hash_map.h new file mode 100644 index 0000000..1eb6acb --- /dev/null +++ b/libstdc++/include/debug/hash_map.h @@ -0,0 +1,284 @@ +// Debugging hash_map implementation -*- C++ -*- + +// Copyright (C) 2003, 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. + +/** @file debug/hash_map.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_HASH_MAP_H +#define _GLIBCXX_DEBUG_HASH_MAP_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_cxx +{ +namespace __debug +{ + template<typename _Value, typename _Tp, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_map + : public _GLIBCXX_EXT::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence<hash_map<_Value, _Tp, _HashFcn, + _EqualKey, _Alloc> > + { + typedef _GLIBCXX_EXT::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence<hash_map> _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, hash_map> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_map> + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_map() { } + + explicit hash_map(size_type __n) : _Base(__n) { } + + hash_map(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + hash_map(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_map& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() { return iterator(_Base::begin(), this); } + + iterator + end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + std::pair<iterator, bool> + insert(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + void + insert(const value_type* __first, const value_type* __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair<iterator, bool> + insert_noresize(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::operator[]; + using _Base::count; + + std::pair<iterator, iterator> + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline bool + operator==(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline bool + operator!=(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline void + swap(hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __debug +} // namespace __gnu_cxx + +#endif diff --git a/libstdc++/include/debug/hash_multimap.h b/libstdc++/include/debug/hash_multimap.h new file mode 100644 index 0000000..e3c689a --- /dev/null +++ b/libstdc++/include/debug/hash_multimap.h @@ -0,0 +1,268 @@ +// Debugging hash_multimap implementation -*- C++ -*- + +// Copyright (C) 2003, 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. + +/** @file debug/hash_multimap.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_HASH_MULTIMAP_H +#define _GLIBCXX_DEBUG_HASH_MULTIMAP_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_cxx +{ +namespace __debug +{ + template<typename _Value, typename _Tp, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multimap + : public _GLIBCXX_EXT::hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>, + public __gnu_debug::_Safe_sequence<hash_multimap<_Value, _Tp, _HashFcn, + _EqualKey, _Alloc> > + { + typedef _GLIBCXX_EXT::hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence<hash_multimap> _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, + hash_multimap> iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_multimap> const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multimap() { } + + explicit hash_multimap(size_type __n) : _Base(__n) { } + + hash_multimap(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multimap& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() { return iterator(_Base::begin(), this); } + + iterator + end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair<iterator, iterator> + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + std::pair<iterator, iterator> __victims = this->equal_range(__key); + std::size_t __num_victims = 0; + while (__victims.first != __victims.second) + { + this->erase(__victims.first++); + ++__num_victims; + } + return __num_victims; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline bool + operator==(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline bool + operator!=(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline void + swap(hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __debug +} // namespace __gnu_cxx + +#endif diff --git a/libstdc++/include/debug/hash_multiset.h b/libstdc++/include/debug/hash_multiset.h new file mode 100644 index 0000000..9346496 --- /dev/null +++ b/libstdc++/include/debug/hash_multiset.h @@ -0,0 +1,243 @@ +// Debugging hash_multiset implementation -*- C++ -*- + +// Copyright (C) 2003, 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. + +/** @file debug/hash_multiset.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_HASH_MULTISET_H +#define _GLIBCXX_DEBUG_HASH_MULTISET_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_cxx +{ +namespace __debug +{ + template<typename _Value, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multiset + : public _GLIBCXX_EXT::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence<hash_multiset<_Value, _HashFcn, + _EqualKey, _Alloc> > + { + typedef _GLIBCXX_EXT:: hash_multiset<_Value,_HashFcn, _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence<hash_multiset> _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, + hash_multiset> iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_multiset> const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multiset() { } + + explicit hash_multiset(size_type __n) : _Base(__n) { } + + hash_multiset(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) + { } + + hash_multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multiset& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator begin() const { return iterator(_Base::begin(), this); } + iterator end() const { return iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair<iterator, iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + size_type __count = 0; + std::pair<iterator, iterator> __victims = this->equal_range(__key); + while (__victims.first != __victims.second) + { + this->erase(__victims++); + ++__count; + } + return __count; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + +template<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc> + inline bool + operator==(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + +template<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc> + inline bool + operator!=(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + +template<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc> + inline void + swap(hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __debug +} // namespace __gnu_cxx + +#endif diff --git a/libstdc++/include/debug/hash_set b/libstdc++/include/debug/hash_set new file mode 100644 index 0000000..4b98fef --- /dev/null +++ b/libstdc++/include/debug/hash_set @@ -0,0 +1,42 @@ +// Debugging hash_set/hash_multiset implementation -*- C++ -*- + +// 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. + +/** @file debug/hash_set + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_HASH_SET +#define _GLIBCXX_DEBUG_HASH_SET 1 + +#include <ext/hash_set> +#include <debug/hash_set.h> +#include <debug/hash_multiset.h> + +#endif diff --git a/libstdc++/include/debug/hash_set.h b/libstdc++/include/debug/hash_set.h new file mode 100644 index 0000000..2d3e0b3 --- /dev/null +++ b/libstdc++/include/debug/hash_set.h @@ -0,0 +1,259 @@ +// Debugging hash_set implementation -*- C++ -*- + +// Copyright (C) 2003, 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. + +/** @file debug/hash_set.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_HASH_SET_H +#define _GLIBCXX_DEBUG_HASH_SET_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_cxx +{ +namespace __debug +{ + template<typename _Value, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_set + : public _GLIBCXX_EXT::hash_set<_Value, _HashFcn, _EqualKey,_Alloc>, + public __gnu_debug::_Safe_sequence<hash_set<_Value, _HashFcn, _EqualKey, + _Alloc> > + { + typedef _GLIBCXX_EXT::hash_set<_Value, _HashFcn, _EqualKey,_Alloc> _Base; + typedef __gnu_debug::_Safe_sequence<hash_set> _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, hash_set> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_set> + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_set() { } + + explicit hash_set(size_type __n) : _Base(__n) { } + + hash_set(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + hash_set(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_set& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() const { return iterator(_Base::begin(), this); } + + iterator + end() const { return iterator(_Base::end(), this); } + + std::pair<iterator, bool> + insert(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = + _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + void + insert(const value_type* __first, const value_type* __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair<iterator, bool> + insert_noresize(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair<iterator, iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Value, typename _HashFcn, typename _EqualKey, + typename _Alloc> + inline bool + operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template<typename _Value, typename _HashFcn, typename _EqualKey, + typename _Alloc> + inline bool + operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template<typename _Value, typename _HashFcn, typename _EqualKey, + typename _Alloc> + inline void + swap(hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __debug +} // namespace __gnu_cxx + +#endif diff --git a/libstdc++/include/debug/list b/libstdc++/include/debug/list new file mode 100644 index 0000000..939fe4d --- /dev/null +++ b/libstdc++/include/debug/list @@ -0,0 +1,540 @@ +// Debugging list implementation -*- C++ -*- + +// Copyright (C) 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. + +// 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. + +/** @file debug/list + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_LIST +#define _GLIBCXX_DEBUG_LIST 1 + +#include <list> +#include <bits/stl_algo.h> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace std +{ +namespace __debug +{ + template<typename _Tp, typename _Allocator = std::allocator<_Tp> > + class list + : public _GLIBCXX_STD::list<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> > + { + typedef _GLIBCXX_STD::list<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<list> _Safe_base; + + public: + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, list> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, list> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.2.2.1 construct/copy/destroy: + explicit list(const _Allocator& __a = _Allocator()) + : _Base(__a) { } + + explicit list(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) { } + + template<class _InputIterator> + list(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + + list(const list& __x) : _Base(__x), _Safe_base() { } + + list(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~list() { } + + list& + operator=(const list& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template<class _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.2.2 capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + this->_M_detach_singular(); + + // if __sz < size(), invalidate all iterators in [begin+__sz, end()) + iterator __victim = begin(); + iterator __end = end(); + for (size_type __i = __sz; __victim != __end && __i > 0; --__i) + ++__victim; + + while (__victim != __end) + { + iterator __real_victim = __victim++; + __real_victim._M_invalidate(); + } + + try + { + _Base::resize(__sz, __c); + } + catch(...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + + // element access: + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.2.3 modifiers: + using _Base::push_front; + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + using _Base::push_back; + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + } + + template<class _InputIterator> + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + + iterator + erase(iterator __position, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__position, __last); + for (iterator __victim = __position; __victim != __last; ) + { + iterator __old = __victim; + ++__victim; + __old._M_invalidate(); + } + return iterator(_Base::erase(__position.base(), __last.base()), this); + } + + void + swap(list& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + // 23.2.2.4 list operations: + void + splice(iterator __position, list& __x) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this, + _M_message(__gnu_debug::__msg_self_splice) + ._M_sequence(*this, "this")); + this->splice(__position, __x, __x.begin(), __x.end()); + } + + void + splice(iterator __position, list& __x, iterator __i) + { + __glibcxx_check_insert(__position); + + // We used to perform the splice_alloc check: not anymore, redundant + // after implementing the relevant bits of N1599. + + _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(), + _M_message(__gnu_debug::__msg_splice_bad) + ._M_iterator(__i, "__i")); + _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x), + _M_message(__gnu_debug::__msg_splice_other) + ._M_iterator(__i, "__i")._M_sequence(__x, "__x")); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__i); + _Base::splice(__position.base(), __x._M_base(), __i.base()); + } + + void + splice(iterator __position, list& __x, iterator __first, iterator __last) + { + __glibcxx_check_insert(__position); + __glibcxx_check_valid_range(__first, __last); + _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x), + _M_message(__gnu_debug::__msg_splice_other) + ._M_sequence(__x, "x") + ._M_iterator(__first, "first")); + + // We used to perform the splice_alloc check: not anymore, redundant + // after implementing the relevant bits of N1599. + + for (iterator __tmp = __first; __tmp != __last; ) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position, + _M_message(__gnu_debug::__msg_splice_overlap) + ._M_iterator(__tmp, "position") + ._M_iterator(__first, "first") + ._M_iterator(__last, "last")); + iterator __victim = __tmp++; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__victim); + } + + _Base::splice(__position.base(), __x._M_base(), __first.base(), + __last.base()); + } + + void + remove(const _Tp& __value) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (*__x == __value) + __x = erase(__x); + else + ++__x; + } + } + + template<class _Predicate> + void + remove_if(_Predicate __pred) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (__pred(*__x)) + __x = erase(__x); + else + ++__x; + } + } + + void + unique() + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (*__first == *__next) + erase(__next); + else + __first = __next; + __next = __first; + } + } + + template<class _BinaryPredicate> + void + unique(_BinaryPredicate __binary_pred) + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(*__first, *__next)) + erase(__next); + else + __first = __next; + __next = __first; + } + } + + void + merge(list& __x) + { + __glibcxx_check_sorted(_Base::begin(), _Base::end()); + __glibcxx_check_sorted(__x.begin().base(), __x.end().base()); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base()); + } + + template<class _Compare> + void + merge(list& __x, _Compare __comp) + { + __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp); + __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(), + __comp); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base(), __comp); + } + + void + sort() { _Base::sort(); } + + template<typename _StrictWeakOrdering> + void + sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); } + + using _Base::reverse; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Tp, typename _Alloc> + inline bool + operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline void + swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __debug +} // namespace std + +#endif diff --git a/libstdc++/include/debug/macros.h b/libstdc++/include/debug/macros.h new file mode 100644 index 0000000..ce40919 --- /dev/null +++ b/libstdc++/include/debug/macros.h @@ -0,0 +1,224 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2003, 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. + +/** @file debug/macros.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_MACROS_H +#define _GLIBCXX_DEBUG_MACROS_H 1 + +/** + * Macros used by the implementation to verify certain + * properties. These macros may only be used directly by the debug + * wrappers. Note that these are macros (instead of the more obviously + * "correct" choice of making them functions) because we need line and + * file information at the call site, to minimize the distance between + * the user error and where the error is reported. + * + */ +#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \ + do \ + { \ + if (! (_Condition)) \ + __gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \ + ._ErrorMessage._M_error(); \ + } while (false) + +// Verify that [_First, _Last) forms a valid iterator range. +#define __glibcxx_check_valid_range(_First,_Last) \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__valid_range(_First, _Last), \ + _M_message(__gnu_debug::__msg_valid_range) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that we can insert into *this with the iterator _Position. + * Insertion into a container at a specific position requires that + * the iterator be nonsingular (i.e., either dereferenceable or + * past-the-end) and that it reference the sequence we are inserting + * into. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. +*/ +#define __glibcxx_check_insert(_Position) \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can insert the values in the iterator range + * [_First, _Last) into *this with the iterator _Position. Insertion + * into a container at a specific position requires that the iterator + * be nonsingular (i.e., either dereferenceable or past-the-end), + * that it reference the sequence we are inserting into, and that the + * iterator range [_First, Last) is a valid (possibly empty) + * range. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. + * + * @tbd We would like to be able to check for noninterference of + * _Position and the range [_First, _Last), but that can't (in + * general) be done. +*/ +#define __glibcxx_check_insert_range(_Position,_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the element referenced by the iterator + * _Position. We can erase the element if the _Position iterator is + * dereferenceable and references this sequence. +*/ +#define __glibcxx_check_erase(_Position) \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \ + _M_message(__gnu_debug::__msg_erase_bad) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the elements in the iterator range + * [_First, _Last). We can erase the elements if [_First, _Last) is a + * valid iterator range within this sequence. +*/ +#define __glibcxx_check_erase_range(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ + _M_message(__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +// Verify that the subscript _N is less than the container's size. +#define __glibcxx_check_subscript(_N) \ +_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ + _M_message(__gnu_debug::__msg_subscript_oob) \ + ._M_sequence(*this, "this") \ + ._M_integer(_N, #_N) \ + ._M_integer(this->size(), "size")) + +// Verify that the container is nonempty +#define __glibcxx_check_nonempty() \ +_GLIBCXX_DEBUG_VERIFY(! this->empty(), \ + _M_message(__gnu_debug::__msg_empty) \ + ._M_sequence(*this, "this")) + +// Verify that the < operator for elements in the sequence is a +// StrictWeakOrdering by checking that it is irreflexive. +#define __glibcxx_check_strict_weak_ordering(_First,_Last) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First)) + +// Verify that the predicate is StrictWeakOrdering by checking that it +// is irreflexive. +#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First)) + + +// Verify that the iterator range [_First, _Last) is sorted +#define __glibcxx_check_sorted(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last), \ + _M_message(__gnu_debug::__msg_unsorted) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is sorted by the + predicate _Pred. */ +#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last, _Pred), \ + _M_message(__gnu_debug::__msg_unsorted_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value. */ +#define __glibcxx_check_partitioned(_First,_Last,_Value) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned(_First, _Last, \ + _Value), \ + _M_message(__gnu_debug::__msg_unpartitioned) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Value)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value and predicate _Pred. */ +#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned(_First, _Last, \ + _Value, _Pred), \ + _M_message(__gnu_debug::__msg_unpartitioned_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred) \ + ._M_string(#_Value)) + +// Verify that the iterator range [_First, _Last) is a heap +#define __glibcxx_check_heap(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(std::__is_heap(_First, _Last), \ + _M_message(__gnu_debug::__msg_not_heap) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is a heap + w.r.t. the predicate _Pred. */ +#define __glibcxx_check_heap_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(std::__is_heap(_First, _Last, _Pred), \ + _M_message(__gnu_debug::__msg_not_heap_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +#ifdef _GLIBCXX_DEBUG_PEDANTIC +# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0) +# define __glibcxx_check_string_len(_String,_Len) \ + _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0) +#else +# define __glibcxx_check_string(_String) +# define __glibcxx_check_string_len(_String,_Len) +#endif + +#endif diff --git a/libstdc++/include/debug/map b/libstdc++/include/debug/map new file mode 100644 index 0000000..2435154 --- /dev/null +++ b/libstdc++/include/debug/map @@ -0,0 +1,42 @@ +// Debugging map/multimap implementation -*- C++ -*- + +// Copyright (C) 2003, 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. + +/** @file debug/map + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_MAP +#define _GLIBCXX_DEBUG_MAP 1 + +#include <map> +#include <debug/map.h> +#include <debug/multimap.h> + +#endif diff --git a/libstdc++/include/debug/map.h b/libstdc++/include/debug/map.h new file mode 100644 index 0000000..96591ca --- /dev/null +++ b/libstdc++/include/debug/map.h @@ -0,0 +1,334 @@ +// Debugging map implementation -*- C++ -*- + +// 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. + +/** @file debug/map.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_MAP_H +#define _GLIBCXX_DEBUG_MAP_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace std +{ +namespace __debug +{ + template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > > + class map + : public _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> > + { + typedef _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<map> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair<const _Key, _Tp> value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, map> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, map> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit map(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template<typename _InputIterator> + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a), _Safe_base() { } + + map(const map<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + map(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~map() { } + + map<_Key,_Tp,_Compare,_Allocator>& + operator=(const map<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 133. map missing get_allocator() + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // 23.3.1.2 element access: + using _Base::operator[]; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 464. Suggestion for new member functions in standard containers. + using _Base::at; + + // modifiers: + std::pair<iterator, bool> + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair<iterator, bool>(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(map<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 map operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator==(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator!=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator<(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator<=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator>=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator>(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline void + swap(map<_Key,_Tp,_Compare,_Allocator>& __lhs, + map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __debug +} // namespace std + +#endif diff --git a/libstdc++/include/debug/multimap.h b/libstdc++/include/debug/multimap.h new file mode 100644 index 0000000..cbd6704 --- /dev/null +++ b/libstdc++/include/debug/multimap.h @@ -0,0 +1,321 @@ +// Debugging multimap implementation -*- C++ -*- + +// 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. + +/** @file debug/multimap.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_MULTIMAP_H +#define _GLIBCXX_DEBUG_MULTIMAP_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace std +{ +namespace __debug +{ + template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > > + class multimap + : public _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence<multimap<_Key,_Tp,_Compare,_Allocator> > + { + typedef _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair<const _Key, _Tp> value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multimap> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + multimap> const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit multimap(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template<typename _InputIterator> + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + multimap(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + multimap(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multimap() { } + + multimap<_Key,_Tp,_Compare,_Allocator>& + operator=(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair<iterator, iterator> __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 multimap operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator!=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator<=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator>=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator>(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __debug +} // namespace std + +#endif diff --git a/libstdc++/include/debug/multiset.h b/libstdc++/include/debug/multiset.h new file mode 100644 index 0000000..a37099e --- /dev/null +++ b/libstdc++/include/debug/multiset.h @@ -0,0 +1,327 @@ +// Debugging multiset implementation -*- C++ -*- + +// 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. + +/** @file debug/multiset.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_MULTISET_H +#define _GLIBCXX_DEBUG_MULTISET_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace std +{ +namespace __debug +{ + template<typename _Key, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<_Key> > + class multiset + : public _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> > + { + typedef _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<multiset> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multiset> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + multiset> const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit multiset(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template<typename _InputIterator> + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + multiset(const multiset<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multiset() { } + + multiset<_Key,_Compare,_Allocator>& + operator=(const multiset<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair<iterator, iterator> __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multiset<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // multiset operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator==(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator!=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + void + swap(multiset<_Key,_Compare,_Allocator>& __x, + multiset<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __debug +} // namespace std + +#endif diff --git a/libstdc++/include/debug/safe_base.h b/libstdc++/include/debug/safe_base.h new file mode 100644 index 0000000..2d26f57 --- /dev/null +++ b/libstdc++/include/debug/safe_base.h @@ -0,0 +1,225 @@ +// Safe sequence/iterator base implementation -*- C++ -*- + +// Copyright (C) 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. + +/** @file debug/safe_base.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_SAFE_BASE_H +#define _GLIBCXX_DEBUG_SAFE_BASE_H 1 + +#include <ext/concurrence.h> + +namespace __gnu_debug +{ + class _Safe_sequence_base; + + /** \brief Basic functionality for a "safe" iterator. + * + * The %_Safe_iterator_base base class implements the functionality + * of a safe iterator that is not specific to a particular iterator + * type. It contains a pointer back to the sequence it references + * along with iterator version information and pointers to form a + * doubly-linked list of iterators referenced by the container. + * + * This class must not perform any operations that can throw an + * exception, or the exception guarantees of derived iterators will + * be broken. + */ + class _Safe_iterator_base + { + public: + /** The sequence this iterator references; may be NULL to indicate + a singular iterator. */ + _Safe_sequence_base* _M_sequence; + + /** The version number of this iterator. The sentinel value 0 is + * used to indicate an invalidated iterator (i.e., one that is + * singular because of an operation on the container). This + * version number must equal the version number in the sequence + * referenced by _M_sequence for the iterator to be + * non-singular. + */ + unsigned int _M_version; + + /** Pointer to the previous iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_prior; + + /** Pointer to the next iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_next; + + protected: + /** Initializes the iterator and makes it singular. */ + _Safe_iterator_base() + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { } + + /** Initialize the iterator to reference the sequence pointed to + * by @p__seq. @p __constant is true when we are initializing a + * constant iterator, and false if it is a mutable iterator. Note + * that @p __seq may be NULL, in which case the iterator will be + * singular. Otherwise, the iterator will reference @p __seq and + * be nonsingular. + */ + _Safe_iterator_base(const _Safe_sequence_base* __seq, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); } + + /** Initializes the iterator to reference the same sequence that + @p __x does. @p __constant is true if this is a constant + iterator, and false if it is mutable. */ + _Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(__x._M_sequence, __constant); } + + _Safe_iterator_base& + operator=(const _Safe_iterator_base&); + + explicit + _Safe_iterator_base(const _Safe_iterator_base&); + + ~_Safe_iterator_base() { this->_M_detach(); } + + /** For use in _Safe_iterator. */ + __gnu_cxx::__mutex& _M_get_mutex(); + + public: + /** Attaches this iterator to the given sequence, detaching it + * from whatever sequence it was attached to originally. If the + * new sequence is the NULL pointer, the iterator is left + * unattached. + */ + void _M_attach(_Safe_sequence_base* __seq, bool __constant); + + /** Likewise, but not thread-safe. */ + void _M_attach_single(_Safe_sequence_base* __seq, bool __constant); + + /** Detach the iterator for whatever sequence it is attached to, + * if any. + */ + void _M_detach(); + + /** Likewise, but not thread-safe. */ + void _M_detach_single(); + + /** Determines if we are attached to the given sequence. */ + bool _M_attached_to(const _Safe_sequence_base* __seq) const + { return _M_sequence == __seq; } + + /** Is this iterator singular? */ + bool _M_singular() const; + + /** Can we compare this iterator to the given iterator @p __x? + Returns true if both iterators are nonsingular and reference + the same sequence. */ + bool _M_can_compare(const _Safe_iterator_base& __x) const; + }; + + /** + * @brief Base class that supports tracking of iterators that + * reference a sequence. + * + * The %_Safe_sequence_base class provides basic support for + * tracking iterators into a sequence. Sequences that track + * iterators must derived from %_Safe_sequence_base publicly, so + * that safe iterators (which inherit _Safe_iterator_base) can + * attach to them. This class contains two linked lists of + * iterators, one for constant iterators and one for mutable + * iterators, and a version number that allows very fast + * invalidation of all iterators that reference the container. + * + * This class must ensure that no operation on it may throw an + * exception, otherwise "safe" sequences may fail to provide the + * exception-safety guarantees required by the C++ standard. + */ + class _Safe_sequence_base + { + public: + /// The list of mutable iterators that reference this container + _Safe_iterator_base* _M_iterators; + + /// The list of constant iterators that reference this container + _Safe_iterator_base* _M_const_iterators; + + /// The container version number. This number may never be 0. + mutable unsigned int _M_version; + + protected: + // Initialize with a version number of 1 and no iterators + _Safe_sequence_base() + : _M_iterators(0), _M_const_iterators(0), _M_version(1) + { } + + /** Notify all iterators that reference this sequence that the + sequence is being destroyed. */ + ~_Safe_sequence_base() + { this->_M_detach_all(); } + + /** Detach all iterators, leaving them singular. */ + void + _M_detach_all(); + + /** Detach all singular iterators. + * @post for all iterators i attached to this sequence, + * i->_M_version == _M_version. + */ + void + _M_detach_singular(); + + /** Revalidates all attached singular iterators. This method may + * be used to validate iterators that were invalidated before + * (but for some reasion, such as an exception, need to become + * valid again). + */ + void + _M_revalidate_singular(); + + /** Swap this sequence with the given sequence. This operation + * also swaps ownership of the iterators, so that when the + * operation is complete all iterators that originally referenced + * one container now reference the other container. + */ + void + _M_swap(_Safe_sequence_base& __x); + + /** For use in _Safe_sequence. */ + __gnu_cxx::__mutex& _M_get_mutex(); + + public: + /** Invalidates all iterators. */ + void + _M_invalidate_all() const + { if (++_M_version == 0) _M_version = 1; } + }; +} // namespace __gnu_debug + +#endif diff --git a/libstdc++/include/debug/safe_iterator.h b/libstdc++/include/debug/safe_iterator.h new file mode 100644 index 0000000..3d8ba59 --- /dev/null +++ b/libstdc++/include/debug/safe_iterator.h @@ -0,0 +1,648 @@ +// Safe iterator implementation -*- C++ -*- + +// Copyright (C) 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. + +/** @file debug/safe_iterator.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H +#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 + +#include <debug/debug.h> +#include <debug/macros.h> +#include <debug/functions.h> +#include <debug/formatter.h> +#include <debug/safe_base.h> +#include <bits/stl_pair.h> +#include <ext/type_traits.h> + +namespace __gnu_debug +{ + /** Iterators that derive from _Safe_iterator_base but that aren't + * _Safe_iterators can be determined singular or non-singular via + * _Safe_iterator_base. + */ + inline bool + __check_singular_aux(const _Safe_iterator_base* __x) + { return __x->_M_singular(); } + + /** \brief Safe iterator wrapper. + * + * The class template %_Safe_iterator is a wrapper around an + * iterator that tracks the iterator's movement among sequences and + * checks that operations performed on the "safe" iterator are + * legal. In additional to the basic iterator operations (which are + * validated, and then passed to the underlying iterator), + * %_Safe_iterator has member functions for iterator invalidation, + * attaching/detaching the iterator from sequences, and querying + * the iterator's state. + */ + template<typename _Iterator, typename _Sequence> + class _Safe_iterator : public _Safe_iterator_base + { + typedef _Safe_iterator _Self; + + /** The precision to which we can calculate the distance between + * two iterators. + */ + enum _Distance_precision + { + __dp_equality, //< Can compare iterator equality, only + __dp_sign, //< Can determine equality and ordering + __dp_exact //< Can determine distance precisely + }; + + /// The underlying iterator + _Iterator _M_current; + + /// Determine if this is a constant iterator. + bool + _M_constant() const + { + typedef typename _Sequence::const_iterator const_iterator; + return __is_same<const_iterator, _Safe_iterator>::value; + } + + typedef std::iterator_traits<_Iterator> _Traits; + + public: + typedef _Iterator _Base_iterator; + typedef typename _Traits::iterator_category iterator_category; + typedef typename _Traits::value_type value_type; + typedef typename _Traits::difference_type difference_type; + typedef typename _Traits::reference reference; + typedef typename _Traits::pointer pointer; + + /// @post the iterator is singular and unattached + _Safe_iterator() : _M_current() { } + + /** + * @brief Safe iterator construction from an unsafe iterator and + * its sequence. + * + * @pre @p seq is not NULL + * @post this is not singular + */ + _Safe_iterator(const _Iterator& __i, const _Sequence* __seq) + : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__msg_init_singular) + ._M_iterator(*this, "this")); + } + + /** + * @brief Copy construction. + * @pre @p x is not singular + */ + _Safe_iterator(const _Safe_iterator& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_init_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Converting constructor from a mutable iterator to a + * constant iterator. + * + * @pre @p x is not singular + */ + template<typename _MutableIterator> + _Safe_iterator( + const _Safe_iterator<_MutableIterator, + typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, + typename _Sequence::iterator::_Base_iterator>::__value), + _Sequence>::__type>& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_init_const_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Copy assignment. + * @pre @p x is not singular + */ + _Safe_iterator& + operator=(const _Safe_iterator& __x) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + _M_current = __x._M_current; + this->_M_attach(static_cast<_Sequence*>(__x._M_sequence)); + return *this; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + */ + reference + operator*() const + { + + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__msg_bad_deref) + ._M_iterator(*this, "this")); + return *_M_current; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + * @todo Make this correct w.r.t. iterators that return proxies + * @todo Use addressof() instead of & operator + */ + pointer + operator->() const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__msg_bad_deref) + ._M_iterator(*this, "this")); + return &*_M_current; + } + + // ------ Input iterator requirements ------ + /** + * @brief Iterator preincrement + * @pre iterator is incrementable + */ + _Safe_iterator& + operator++() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__msg_bad_inc) + ._M_iterator(*this, "this")); + ++_M_current; + return *this; + } + + /** + * @brief Iterator postincrement + * @pre iterator is incrementable + */ + _Safe_iterator + operator++(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__msg_bad_inc) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + ++_M_current; + return __tmp; + } + + // ------ Bidirectional iterator requirements ------ + /** + * @brief Iterator predecrement + * @pre iterator is decrementable + */ + _Safe_iterator& + operator--() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__msg_bad_dec) + ._M_iterator(*this, "this")); + --_M_current; + return *this; + } + + /** + * @brief Iterator postdecrement + * @pre iterator is decrementable + */ + _Safe_iterator + operator--(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__msg_bad_dec) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + --_M_current; + return __tmp; + } + + // ------ Random access iterator requirements ------ + reference + operator[](const difference_type& __n) const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) + && this->_M_can_advance(__n+1), + _M_message(__msg_iter_subscript_oob) + ._M_iterator(*this)._M_integer(__n)); + + return _M_current[__n]; + } + + _Safe_iterator& + operator+=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), + _M_message(__msg_advance_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += __n; + return *this; + } + + _Safe_iterator + operator+(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp += __n; + return __tmp; + } + + _Safe_iterator& + operator-=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), + _M_message(__msg_retreat_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += -__n; + return *this; + } + + _Safe_iterator + operator-(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp -= __n; + return __tmp; + } + + // ------ Utilities ------ + /** + * @brief Return the underlying iterator + */ + _Iterator + base() const { return _M_current; } + + /** + * @brief Conversion to underlying non-debug iterator to allow + * better interaction with non-debug containers. + */ + operator _Iterator() const { return _M_current; } + + /** Attach iterator to the given sequence. */ + void + _M_attach(const _Sequence* __seq) + { + _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq), + _M_constant()); + } + + /** Likewise, but not thread-safe. */ + void + _M_attach_single(const _Sequence* __seq) + { + _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq), + _M_constant()); + } + + /** Invalidate the iterator, making it singular. */ + void + _M_invalidate(); + + /** Likewise, but not thread-safe. */ + void + _M_invalidate_single(); + + /// Is the iterator dereferenceable? + bool + _M_dereferenceable() const + { return !this->_M_singular() && !_M_is_end(); } + + /// Is the iterator incrementable? + bool + _M_incrementable() const { return this->_M_dereferenceable(); } + + // Is the iterator decrementable? + bool + _M_decrementable() const { return !_M_singular() && !_M_is_begin(); } + + // Can we advance the iterator @p __n steps (@p __n may be negative) + bool + _M_can_advance(const difference_type& __n) const; + + // Is the iterator range [*this, __rhs) valid? + template<typename _Other> + bool + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const; + + // The sequence this iterator references. + const _Sequence* + _M_get_sequence() const + { return static_cast<const _Sequence*>(_M_sequence); } + + /** Determine the distance between two iterators with some known + * precision. + */ + template<typename _Iterator1, typename _Iterator2> + static std::pair<difference_type, _Distance_precision> + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs) + { + typedef typename std::iterator_traits<_Iterator1>::iterator_category + _Category; + return _M_get_distance(__lhs, __rhs, _Category()); + } + + template<typename _Iterator1, typename _Iterator2> + static std::pair<difference_type, _Distance_precision> + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::random_access_iterator_tag) + { + return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact); + } + + template<typename _Iterator1, typename _Iterator2> + static std::pair<difference_type, _Distance_precision> + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::forward_iterator_tag) + { + return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1, + __dp_equality); + } + + /// Is this iterator equal to the sequence's begin() iterator? + bool _M_is_begin() const + { return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); } + + /// Is this iterator equal to the sequence's end() iterator? + bool _M_is_end() const + { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); } + }; + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type + operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_distance_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_distance_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() - __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type + operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_distance_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_distance_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() - __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline _Safe_iterator<_Iterator, _Sequence> + operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, + const _Safe_iterator<_Iterator, _Sequence>& __i) + { return __i + __n; } +} // namespace __gnu_debug + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <debug/safe_iterator.tcc> +#endif + +#endif diff --git a/libstdc++/include/debug/safe_iterator.tcc b/libstdc++/include/debug/safe_iterator.tcc new file mode 100644 index 0000000..d23e90f --- /dev/null +++ b/libstdc++/include/debug/safe_iterator.tcc @@ -0,0 +1,148 @@ +// Debugging iterator implementation (out of line) -*- C++ -*- + +// Copyright (C) 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. + +/** @file debug/safe_iterator.tcc + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC +#define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1 + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_can_advance(const difference_type& __n) const + { + typedef typename _Sequence::const_iterator const_iterator; + + if (this->_M_singular()) + return false; + if (__n == 0) + return true; + if (__n < 0) + { + const_iterator __begin = + static_cast<const _Sequence*>(_M_sequence)->begin(); + std::pair<difference_type, _Distance_precision> __dist = + this->_M_get_distance(__begin, *this); + bool __ok = (__dist.second == __dp_exact && __dist.first >= -__n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + else + { + const_iterator __end = + static_cast<const _Sequence*>(_M_sequence)->end(); + std::pair<difference_type, _Distance_precision> __dist = + this->_M_get_distance(*this, __end); + bool __ok = (__dist.second == __dp_exact && __dist.first >= __n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + } + + template<typename _Iterator, typename _Sequence> + template<typename _Other> + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const + { + if (!_M_can_compare(__rhs)) + return false; + + /* Determine if we can order the iterators without the help of + the container */ + std::pair<difference_type, _Distance_precision> __dist = + this->_M_get_distance(*this, __rhs); + switch (__dist.second) { + case __dp_equality: + if (__dist.first == 0) + return true; + break; + + case __dp_sign: + case __dp_exact: + return __dist.first >= 0; + } + + /* We can only test for equality, but check if one of the + iterators is at an extreme. */ + if (_M_is_begin() || __rhs._M_is_end()) + return true; + else if (_M_is_end() || __rhs._M_is_begin()) + return false; + + // Assume that this is a valid range; we can't check anything else + return true; + } + + template<typename _Iterator, typename _Sequence> + void + _Safe_iterator<_Iterator, _Sequence>:: + _M_invalidate() + { + __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); + _M_invalidate_single(); + } + + template<typename _Iterator, typename _Sequence> + void + _Safe_iterator<_Iterator, _Sequence>:: + _M_invalidate_single() + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + if (!this->_M_singular()) + { + for (_Safe_iterator_base* __iter = _M_sequence->_M_iterators; + __iter; __iter = __iter->_M_next) + { + iterator* __victim = static_cast<iterator*>(__iter); + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + + for (_Safe_iterator_base* __iter2 = _M_sequence->_M_const_iterators; + __iter2; __iter2 = __iter2->_M_next) + { + const_iterator* __victim = static_cast<const_iterator*>(__iter2); + if (__victim->base() == this->base()) + __victim->_M_version = 0; + } + _M_version = 0; + } + } +} // namespace __gnu_debug + +#endif + diff --git a/libstdc++/include/debug/safe_sequence.h b/libstdc++/include/debug/safe_sequence.h new file mode 100644 index 0000000..b5d6cce --- /dev/null +++ b/libstdc++/include/debug/safe_sequence.h @@ -0,0 +1,188 @@ +// Safe sequence implementation -*- C++ -*- + +// Copyright (C) 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. + +/** @file debug/safe_sequence.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H +#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1 + +#include <debug/debug.h> +#include <debug/macros.h> +#include <debug/functions.h> +#include <debug/safe_base.h> + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + class _Safe_iterator; + + /** A simple function object that returns true if the passed-in + * value is not equal to the stored value. It saves typing over + * using both bind1st and not_equal. + */ + template<typename _Type> + class _Not_equal_to + { + _Type __value; + + public: + explicit _Not_equal_to(const _Type& __v) : __value(__v) { } + + bool + operator()(const _Type& __x) const + { return __value != __x; } + }; + + /** A function object that returns true when the given random access + iterator is at least @c n steps away from the given iterator. */ + template<typename _Iterator> + class _After_nth_from + { + typedef typename std::iterator_traits<_Iterator>::difference_type + difference_type; + + _Iterator _M_base; + difference_type _M_n; + + public: + _After_nth_from(const difference_type& __n, const _Iterator& __base) + : _M_base(__base), _M_n(__n) { } + + bool + operator()(const _Iterator& __x) const + { return __x - _M_base >= _M_n; } + }; + + /** + * @brief Base class for constructing a "safe" sequence type that + * tracks iterators that reference it. + * + * The class template %_Safe_sequence simplifies the construction of + * "safe" sequences that track the iterators that reference the + * sequence, so that the iterators are notified of changes in the + * sequence that may affect their operation, e.g., if the container + * invalidates its iterators or is destructed. This class template + * may only be used by deriving from it and passing the name of the + * derived class as its template parameter via the curiously + * recurring template pattern. The derived class must have @c + * iterator and @const_iterator types that are instantiations of + * class template _Safe_iterator for this sequence. Iterators will + * then be tracked automatically. + */ + template<typename _Sequence> + class _Safe_sequence : public _Safe_sequence_base + { + public: + /** Invalidates all iterators @c x that reference this sequence, + are not singular, and for which @c pred(x) returns @c + true. The user of this routine should be careful not to make + copies of the iterators passed to @p pred, as the copies may + interfere with the invalidation. */ + template<typename _Predicate> + void + _M_invalidate_if(_Predicate __pred); + + /** Transfers all iterators that reference this memory location + to this sequence from whatever sequence they are attached + to. */ + template<typename _Iterator> + void + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x); + }; + + template<typename _Sequence> + template<typename _Predicate> + void + _Safe_sequence<_Sequence>:: + _M_invalidate_if(_Predicate __pred) + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); + for (_Safe_iterator_base* __iter = _M_iterators; __iter;) + { + iterator* __victim = static_cast<iterator*>(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate_single(); + } + } + + for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;) + { + const_iterator* __victim = static_cast<const_iterator*>(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate_single(); + } + } + } + + template<typename _Sequence> + template<typename _Iterator> + void + _Safe_sequence<_Sequence>:: + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x) + { + _Safe_sequence_base* __from = __x._M_sequence; + if (!__from) + return; + + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); + for (_Safe_iterator_base* __iter = __from->_M_iterators; __iter;) + { + iterator* __victim = static_cast<iterator*>(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach_single(static_cast<_Sequence*>(this)); + } + + for (_Safe_iterator_base* __iter2 = __from->_M_const_iterators; + __iter2;) + { + const_iterator* __victim = static_cast<const_iterator*>(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach_single(static_cast<_Sequence*>(this)); + } + } +} // namespace __gnu_debug + +#endif diff --git a/libstdc++/include/debug/set b/libstdc++/include/debug/set new file mode 100644 index 0000000..e5f4e37 --- /dev/null +++ b/libstdc++/include/debug/set @@ -0,0 +1,42 @@ +// Debugging set/multiset implementation -*- C++ -*- + +// Copyright (C) 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. + +/** @file debug/set + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_SET +#define _GLIBCXX_DEBUG_SET 1 + +#include <set> +#include <debug/set.h> +#include <debug/multiset.h> + +#endif diff --git a/libstdc++/include/debug/set.h b/libstdc++/include/debug/set.h new file mode 100644 index 0000000..6c2ce9f --- /dev/null +++ b/libstdc++/include/debug/set.h @@ -0,0 +1,332 @@ +// Debugging set implementation -*- C++ -*- + +// 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. + +/** @file debug/set.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_SET_H +#define _GLIBCXX_DEBUG_SET_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace std +{ +namespace __debug +{ + template<typename _Key, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<_Key> > + class set + : public _GLIBCXX_STD::set<_Key,_Compare,_Allocator>, + public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> > + { + typedef _GLIBCXX_STD::set<_Key,_Compare,_Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<set> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, set> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, set> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit set(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template<typename _InputIterator> + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + set(const set<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + set(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~set() { } + + set<_Key,_Compare,_Allocator>& + operator=(const set<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + std::pair<iterator, bool> + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair<iterator, bool>(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + while (__first != __last) + this->erase(__first++); + } + + void + swap(set<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // set operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator==(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator!=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + void + swap(set<_Key,_Compare,_Allocator>& __x, + set<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __debug +} // namespace std + +#endif diff --git a/libstdc++/include/debug/string b/libstdc++/include/debug/string new file mode 100644 index 0000000..070ca1f --- /dev/null +++ b/libstdc++/include/debug/string @@ -0,0 +1,1023 @@ +// Debugging string implementation -*- C++ -*- + +// Copyright (C) 2003, 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. + +/** @file debug/string + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_STRING +#define _GLIBCXX_DEBUG_STRING 1 + +#include <string> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug +{ + template<typename _CharT, typename _Traits = std::char_traits<_CharT>, + typename _Allocator = std::allocator<_CharT> > + class basic_string + : public std::basic_string<_CharT, _Traits, _Allocator>, + public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits, + _Allocator> > + { + typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<basic_string> _Safe_base; + + public: + // types: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + basic_string> const_iterator; + + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + using _Base::npos; + + // 21.3.1 construct/copy/destroy: + explicit basic_string(const _Allocator& __a = _Allocator()) + : _Base(__a) + { } + + // Provides conversion from a release-mode string to a debug-mode string + basic_string(const _Base& __base) : _Base(__base), _Safe_base() { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str) + : _Base(__str, 0, _Base::npos, __str.get_allocator()), _Safe_base() + { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str, size_type __pos, + size_type __n = _Base::npos, + const _Allocator& __a = _Allocator()) + : _Base(__str, __pos, __n, __a) + { } + + basic_string(const _CharT* __s, size_type __n, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) + { } + + basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s), __a) + { this->assign(__s); } + + basic_string(size_type __n, _CharT __c, + const _Allocator& __a = _Allocator()) + : _Base(__n, __c, __a) + { } + + template<typename _InputIterator> + basic_string(_InputIterator __begin, _InputIterator __end, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__begin, __end), __end, __a) + { } + + ~basic_string() { } + + basic_string& + operator=(const basic_string& __str) + { + *static_cast<_Base*>(this) = __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(const _CharT* __s) + { + __glibcxx_check_string(__s); + *static_cast<_Base*>(this) = __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(_CharT __c) + { + *static_cast<_Base*>(this) = __c; + this->_M_invalidate_all(); + return *this; + } + + // 21.3.2 iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 21.3.3 capacity: + using _Base::size; + using _Base::length; + using _Base::max_size; + + void + resize(size_type __n, _CharT __c) + { + _Base::resize(__n, __c); + this->_M_invalidate_all(); + } + + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + + using _Base::capacity; + using _Base::reserve; + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::empty; + + // 21.3.4 element access: + const_reference + operator[](size_type __pos) const + { + _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), + _M_message(__gnu_debug::__msg_subscript_oob) + ._M_sequence(*this, "this") + ._M_integer(__pos, "__pos") + ._M_integer(this->size(), "size")); + return _M_base()[__pos]; + } + + reference + operator[](size_type __pos) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + __glibcxx_check_subscript(__pos); +#else + // as an extension v3 allows s[s.size()] when s is non-const. + _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), + _M_message(__gnu_debug::__msg_subscript_oob) + ._M_sequence(*this, "this") + ._M_integer(__pos, "__pos") + ._M_integer(this->size(), "size")); +#endif + return _M_base()[__pos]; + } + + using _Base::at; + + // 21.3.5 modifiers: + basic_string& + operator+=(const basic_string& __str) + { + _M_base() += __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(const _CharT* __s) + { + __glibcxx_check_string(__s); + _M_base() += __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(_CharT __c) + { + _M_base() += __c; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str) + { + _Base::append(__str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::append(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::append(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::append(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(size_type __n, _CharT __c) + { + _Base::append(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template<typename _InputIterator> + basic_string& + append(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::append(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 7. string clause minor problems + void + push_back(_CharT __c) + { + _Base::push_back(__c); + this->_M_invalidate_all(); + } + + basic_string& + assign(const basic_string& __x) + { + _Base::assign(__x); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::assign(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::assign(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::assign(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(size_type __n, _CharT __c) + { + _Base::assign(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template<typename _InputIterator> + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str) + { + _Base::insert(__pos1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { + _Base::insert(__pos1, __str, __pos2, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { + _Base::insert(__pos, __n, __c); + this->_M_invalidate_all(); + return *this; + } + + iterator + insert(iterator __p, _CharT __c) + { + __glibcxx_check_insert(__p); + typename _Base::iterator __res = _Base::insert(__p.base(), __c); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + void + insert(iterator __p, size_type __n, _CharT __c) + { + __glibcxx_check_insert(__p); + _Base::insert(__p.base(), __n, __c); + this->_M_invalidate_all(); + } + + template<typename _InputIterator> + void + insert(iterator __p, _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__p, __first, __last); + _Base::insert(__p.base(), __first, __last); + this->_M_invalidate_all(); + } + + basic_string& + erase(size_type __pos = 0, size_type __n = _Base::npos) + { + _Base::erase(__pos, __n); + this->_M_invalidate_all(); + return *this; + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str) + { + _Base::replace(__pos1, __n1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { + _Base::replace(__pos1, __n1, __str, __pos2, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_check_string_len(__s, __n2); + _Base::replace(__pos, __n1, __s, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::replace(__pos, __n1, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { + _Base::replace(__pos, __n1, __n2, __c); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string_len(__s, __n); + _Base::replace(__i1.base(), __i2.base(), __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string(__s); + _Base::replace(__i1.base(), __i2.base(), __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __n, __c); + this->_M_invalidate_all(); + return *this; + } + + template<typename _InputIterator> + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __j1, _InputIterator __j2) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_valid_range(__j1, __j2); + _Base::replace(__i1.base(), __i2.base(), __j1, __j2); + this->_M_invalidate_all(); + return *this; + } + + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::copy(__s, __n, __pos); + } + + void + swap(basic_string<_CharT,_Traits,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + this->_M_invalidate_all(); + __x._M_invalidate_all(); + } + + // 21.3.6 string operations: + const _CharT* + c_str() const + { + const _CharT* __res = _Base::c_str(); + this->_M_invalidate_all(); + return __res; + } + + const _CharT* + data() const + { + const _CharT* __res = _Base::data(); + this->_M_invalidate_all(); + return __res; + } + + using _Base::get_allocator; + + size_type + find(const basic_string& __str, size_type __pos = 0) const + { return _Base::find(__str, __pos); } + + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos, __n); + } + + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos); + } + + size_type + find(_CharT __c, size_type __pos = 0) const + { return _Base::find(__c, __pos); } + + size_type + rfind(const basic_string& __str, size_type __pos = _Base::npos) const + { return _Base::rfind(__str, __pos); } + + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::rfind(__s, __pos, __n); + } + + size_type + rfind(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::rfind(__s, __pos); + } + + size_type + rfind(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::rfind(__c, __pos); } + + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_of(__str, __pos); } + + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos, __n); + } + + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos); + } + + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_of(__c, __pos); } + + size_type + find_last_of(const basic_string& __str, + size_type __pos = _Base::npos) const + { return _Base::find_last_of(__str, __pos); } + + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos, __n); + } + + size_type + find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos); + } + + size_type + find_last_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_of(__c, __pos); } + + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_not_of(__str, __pos); } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::find_first_not_of(__s, __pos, __n); + } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_not_of(__s, __pos); + } + + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_not_of(__c, __pos); } + + size_type + find_last_not_of(const basic_string& __str, + size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__str, __pos); } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos, __n); + } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos); + } + + size_type + find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__c, __pos); } + + basic_string + substr(size_type __pos = 0, size_type __n = _Base::npos) const + { return basic_string(_Base::substr(__pos, __n)); } + + int + compare(const basic_string& __str) const + { return _Base::compare(__str); } + + int + compare(size_type __pos1, size_type __n1, + const basic_string& __str) const + { return _Base::compare(__pos1, __n1, __str); } + + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); } + + int + compare(const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1, const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__pos1, __n1, __s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1,const _CharT* __s, + size_type __n2) const + { + __glibcxx_check_string_len(__s, __n2); + return _Base::compare(__pos1, __n1, __s, __n2); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + using _Safe_base::_M_invalidate_all; + }; + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(_CharT __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + _CharT __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs == __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() == __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs != __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() != __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs < __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() < __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs <= __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() <= __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs >= __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() >= __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs > __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() > __rhs; + } + + // 21.3.7.8: + template<typename _CharT, typename _Traits, typename _Allocator> + inline void + swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, + basic_string<_CharT,_Traits,_Allocator>& __rhs) + { __lhs.swap(__rhs); } + + template<typename _CharT, typename _Traits, typename _Allocator> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT, _Traits, _Allocator>& __str) + { return __os << __str._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + std::basic_istream<_CharT,_Traits>& + operator>>(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base(); + __str._M_invalidate_all(); + return __res; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim) + { + std::basic_istream<_CharT,_Traits>& __res = getline(__is, + __str._M_base(), + __delim); + __str._M_invalidate_all(); + return __res; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = getline(__is, + __str._M_base()); + __str._M_invalidate_all(); + return __res; + } + + typedef basic_string<char> string; + +#ifdef _GLIBCXX_USE_WCHAR_T + typedef basic_string<wchar_t> wstring; +#endif + +} // namespace __gnu_debug + +#endif diff --git a/libstdc++/include/debug/vector b/libstdc++/include/debug/vector new file mode 100644 index 0000000..33b8b63 --- /dev/null +++ b/libstdc++/include/debug/vector @@ -0,0 +1,423 @@ +// Debugging vector implementation -*- C++ -*- + +// 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. + +/** @file debug/vector + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_VECTOR +#define _GLIBCXX_DEBUG_VECTOR 1 + +#include <vector> +#include <utility> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace std +{ +namespace __debug +{ + template<typename _Tp, + typename _Allocator = std::allocator<_Tp> > + class vector + : public _GLIBCXX_STD::vector<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > + { + typedef _GLIBCXX_STD::vector<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<vector> _Safe_base; + + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + public: + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,vector> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.2.4.1 construct/copy/destroy: + explicit vector(const _Allocator& __a = _Allocator()) + : _Base(__a), _M_guaranteed_capacity(0) { } + + explicit vector(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } + + template<class _InputIterator> + vector(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), + __last, __a), + _M_guaranteed_capacity(0) + { _M_update_guaranteed_capacity(); } + + vector(const vector<_Tp,_Allocator>& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } + + /// Construction from a release-mode vector + vector(const _Base& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } + + ~vector() { } + + vector<_Tp,_Allocator>& + operator=(const vector<_Tp,_Allocator>& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + return *this; + } + + template<typename _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + assign(size_type __n, const _Tp& __u) + { + _Base::assign(__n, __u); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.4.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + bool __realloc = _M_requires_reallocation(__sz); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + _Base::resize(__sz, __c); + if (__realloc) + this->_M_invalidate_all(); + } + + using _Base::capacity; + using _Base::empty; + + void + reserve(size_type __n) + { + bool __realloc = _M_requires_reallocation(__n); + _Base::reserve(__n); + if (__n > _M_guaranteed_capacity) + _M_guaranteed_capacity = __n; + if (__realloc) + this->_M_invalidate_all(); + } + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 464. Suggestion for new member functions in standard containers. + using _Base::data; + + // 23.2.4.3 modifiers: + void + push_back(const _Tp& __x) + { + bool __realloc = _M_requires_reallocation(this->size() + 1); + _Base::push_back(__x); + if (__realloc) + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end() - 1; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + 1); + difference_type __offset = __position - begin(); + typename _Base::iterator __res = _Base::insert(__position.base(),__x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + return iterator(__res, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + __n); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __n, __x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + template<class _InputIterator> + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + + /* Hard to guess if invalidation will occur, because __last + - __first can't be calculated in all cases, so we just + punt here by checking if it did occur. */ + typename _Base::iterator __old_begin = _M_base().begin(); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __first, __last); + + if (_M_base().begin() != __old_begin) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + difference_type __offset = __position - begin(); + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + difference_type __offset = __first - begin(); + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, this); + } + + void + swap(vector<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + _M_guaranteed_capacity = 0; + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + size_type _M_guaranteed_capacity; + + bool + _M_requires_reallocation(size_type __elements) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + return __elements > this->capacity(); +#else + return __elements > _M_guaranteed_capacity; +#endif + } + + void + _M_update_guaranteed_capacity() + { + if (this->size() > _M_guaranteed_capacity) + _M_guaranteed_capacity = this->size(); + } + }; + + template<typename _Tp, typename _Alloc> + inline bool + operator==(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline void + swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __debug +} // namespace std + +#endif diff --git a/libstdc++/include/ext/algorithm b/libstdc++/include/ext/algorithm new file mode 100644 index 0000000..712a4ed --- /dev/null +++ b/libstdc++/include/ext/algorithm @@ -0,0 +1,527 @@ +// Algorithm extensions -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/algorithm + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _EXT_ALGORITHM +#define _EXT_ALGORITHM 1 + +#pragma GCC system_header + +#include <algorithm> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::ptrdiff_t; + using std::min; + using std::pair; + using std::input_iterator_tag; + using std::random_access_iterator_tag; + using std::iterator_traits; + + //-------------------------------------------------- + // copy_n (not part of the C++ standard) + + template<typename _InputIterator, typename _Size, typename _OutputIterator> + pair<_InputIterator, _OutputIterator> + __copy_n(_InputIterator __first, _Size __count, + _OutputIterator __result, + input_iterator_tag) + { + for ( ; __count > 0; --__count) + { + *__result = *__first; + ++__first; + ++__result; + } + return pair<_InputIterator, _OutputIterator>(__first, __result); + } + + template<typename _RAIterator, typename _Size, typename _OutputIterator> + inline pair<_RAIterator, _OutputIterator> + __copy_n(_RAIterator __first, _Size __count, + _OutputIterator __result, + random_access_iterator_tag) + { + _RAIterator __last = __first + __count; + return pair<_RAIterator, _OutputIterator>(__last, std::copy(__first, + __last, + __result)); + } + + /** + * @brief Copies the range [first,first+count) into [result,result+count). + * @param first An input iterator. + * @param count The number of elements to copy. + * @param result An output iterator. + * @return A std::pair composed of first+count and result+count. + * + * This is an SGI extension. + * This inline function will boil down to a call to @c memmove whenever + * possible. Failing that, if random access iterators are passed, then the + * loop count will be known (and therefore a candidate for compiler + * optimizations such as unrolling). + * @ingroup SGIextensions + */ + template<typename _InputIterator, typename _Size, typename _OutputIterator> + inline pair<_InputIterator, _OutputIterator> + copy_n(_InputIterator __first, _Size __count, _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + + return __copy_n(__first, __count, __result, + std::__iterator_category(__first)); + } + + template<typename _InputIterator1, typename _InputIterator2> + int + __lexicographical_compare_3way(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2) + { + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first1 < *__first2) + return -1; + if (*__first2 < *__first1) + return 1; + ++__first1; + ++__first2; + } + if (__first2 == __last2) + return !(__first1 == __last1); + else + return -1; + } + + inline int + __lexicographical_compare_3way(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) + { + const ptrdiff_t __len1 = __last1 - __first1; + const ptrdiff_t __len2 = __last2 - __first2; + const int __result = std::memcmp(__first1, __first2, min(__len1, __len2)); + return __result != 0 ? __result + : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); + } + + inline int + __lexicographical_compare_3way(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) + { +#if CHAR_MAX == SCHAR_MAX + return __lexicographical_compare_3way((const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else + return __lexicographical_compare_3way((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif + } + + /** + * @brief @c memcmp on steroids. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param last2 An input iterator. + * @return An int, as with @c memcmp. + * + * The return value will be less than zero if the first range is + * "lexigraphically less than" the second, greater than zero if the second + * range is "lexigraphically less than" the first, and zero otherwise. + * This is an SGI extension. + * @ingroup SGIextensions + */ + template<typename _InputIterator1, typename _InputIterator2> + int + lexicographical_compare_3way(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return __lexicographical_compare_3way(__first1, __last1, __first2, + __last2); + } + + // count and count_if: this version, whose return type is void, was present + // in the HP STL, and is retained as an extension for backward compatibility. + template<typename _InputIterator, typename _Tp, typename _Size> + void + count(_InputIterator __first, _InputIterator __last, + const _Tp& __value, + _Size& __n) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type >) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + } + + template<typename _InputIterator, typename _Predicate, typename _Size> + void + count_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred, + _Size& __n) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + } + + // random_sample and random_sample_n (extensions, not part of the standard). + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _ForwardIterator, typename _OutputIterator, + typename _Distance> + _OutputIterator + random_sample_n(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __out, const _Distance __n) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + _Distance __remaining = std::distance(__first, __last); + _Distance __m = min(__n, __remaining); + + while (__m > 0) + { + if ((std::rand() % __remaining) < __m) + { + *__out = *__first; + ++__out; + --__m; + } + --__remaining; + ++__first; + } + return __out; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _ForwardIterator, typename _OutputIterator, + typename _Distance, typename _RandomNumberGenerator> + _OutputIterator + random_sample_n(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __out, const _Distance __n, + _RandomNumberGenerator& __rand) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_UnaryFunctionConcept< + _RandomNumberGenerator, _Distance, _Distance>) + __glibcxx_requires_valid_range(__first, __last); + + _Distance __remaining = std::distance(__first, __last); + _Distance __m = min(__n, __remaining); + + while (__m > 0) + { + if (__rand(__remaining) < __m) + { + *__out = *__first; + ++__out; + --__m; + } + --__remaining; + ++__first; + } + return __out; + } + + template<typename _InputIterator, typename _RandomAccessIterator, + typename _Distance> + _RandomAccessIterator + __random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out, + const _Distance __n) + { + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) + { + ++__t; + _Distance __M = std::rand() % (__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + return __out + __m; + } + + template<typename _InputIterator, typename _RandomAccessIterator, + typename _RandomNumberGenerator, typename _Distance> + _RandomAccessIterator + __random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out, + _RandomNumberGenerator& __rand, + const _Distance __n) + { + // concept requirements + __glibcxx_function_requires(_UnaryFunctionConcept< + _RandomNumberGenerator, _Distance, _Distance>) + + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) + { + ++__t; + _Distance __M = __rand(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + return __out + __m; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _InputIterator, typename _RandomAccessIterator> + inline _RandomAccessIterator + random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out_first, + _RandomAccessIterator __out_last) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); + + return __random_sample(__first, __last, + __out_first, __out_last - __out_first); + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _InputIterator, typename _RandomAccessIterator, + typename _RandomNumberGenerator> + inline _RandomAccessIterator + random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out_first, + _RandomAccessIterator __out_last, + _RandomNumberGenerator& __rand) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); + + return __random_sample(__first, __last, + __out_first, __rand, + __out_last - __out_first); + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _RandomAccessIterator> + inline bool + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__is_heap(__first, __last - __first); + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _RandomAccessIterator, typename _StrictWeakOrdering> + inline bool + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _StrictWeakOrdering __comp) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, + typename iterator_traits<_RandomAccessIterator>::value_type, + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__is_heap(__first, __comp, __last - __first); + } + + // is_sorted, a predicated testing whether a range is sorted in + // nondescending order. This is an extension, not part of the C++ + // standard. + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _ForwardIterator> + bool + is_sorted(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) + if (*__next < *__first) + return false; + return true; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _ForwardIterator, typename _StrictWeakOrdering> + bool + is_sorted(_ForwardIterator __first, _ForwardIterator __last, + _StrictWeakOrdering __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) + if (__comp(*__next, *__first)) + return false; + return true; + } + +_GLIBCXX_END_NAMESPACE + +#endif /* _EXT_ALGORITHM */ diff --git a/libstdc++/include/ext/array_allocator.h b/libstdc++/include/ext/array_allocator.h new file mode 100644 index 0000000..0bbd97a --- /dev/null +++ b/libstdc++/include/ext/array_allocator.h @@ -0,0 +1,149 @@ +// array allocator -*- C++ -*- + +// 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. + +/** @file ext/array_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _ARRAY_ALLOCATOR_H +#define _ARRAY_ALLOCATOR_H 1 + +#include <cstddef> +#include <new> +#include <bits/functexcept.h> +#include <tr1/array> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + + /// @brief Base class. + template<typename _Tp> + class array_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; + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + void + deallocate(pointer, size_type) + { + // Does nothing. + } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) value_type(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + + /** + * @brief An allocator that uses previously allocated memory. + * This memory can be externally, globally, or otherwise allocated. + */ + template<typename _Tp, typename _Array = std::tr1::array<_Tp, 1> > + class array_allocator : public array_allocator_base<_Tp> + { + 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; + typedef _Array array_type; + + private: + array_type* _M_array; + size_type _M_used; + + public: + template<typename _Tp1, typename _Array1 = _Array> + struct rebind + { typedef array_allocator<_Tp1, _Array1> other; }; + + array_allocator(array_type* __array = NULL) throw() + : _M_array(__array), _M_used(size_type()) { } + + array_allocator(const array_allocator& __o) throw() + : _M_array(__o._M_array), _M_used(__o._M_used) { } + + template<typename _Tp1, typename _Array1> + array_allocator(const array_allocator<_Tp1, _Array1>&) throw() + : _M_array(NULL), _M_used(size_type()) { } + + ~array_allocator() throw() { } + + pointer + allocate(size_type __n, const void* = 0) + { + if (_M_array == 0 || _M_used + __n > _M_array->size()) + std::__throw_bad_alloc(); + pointer __ret = _M_array->begin() + _M_used; + _M_used += __n; + return __ret; + } + }; + + template<typename _Tp, typename _Array> + inline bool + operator==(const array_allocator<_Tp, _Array>&, + const array_allocator<_Tp, _Array>&) + { return true; } + + template<typename _Tp, typename _Array> + inline bool + operator!=(const array_allocator<_Tp, _Array>&, + const array_allocator<_Tp, _Array>&) + { return false; } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/atomicity.h b/libstdc++/include/ext/atomicity.h new file mode 100644 index 0000000..975121e --- /dev/null +++ b/libstdc++/include/ext/atomicity.h @@ -0,0 +1,118 @@ +// Support for atomic operations -*- C++ -*- + +// 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. + +/** @file atomicity.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +#include <bits/c++config.h> +#include <bits/gthr.h> +#include <bits/atomic_word.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // Functions for portable atomic access. + // To abstract locking primatives across all thread policies, use: + // __exchange_and_add_dispatch + // __atomic_add_dispatch +#ifdef _GLIBCXX_ATOMIC_BUILTINS + static inline _Atomic_word + __exchange_and_add(volatile _Atomic_word* __mem, int __val) + { return __sync_fetch_and_add(__mem, __val); } + + static inline void + __atomic_add(volatile _Atomic_word* __mem, int __val) + { __sync_fetch_and_add(__mem, __val); } +#else + _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_add(volatile _Atomic_word*, int); + + void + __attribute__ ((__unused__)) + __atomic_add(volatile _Atomic_word*, int); +#endif + + static inline _Atomic_word + __exchange_and_add_single(_Atomic_word* __mem, int __val) + { + _Atomic_word __result = *__mem; + *__mem += __val; + return __result; + } + + static inline void + __atomic_add_single(_Atomic_word* __mem, int __val) + { *__mem += __val; } + + static inline _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_add_dispatch(_Atomic_word* __mem, int __val) + { +#ifdef __GTHREADS + if (__gthread_active_p()) + return __exchange_and_add(__mem, __val); + else + return __exchange_and_add_single(__mem, __val); +#else + return __exchange_and_add_single(__mem, __val); +#endif + } + + static inline void + __attribute__ ((__unused__)) + __atomic_add_dispatch(_Atomic_word* __mem, int __val) + { +#ifdef __GTHREADS + if (__gthread_active_p()) + __atomic_add(__mem, __val); + else + __atomic_add_single(__mem, __val); +#else + __atomic_add_single(__mem, __val); +#endif + } + +_GLIBCXX_END_NAMESPACE + +// Even if the CPU doesn't need a memory barrier, we need to ensure +// that the compiler doesn't reorder memory accesses across the +// barriers. +#ifndef _GLIBCXX_READ_MEM_BARRIER +#define _GLIBCXX_READ_MEM_BARRIER __asm __volatile ("":::"memory") +#endif +#ifndef _GLIBCXX_WRITE_MEM_BARRIER +#define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("":::"memory") +#endif + +#endif diff --git a/libstdc++/include/ext/bitmap_allocator.h b/libstdc++/include/ext/bitmap_allocator.h new file mode 100644 index 0000000..93fa8e6 --- /dev/null +++ b/libstdc++/include/ext/bitmap_allocator.h @@ -0,0 +1,1138 @@ +// Bitmap Allocator. -*- C++ -*- + +// 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. + +/** @file ext/bitmap_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _BITMAP_ALLOCATOR_H +#define _BITMAP_ALLOCATOR_H 1 + +#include <cstddef> // For std::size_t, and ptrdiff_t. +#include <bits/functexcept.h> // For __throw_bad_alloc(). +#include <utility> // For std::pair. +#include <functional> // For greater_equal, and less_equal. +#include <new> // For operator new. +#include <debug/debug.h> // _GLIBCXX_DEBUG_ASSERT +#include <ext/concurrence.h> + + +/** @brief The constant in the expression below is the alignment + * required in bytes. + */ +#define _BALLOC_ALIGN_BYTES 8 + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + + namespace __detail + { + /** @class __mini_vector bitmap_allocator.h bitmap_allocator.h + * + * @brief __mini_vector<> is a stripped down version of the + * full-fledged std::vector<>. + * + * It is to be used only for built-in types or PODs. Notable + * differences are: + * + * @detail + * 1. Not all accessor functions are present. + * 2. Used ONLY for PODs. + * 3. No Allocator template argument. Uses ::operator new() to get + * memory, and ::operator delete() to free it. + * Caveat: The dtor does NOT free the memory allocated, so this a + * memory-leaking vector! + */ + template<typename _Tp> + class __mini_vector + { + __mini_vector(const __mini_vector&); + __mini_vector& operator=(const __mini_vector&); + + public: + typedef _Tp value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef pointer iterator; + + private: + pointer _M_start; + pointer _M_finish; + pointer _M_end_of_storage; + + size_type + _M_space_left() const throw() + { return _M_end_of_storage - _M_finish; } + + pointer + allocate(size_type __n) + { return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); } + + void + deallocate(pointer __p, size_type) + { ::operator delete(__p); } + + public: + // Members used: size(), push_back(), pop_back(), + // insert(iterator, const_reference), erase(iterator), + // begin(), end(), back(), operator[]. + + __mini_vector() : _M_start(0), _M_finish(0), + _M_end_of_storage(0) + { } + +#if 0 + ~__mini_vector() + { + if (this->_M_start) + { + this->deallocate(this->_M_start, this->_M_end_of_storage + - this->_M_start); + } + } +#endif + + size_type + size() const throw() + { return _M_finish - _M_start; } + + iterator + begin() const throw() + { return this->_M_start; } + + iterator + end() const throw() + { return this->_M_finish; } + + reference + back() const throw() + { return *(this->end() - 1); } + + reference + operator[](const size_type __pos) const throw() + { return this->_M_start[__pos]; } + + void + insert(iterator __pos, const_reference __x); + + void + push_back(const_reference __x) + { + if (this->_M_space_left()) + { + *this->end() = __x; + ++this->_M_finish; + } + else + this->insert(this->end(), __x); + } + + void + pop_back() throw() + { --this->_M_finish; } + + void + erase(iterator __pos) throw(); + + void + clear() throw() + { this->_M_finish = this->_M_start; } + }; + + // Out of line function definitions. + template<typename _Tp> + void __mini_vector<_Tp>:: + insert(iterator __pos, const_reference __x) + { + if (this->_M_space_left()) + { + size_type __to_move = this->_M_finish - __pos; + iterator __dest = this->end(); + iterator __src = this->end() - 1; + + ++this->_M_finish; + while (__to_move) + { + *__dest = *__src; + --__dest; --__src; --__to_move; + } + *__pos = __x; + } + else + { + size_type __new_size = this->size() ? this->size() * 2 : 1; + iterator __new_start = this->allocate(__new_size); + iterator __first = this->begin(); + iterator __start = __new_start; + while (__first != __pos) + { + *__start = *__first; + ++__start; ++__first; + } + *__start = __x; + ++__start; + while (__first != this->end()) + { + *__start = *__first; + ++__start; ++__first; + } + if (this->_M_start) + this->deallocate(this->_M_start, this->size()); + + this->_M_start = __new_start; + this->_M_finish = __start; + this->_M_end_of_storage = this->_M_start + __new_size; + } + } + + template<typename _Tp> + void __mini_vector<_Tp>:: + erase(iterator __pos) throw() + { + while (__pos + 1 != this->end()) + { + *__pos = __pos[1]; + ++__pos; + } + --this->_M_finish; + } + + + template<typename _Tp> + struct __mv_iter_traits + { + typedef typename _Tp::value_type value_type; + typedef typename _Tp::difference_type difference_type; + }; + + template<typename _Tp> + struct __mv_iter_traits<_Tp*> + { + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + }; + + enum + { + bits_per_byte = 8, + bits_per_block = sizeof(size_t) * size_t(bits_per_byte) + }; + + template<typename _ForwardIterator, typename _Tp, typename _Compare> + _ForwardIterator + __lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename __mv_iter_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename __mv_iter_traits<_ForwardIterator>::difference_type + _DistanceType; + + _DistanceType __len = __last - __first; + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + __middle += __half; + if (__comp(*__middle, __val)) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; + } + + template<typename _InputIterator, typename _Predicate> + inline _InputIterator + __find_if(_InputIterator __first, _InputIterator __last, _Predicate __p) + { + while (__first != __last && !__p(*__first)) + ++__first; + return __first; + } + + /** @brief The number of Blocks pointed to by the address pair + * passed to the function. + */ + template<typename _AddrPair> + inline size_t + __num_blocks(_AddrPair __ap) + { return (__ap.second - __ap.first) + 1; } + + /** @brief The number of Bit-maps pointed to by the address pair + * passed to the function. + */ + template<typename _AddrPair> + inline size_t + __num_bitmaps(_AddrPair __ap) + { return __num_blocks(__ap) / size_t(bits_per_block); } + + // _Tp should be a pointer type. + template<typename _Tp> + class _Inclusive_between + : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> + { + typedef _Tp pointer; + pointer _M_ptr_value; + typedef typename std::pair<_Tp, _Tp> _Block_pair; + + public: + _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr) + { } + + bool + operator()(_Block_pair __bp) const throw() + { + if (std::less_equal<pointer>()(_M_ptr_value, __bp.second) + && std::greater_equal<pointer>()(_M_ptr_value, __bp.first)) + return true; + else + return false; + } + }; + + // Used to pass a Functor to functions by reference. + template<typename _Functor> + class _Functor_Ref + : public std::unary_function<typename _Functor::argument_type, + typename _Functor::result_type> + { + _Functor& _M_fref; + + public: + typedef typename _Functor::argument_type argument_type; + typedef typename _Functor::result_type result_type; + + _Functor_Ref(_Functor& __fref) : _M_fref(__fref) + { } + + result_type + operator()(argument_type __arg) + { return _M_fref(__arg); } + }; + + /** @class _Ffit_finder bitmap_allocator.h bitmap_allocator.h + * + * @brief The class which acts as a predicate for applying the + * first-fit memory allocation policy for the bitmap allocator. + */ + // _Tp should be a pointer type, and _Alloc is the Allocator for + // the vector. + template<typename _Tp> + class _Ffit_finder + : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> + { + typedef typename std::pair<_Tp, _Tp> _Block_pair; + typedef typename __detail::__mini_vector<_Block_pair> _BPVector; + typedef typename _BPVector::difference_type _Counter_type; + + size_t* _M_pbitmap; + _Counter_type _M_data_offset; + + public: + _Ffit_finder() : _M_pbitmap(0), _M_data_offset(0) + { } + + bool + operator()(_Block_pair __bp) throw() + { + // Set the _rover to the last physical location bitmap, + // which is the bitmap which belongs to the first free + // block. Thus, the bitmaps are in exact reverse order of + // the actual memory layout. So, we count down the bimaps, + // which is the same as moving up the memory. + + // If the used count stored at the start of the Bit Map headers + // is equal to the number of Objects that the current Block can + // store, then there is definitely no space for another single + // object, so just return false. + _Counter_type __diff = + __gnu_cxx::__detail::__num_bitmaps(__bp); + + if (*(reinterpret_cast<size_t*> + (__bp.first) - (__diff + 1)) + == __gnu_cxx::__detail::__num_blocks(__bp)) + return false; + + size_t* __rover = reinterpret_cast<size_t*>(__bp.first) - 1; + + for (_Counter_type __i = 0; __i < __diff; ++__i) + { + _M_data_offset = __i; + if (*__rover) + { + _M_pbitmap = __rover; + return true; + } + --__rover; + } + return false; + } + + + size_t* + _M_get() const throw() + { return _M_pbitmap; } + + _Counter_type + _M_offset() const throw() + { return _M_data_offset * size_t(bits_per_block); } + }; + + + /** @class _Bitmap_counter bitmap_allocator.h bitmap_allocator.h + * + * @brief The bitmap counter which acts as the bitmap + * manipulator, and manages the bit-manipulation functions and + * the searching and identification functions on the bit-map. + */ + // _Tp should be a pointer type. + template<typename _Tp> + class _Bitmap_counter + { + typedef typename __detail::__mini_vector<typename std::pair<_Tp, _Tp> > + _BPVector; + typedef typename _BPVector::size_type _Index_type; + typedef _Tp pointer; + + _BPVector& _M_vbp; + size_t* _M_curr_bmap; + size_t* _M_last_bmap_in_block; + _Index_type _M_curr_index; + + public: + // Use the 2nd parameter with care. Make sure that such an + // entry exists in the vector before passing that particular + // index to this ctor. + _Bitmap_counter(_BPVector& Rvbp, long __index = -1) : _M_vbp(Rvbp) + { this->_M_reset(__index); } + + void + _M_reset(long __index = -1) throw() + { + if (__index == -1) + { + _M_curr_bmap = 0; + _M_curr_index = static_cast<_Index_type>(-1); + return; + } + + _M_curr_index = __index; + _M_curr_bmap = reinterpret_cast<size_t*> + (_M_vbp[_M_curr_index].first) - 1; + + _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1); + + _M_last_bmap_in_block = _M_curr_bmap + - ((_M_vbp[_M_curr_index].second + - _M_vbp[_M_curr_index].first + 1) + / size_t(bits_per_block) - 1); + } + + // Dangerous Function! Use with extreme care. Pass to this + // function ONLY those values that are known to be correct, + // otherwise this will mess up big time. + void + _M_set_internal_bitmap(size_t* __new_internal_marker) throw() + { _M_curr_bmap = __new_internal_marker; } + + bool + _M_finished() const throw() + { return(_M_curr_bmap == 0); } + + _Bitmap_counter& + operator++() throw() + { + if (_M_curr_bmap == _M_last_bmap_in_block) + { + if (++_M_curr_index == _M_vbp.size()) + _M_curr_bmap = 0; + else + this->_M_reset(_M_curr_index); + } + else + --_M_curr_bmap; + return *this; + } + + size_t* + _M_get() const throw() + { return _M_curr_bmap; } + + pointer + _M_base() const throw() + { return _M_vbp[_M_curr_index].first; } + + _Index_type + _M_offset() const throw() + { + return size_t(bits_per_block) + * ((reinterpret_cast<size_t*>(this->_M_base()) + - _M_curr_bmap) - 1); + } + + _Index_type + _M_where() const throw() + { return _M_curr_index; } + }; + + /** @brief Mark a memory address as allocated by re-setting the + * corresponding bit in the bit-map. + */ + inline void + __bit_allocate(size_t* __pbmap, size_t __pos) throw() + { + size_t __mask = 1 << __pos; + __mask = ~__mask; + *__pbmap &= __mask; + } + + /** @brief Mark a memory address as free by setting the + * corresponding bit in the bit-map. + */ + inline void + __bit_free(size_t* __pbmap, size_t __pos) throw() + { + size_t __mask = 1 << __pos; + *__pbmap |= __mask; + } + } // namespace __detail + + /** @brief Generic Version of the bsf instruction. + */ + inline size_t + _Bit_scan_forward(size_t __num) + { return static_cast<size_t>(__builtin_ctzl(__num)); } + + /** @class free_list bitmap_allocator.h bitmap_allocator.h + * + * @brief The free list class for managing chunks of memory to be + * given to and returned by the bitmap_allocator. + */ + class free_list + { + typedef size_t* value_type; + typedef __detail::__mini_vector<value_type> vector_type; + typedef vector_type::iterator iterator; + typedef __mutex __mutex_type; + + struct _LT_pointer_compare + { + bool + operator()(const size_t* __pui, + const size_t __cui) const throw() + { return *__pui < __cui; } + }; + +#if defined __GTHREADS + __mutex_type& + _M_get_mutex() + { + static __mutex_type _S_mutex; + return _S_mutex; + } +#endif + + vector_type& + _M_get_free_list() + { + static vector_type _S_free_list; + return _S_free_list; + } + + /** @brief Performs validation of memory based on their size. + * + * @param __addr The pointer to the memory block to be + * validated. + * + * @detail Validates the memory block passed to this function and + * appropriately performs the action of managing the free list of + * blocks by adding this block to the free list or deleting this + * or larger blocks from the free list. + */ + void + _M_validate(size_t* __addr) throw() + { + vector_type& __free_list = _M_get_free_list(); + const vector_type::size_type __max_size = 64; + if (__free_list.size() >= __max_size) + { + // Ok, the threshold value has been reached. We determine + // which block to remove from the list of free blocks. + if (*__addr >= *__free_list.back()) + { + // Ok, the new block is greater than or equal to the + // last block in the list of free blocks. We just free + // the new block. + ::operator delete(static_cast<void*>(__addr)); + return; + } + else + { + // Deallocate the last block in the list of free lists, + // and insert the new one in it's correct position. + ::operator delete(static_cast<void*>(__free_list.back())); + __free_list.pop_back(); + } + } + + // Just add the block to the list of free lists unconditionally. + iterator __temp = __gnu_cxx::__detail::__lower_bound + (__free_list.begin(), __free_list.end(), + *__addr, _LT_pointer_compare()); + + // We may insert the new free list before _temp; + __free_list.insert(__temp, __addr); + } + + /** @brief Decides whether the wastage of memory is acceptable for + * the current memory request and returns accordingly. + * + * @param __block_size The size of the block available in the free + * list. + * + * @param __required_size The required size of the memory block. + * + * @return true if the wastage incurred is acceptable, else returns + * false. + */ + bool + _M_should_i_give(size_t __block_size, + size_t __required_size) throw() + { + const size_t __max_wastage_percentage = 36; + if (__block_size >= __required_size && + (((__block_size - __required_size) * 100 / __block_size) + < __max_wastage_percentage)) + return true; + else + return false; + } + + public: + /** @brief This function returns the block of memory to the + * internal free list. + * + * @param __addr The pointer to the memory block that was given + * by a call to the _M_get function. + */ + inline void + _M_insert(size_t* __addr) throw() + { +#if defined __GTHREADS + __gnu_cxx::__scoped_lock __bfl_lock(_M_get_mutex()); +#endif + // Call _M_validate to decide what should be done with + // this particular free list. + this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1); + // See discussion as to why this is 1! + } + + /** @brief This function gets a block of memory of the specified + * size from the free list. + * + * @param __sz The size in bytes of the memory required. + * + * @return A pointer to the new memory block of size at least + * equal to that requested. + */ + size_t* + _M_get(size_t __sz) throw(std::bad_alloc); + + /** @brief This function just clears the internal Free List, and + * gives back all the memory to the OS. + */ + void + _M_clear(); + }; + + + // Forward declare the class. + template<typename _Tp> + class bitmap_allocator; + + // Specialize for void: + template<> + class bitmap_allocator<void> + { + public: + typedef void* pointer; + typedef const void* const_pointer; + + // Reference-to-void members are impossible. + typedef void value_type; + template<typename _Tp1> + struct rebind + { + typedef bitmap_allocator<_Tp1> other; + }; + }; + + template<typename _Tp> + class bitmap_allocator : private free_list + { + 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; + typedef free_list::__mutex_type __mutex_type; + + template<typename _Tp1> + struct rebind + { + typedef bitmap_allocator<_Tp1> other; + }; + + private: + template<size_t _BSize, size_t _AlignSize> + struct aligned_size + { + enum + { + modulus = _BSize % _AlignSize, + value = _BSize + (modulus ? _AlignSize - (modulus) : 0) + }; + }; + + struct _Alloc_block + { + char __M_unused[aligned_size<sizeof(value_type), + _BALLOC_ALIGN_BYTES>::value]; + }; + + + typedef typename std::pair<_Alloc_block*, _Alloc_block*> _Block_pair; + + typedef typename + __detail::__mini_vector<_Block_pair> _BPVector; + +#if defined _GLIBCXX_DEBUG + // Complexity: O(lg(N)). Where, N is the number of block of size + // sizeof(value_type). + void + _S_check_for_free_blocks() throw() + { + typedef typename + __gnu_cxx::__detail::_Ffit_finder<_Alloc_block*> _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = + __gnu_cxx::__detail::__find_if + (_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__detail::_Functor_Ref<_FFF>(__fff)); + + _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end()); + } +#endif + + /** @brief Responsible for exponentially growing the internal + * memory pool. + * + * @throw std::bad_alloc. If memory can not be allocated. + * + * @detail Complexity: O(1), but internally depends upon the + * complexity of the function free_list::_M_get. The part where + * the bitmap headers are written has complexity: O(X),where X + * is the number of blocks of size sizeof(value_type) within + * the newly acquired block. Having a tight bound. + */ + void + _S_refill_pool() throw(std::bad_alloc) + { +#if defined _GLIBCXX_DEBUG + _S_check_for_free_blocks(); +#endif + + const size_t __num_bitmaps = (_S_block_size + / size_t(__detail::bits_per_block)); + const size_t __size_to_allocate = sizeof(size_t) + + _S_block_size * sizeof(_Alloc_block) + + __num_bitmaps * sizeof(size_t); + + size_t* __temp = + reinterpret_cast<size_t*> + (this->_M_get(__size_to_allocate)); + *__temp = 0; + ++__temp; + + // The Header information goes at the Beginning of the Block. + _Block_pair __bp = + std::make_pair(reinterpret_cast<_Alloc_block*> + (__temp + __num_bitmaps), + reinterpret_cast<_Alloc_block*> + (__temp + __num_bitmaps) + + _S_block_size - 1); + + // Fill the Vector with this information. + _S_mem_blocks.push_back(__bp); + + size_t __bit_mask = 0; // 0 Indicates all Allocated. + __bit_mask = ~__bit_mask; // 1 Indicates all Free. + + for (size_t __i = 0; __i < __num_bitmaps; ++__i) + __temp[__i] = __bit_mask; + + _S_block_size *= 2; + } + + + static _BPVector _S_mem_blocks; + static size_t _S_block_size; + static __gnu_cxx::__detail:: + _Bitmap_counter<_Alloc_block*> _S_last_request; + static typename _BPVector::size_type _S_last_dealloc_index; +#if defined __GTHREADS + static __mutex_type _S_mut; +#endif + + public: + + /** @brief Allocates memory for a single object of size + * sizeof(_Tp). + * + * @throw std::bad_alloc. If memory can not be allocated. + * + * @detail Complexity: Worst case complexity is O(N), but that + * is hardly ever hit. If and when this particular case is + * encountered, the next few cases are guaranteed to have a + * worst case complexity of O(1)! That's why this function + * performs very well on average. You can consider this + * function to have a complexity referred to commonly as: + * Amortized Constant time. + */ + pointer + _M_allocate_single_object() throw(std::bad_alloc) + { +#if defined __GTHREADS + __gnu_cxx::__scoped_lock __bit_lock(_S_mut); +#endif + + // The algorithm is something like this: The last_request + // variable points to the last accessed Bit Map. When such a + // condition occurs, we try to find a free block in the + // current bitmap, or succeeding bitmaps until the last bitmap + // is reached. If no free block turns up, we resort to First + // Fit method. + + // WARNING: Do not re-order the condition in the while + // statement below, because it relies on C++'s short-circuit + // evaluation. The return from _S_last_request->_M_get() will + // NOT be dereference able if _S_last_request->_M_finished() + // returns true. This would inevitably lead to a NULL pointer + // dereference if tinkered with. + while (_S_last_request._M_finished() == false + && (*(_S_last_request._M_get()) == 0)) + { + _S_last_request.operator++(); + } + + if (__builtin_expect(_S_last_request._M_finished() == true, false)) + { + // Fall Back to First Fit algorithm. + typedef typename + __gnu_cxx::__detail::_Ffit_finder<_Alloc_block*> _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = + __gnu_cxx::__detail::__find_if + (_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__detail::_Functor_Ref<_FFF>(__fff)); + + if (__bpi != _S_mem_blocks.end()) + { + // Search was successful. Ok, now mark the first bit from + // the right as 0, meaning Allocated. This bit is obtained + // by calling _M_get() on __fff. + size_t __nz_bit = _Bit_scan_forward(*__fff._M_get()); + __detail::__bit_allocate(__fff._M_get(), __nz_bit); + + _S_last_request._M_reset(__bpi - _S_mem_blocks.begin()); + + // Now, get the address of the bit we marked as allocated. + pointer __ret = reinterpret_cast<pointer> + (__bpi->first + __fff._M_offset() + __nz_bit); + size_t* __puse_count = + reinterpret_cast<size_t*> + (__bpi->first) + - (__gnu_cxx::__detail::__num_bitmaps(*__bpi) + 1); + + ++(*__puse_count); + return __ret; + } + else + { + // Search was unsuccessful. We Add more memory to the + // pool by calling _S_refill_pool(). + _S_refill_pool(); + + // _M_Reset the _S_last_request structure to the first + // free block's bit map. + _S_last_request._M_reset(_S_mem_blocks.size() - 1); + + // Now, mark that bit as allocated. + } + } + + // _S_last_request holds a pointer to a valid bit map, that + // points to a free block in memory. + size_t __nz_bit = _Bit_scan_forward(*_S_last_request._M_get()); + __detail::__bit_allocate(_S_last_request._M_get(), __nz_bit); + + pointer __ret = reinterpret_cast<pointer> + (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit); + + size_t* __puse_count = reinterpret_cast<size_t*> + (_S_mem_blocks[_S_last_request._M_where()].first) + - (__gnu_cxx::__detail:: + __num_bitmaps(_S_mem_blocks[_S_last_request._M_where()]) + 1); + + ++(*__puse_count); + return __ret; + } + + /** @brief Deallocates memory that belongs to a single object of + * size sizeof(_Tp). + * + * @detail Complexity: O(lg(N)), but the worst case is not hit + * often! This is because containers usually deallocate memory + * close to each other and this case is handled in O(1) time by + * the deallocate function. + */ + void + _M_deallocate_single_object(pointer __p) throw() + { +#if defined __GTHREADS + __gnu_cxx::__scoped_lock __bit_lock(_S_mut); +#endif + _Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p); + + typedef typename _BPVector::iterator _Iterator; + typedef typename _BPVector::difference_type _Difference_type; + + _Difference_type __diff; + long __displacement; + + _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0); + + + if (__gnu_cxx::__detail::_Inclusive_between<_Alloc_block*> + (__real_p) (_S_mem_blocks[_S_last_dealloc_index])) + { + _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index + <= _S_mem_blocks.size() - 1); + + // Initial Assumption was correct! + __diff = _S_last_dealloc_index; + __displacement = __real_p - _S_mem_blocks[__diff].first; + } + else + { + _Iterator _iter = __gnu_cxx::__detail:: + __find_if(_S_mem_blocks.begin(), + _S_mem_blocks.end(), + __gnu_cxx::__detail:: + _Inclusive_between<_Alloc_block*>(__real_p)); + + _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end()); + + __diff = _iter - _S_mem_blocks.begin(); + __displacement = __real_p - _S_mem_blocks[__diff].first; + _S_last_dealloc_index = __diff; + } + + // Get the position of the iterator that has been found. + const size_t __rotate = (__displacement + % size_t(__detail::bits_per_block)); + size_t* __bitmapC = + reinterpret_cast<size_t*> + (_S_mem_blocks[__diff].first) - 1; + __bitmapC -= (__displacement / size_t(__detail::bits_per_block)); + + __detail::__bit_free(__bitmapC, __rotate); + size_t* __puse_count = reinterpret_cast<size_t*> + (_S_mem_blocks[__diff].first) + - (__gnu_cxx::__detail::__num_bitmaps(_S_mem_blocks[__diff]) + 1); + + _GLIBCXX_DEBUG_ASSERT(*__puse_count != 0); + + --(*__puse_count); + + if (__builtin_expect(*__puse_count == 0, false)) + { + _S_block_size /= 2; + + // We can safely remove this block. + // _Block_pair __bp = _S_mem_blocks[__diff]; + this->_M_insert(__puse_count); + _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff); + + // Reset the _S_last_request variable to reflect the + // erased block. We do this to protect future requests + // after the last block has been removed from a particular + // memory Chunk, which in turn has been returned to the + // free list, and hence had been erased from the vector, + // so the size of the vector gets reduced by 1. + if ((_Difference_type)_S_last_request._M_where() >= __diff--) + _S_last_request._M_reset(__diff); + + // If the Index into the vector of the region of memory + // that might hold the next address that will be passed to + // deallocated may have been invalidated due to the above + // erase procedure being called on the vector, hence we + // try to restore this invariant too. + if (_S_last_dealloc_index >= _S_mem_blocks.size()) + { + _S_last_dealloc_index =(__diff != -1 ? __diff : 0); + _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0); + } + } + } + + public: + bitmap_allocator() throw() + { } + + bitmap_allocator(const bitmap_allocator&) + { } + + template<typename _Tp1> + bitmap_allocator(const bitmap_allocator<_Tp1>&) throw() + { } + + ~bitmap_allocator() throw() + { } + + pointer + allocate(size_type __n) + { + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); + + if (__builtin_expect(__n == 1, true)) + return this->_M_allocate_single_object(); + else + { + const size_type __b = __n * sizeof(value_type); + return reinterpret_cast<pointer>(::operator new(__b)); + } + } + + pointer + allocate(size_type __n, typename bitmap_allocator<void>::const_pointer) + { return allocate(__n); } + + void + deallocate(pointer __p, size_type __n) throw() + { + if (__builtin_expect(__p != 0, true)) + { + if (__builtin_expect(__n == 1, true)) + this->_M_deallocate_single_object(__p); + else + ::operator delete(__p); + } + } + + pointer + address(reference __r) const + { return &__r; } + + const_pointer + address(const_reference __r) const + { return &__r; } + + size_type + max_size() const throw() + { return size_type(-1) / sizeof(value_type); } + + void + construct(pointer __p, const_reference __data) + { ::new(__p) value_type(__data); } + + void + destroy(pointer __p) + { __p->~value_type(); } + }; + + template<typename _Tp1, typename _Tp2> + bool + operator==(const bitmap_allocator<_Tp1>&, + const bitmap_allocator<_Tp2>&) throw() + { return true; } + + template<typename _Tp1, typename _Tp2> + bool + operator!=(const bitmap_allocator<_Tp1>&, + const bitmap_allocator<_Tp2>&) throw() + { return false; } + + // Static member definitions. + template<typename _Tp> + typename bitmap_allocator<_Tp>::_BPVector + bitmap_allocator<_Tp>::_S_mem_blocks; + + template<typename _Tp> + size_t bitmap_allocator<_Tp>::_S_block_size = + 2 * size_t(__detail::bits_per_block); + + template<typename _Tp> + typename __gnu_cxx::bitmap_allocator<_Tp>::_BPVector::size_type + bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; + + template<typename _Tp> + __gnu_cxx::__detail::_Bitmap_counter + <typename bitmap_allocator<_Tp>::_Alloc_block*> + bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks); + +#if defined __GTHREADS + template<typename _Tp> + typename bitmap_allocator<_Tp>::__mutex_type + bitmap_allocator<_Tp>::_S_mut; +#endif + +_GLIBCXX_END_NAMESPACE + +#endif + diff --git a/libstdc++/include/ext/codecvt_specializations.h b/libstdc++/include/ext/codecvt_specializations.h new file mode 100644 index 0000000..f0a6bbe --- /dev/null +++ b/libstdc++/include/ext/codecvt_specializations.h @@ -0,0 +1,521 @@ +// Locale support (codecvt) -*- C++ -*- + +// 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. + +// +// ISO C++ 14882: 22.2.1.5 Template class codecvt +// + +// Written by Benjamin Kosnik <bkoz@redhat.com> + +/** @file ext/codecvt_specializations.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _EXT_CODECVT_SPECIALIZATIONS_H +#define _EXT_CODECVT_SPECIALIZATIONS_H 1 + +#include <bits/c++config.h> + +#ifdef _GLIBCXX_USE_ICONV + +#include <locale> +#include <iconv.h> + + // XXX + // Define this here so codecvt.cc can have _S_max_size definition. +#define _GLIBCXX_USE_ENCODING_STATE 1 + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /// @brief Extension to use icov for dealing with character encodings. + // This includes conversions and comparisons between various character + // sets. This object encapsulates data that may need to be shared between + // char_traits, codecvt and ctype. + class encoding_state + { + public: + // Types: + // NB: A conversion descriptor subsumes and enhances the + // functionality of a simple state type such as mbstate_t. + typedef iconv_t descriptor_type; + + protected: + // Name of internal character set encoding. + std::string _M_int_enc; + + // Name of external character set encoding. + std::string _M_ext_enc; + + // Conversion descriptor between external encoding to internal encoding. + descriptor_type _M_in_desc; + + // Conversion descriptor between internal encoding to external encoding. + descriptor_type _M_out_desc; + + // The byte-order marker for the external encoding, if necessary. + int _M_ext_bom; + + // The byte-order marker for the internal encoding, if necessary. + int _M_int_bom; + + // Number of external bytes needed to construct one complete + // character in the internal encoding. + // NB: -1 indicates variable, or stateful, encodings. + int _M_bytes; + + public: + explicit + encoding_state() + : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0), _M_bytes(0) + { } + + explicit + encoding_state(const char* __int, const char* __ext, + int __ibom = 0, int __ebom = 0, int __bytes = 1) + : _M_int_enc(__int), _M_ext_enc(__ext), _M_in_desc(0), _M_out_desc(0), + _M_ext_bom(__ebom), _M_int_bom(__ibom), _M_bytes(__bytes) + { init(); } + + // 21.1.2 traits typedefs + // p4 + // typedef STATE_T state_type + // requires: state_type shall meet the requirements of + // CopyConstructible types (20.1.3) + // NB: This does not preseve the actual state of the conversion + // descriptor member, but it does duplicate the encoding + // information. + encoding_state(const encoding_state& __obj) : _M_in_desc(0), _M_out_desc(0) + { construct(__obj); } + + // Need assignment operator as well. + encoding_state& + operator=(const encoding_state& __obj) + { + construct(__obj); + return *this; + } + + ~encoding_state() + { destroy(); } + + bool + good() const throw() + { + const descriptor_type __err = reinterpret_cast<iconv_t>(-1); + bool __test = _M_in_desc && _M_in_desc != __err; + __test &= _M_out_desc && _M_out_desc != __err; + return __test; + } + + int + character_ratio() const + { return _M_bytes; } + + const std::string + internal_encoding() const + { return _M_int_enc; } + + int + internal_bom() const + { return _M_int_bom; } + + const std::string + external_encoding() const + { return _M_ext_enc; } + + int + external_bom() const + { return _M_ext_bom; } + + const descriptor_type& + in_descriptor() const + { return _M_in_desc; } + + const descriptor_type& + out_descriptor() const + { return _M_out_desc; } + + protected: + void + init() + { + const descriptor_type __err = reinterpret_cast<iconv_t>(-1); + const bool __have_encodings = _M_int_enc.size() && _M_ext_enc.size(); + if (!_M_in_desc && __have_encodings) + { + _M_in_desc = iconv_open(_M_int_enc.c_str(), _M_ext_enc.c_str()); + if (_M_in_desc == __err) + std::__throw_runtime_error(__N("encoding_state::_M_init " + "creating iconv input descriptor failed")); + } + if (!_M_out_desc && __have_encodings) + { + _M_out_desc = iconv_open(_M_ext_enc.c_str(), _M_int_enc.c_str()); + if (_M_out_desc == __err) + std::__throw_runtime_error(__N("encoding_state::_M_init " + "creating iconv output descriptor failed")); + } + } + + void + construct(const encoding_state& __obj) + { + destroy(); + _M_int_enc = __obj._M_int_enc; + _M_ext_enc = __obj._M_ext_enc; + _M_ext_bom = __obj._M_ext_bom; + _M_int_bom = __obj._M_int_bom; + _M_bytes = __obj._M_bytes; + init(); + } + + void + destroy() throw() + { + const descriptor_type __err = reinterpret_cast<iconv_t>(-1); + if (_M_in_desc && _M_in_desc != __err) + { + iconv_close(_M_in_desc); + _M_in_desc = 0; + } + if (_M_out_desc && _M_out_desc != __err) + { + iconv_close(_M_out_desc); + _M_out_desc = 0; + } + } + }; + + /// @brief encoding_char_traits. + // Custom traits type with encoding_state for the state type, and the + // associated fpos<encoding_state> for the position type, all other + // bits equivalent to the required char_traits instantiations. + template<typename _CharT> + struct encoding_char_traits : public std::char_traits<_CharT> + { + typedef encoding_state state_type; + typedef typename std::fpos<state_type> pos_type; + }; + +_GLIBCXX_END_NAMESPACE + + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using __gnu_cxx::encoding_state; + + /// @brief codecvt<InternT, _ExternT, encoding_state> specialization. + // This partial specialization takes advantage of iconv to provide + // code conversions between a large number of character encodings. + template<typename _InternT, typename _ExternT> + class codecvt<_InternT, _ExternT, encoding_state> + : public __codecvt_abstract_base<_InternT, _ExternT, encoding_state> + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef __gnu_cxx::encoding_state state_type; + typedef state_type::descriptor_type descriptor_type; + + // Data Members: + static locale::id id; + + explicit + codecvt(size_t __refs = 0) + : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs) + { } + + explicit + codecvt(state_type& __enc, size_t __refs = 0) + : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs) + { } + + protected: + virtual + ~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_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + 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_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + + template<typename _InternT, typename _ExternT> + locale::id + codecvt<_InternT, _ExternT, encoding_state>::id; + + // This adaptor works around the signature problems of the second + // argument to iconv(): SUSv2 and others use 'const char**', but glibc 2.2 + // uses 'char**', which matches the POSIX 1003.1-2001 standard. + // Using this adaptor, g++ will do the work for us. + template<typename _Tp> + inline size_t + __iconv_adaptor(size_t(*__func)(iconv_t, _Tp, size_t*, char**, size_t*), + iconv_t __cd, char** __inbuf, size_t* __inbytes, + char** __outbuf, size_t* __outbytes) + { return __func(__cd, (_Tp)__inbuf, __inbytes, __outbuf, __outbytes); } + + template<typename _InternT, typename _ExternT> + codecvt_base::result + codecvt<_InternT, _ExternT, encoding_state>:: + 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_end, + extern_type*& __to_next) const + { + result __ret = codecvt_base::error; + if (__state.good()) + { + const descriptor_type& __desc = __state.out_descriptor(); + const size_t __fmultiple = sizeof(intern_type); + size_t __fbytes = __fmultiple * (__from_end - __from); + const size_t __tmultiple = sizeof(extern_type); + size_t __tbytes = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast<char*>(__to); + char* __cfrom; + size_t __conv; + + // Some encodings need a byte order marker as the first item + // in the byte stream, to designate endian-ness. The default + // value for the byte order marker is NULL, so if this is + // the case, it's not necessary and we can just go on our + // merry way. + int __int_bom = __state.internal_bom(); + if (__int_bom) + { + size_t __size = __from_end - __from; + intern_type* __cfixed = static_cast<intern_type*> + (__builtin_alloca(sizeof(intern_type) * (__size + 1))); + __cfixed[0] = static_cast<intern_type>(__int_bom); + char_traits<intern_type>::copy(__cfixed + 1, __from, __size); + __cfrom = reinterpret_cast<char*>(__cfixed); + __conv = __iconv_adaptor(iconv, __desc, &__cfrom, + &__fbytes, &__cto, &__tbytes); + } + else + { + intern_type* __cfixed = const_cast<intern_type*>(__from); + __cfrom = reinterpret_cast<char*>(__cfixed); + __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__fbytes, + &__cto, &__tbytes); + } + + if (__conv != size_t(-1)) + { + __from_next = reinterpret_cast<const intern_type*>(__cfrom); + __to_next = reinterpret_cast<extern_type*>(__cto); + __ret = codecvt_base::ok; + } + else + { + if (__fbytes < __fmultiple * (__from_end - __from)) + { + __from_next = reinterpret_cast<const intern_type*>(__cfrom); + __to_next = reinterpret_cast<extern_type*>(__cto); + __ret = codecvt_base::partial; + } + else + __ret = codecvt_base::error; + } + } + return __ret; + } + + template<typename _InternT, typename _ExternT> + codecvt_base::result + codecvt<_InternT, _ExternT, encoding_state>:: + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const + { + result __ret = codecvt_base::error; + if (__state.good()) + { + const descriptor_type& __desc = __state.in_descriptor(); + const size_t __tmultiple = sizeof(intern_type); + size_t __tlen = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast<char*>(__to); + size_t __conv = __iconv_adaptor(iconv,__desc, NULL, NULL, + &__cto, &__tlen); + + if (__conv != size_t(-1)) + { + __to_next = reinterpret_cast<extern_type*>(__cto); + if (__tlen == __tmultiple * (__to_end - __to)) + __ret = codecvt_base::noconv; + else if (__tlen == 0) + __ret = codecvt_base::ok; + else + __ret = codecvt_base::partial; + } + else + __ret = codecvt_base::error; + } + return __ret; + } + + template<typename _InternT, typename _ExternT> + codecvt_base::result + codecvt<_InternT, _ExternT, encoding_state>:: + 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_end, + intern_type*& __to_next) const + { + result __ret = codecvt_base::error; + if (__state.good()) + { + const descriptor_type& __desc = __state.in_descriptor(); + const size_t __fmultiple = sizeof(extern_type); + size_t __flen = __fmultiple * (__from_end - __from); + const size_t __tmultiple = sizeof(intern_type); + size_t __tlen = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast<char*>(__to); + char* __cfrom; + size_t __conv; + + // Some encodings need a byte order marker as the first item + // in the byte stream, to designate endian-ness. The default + // value for the byte order marker is NULL, so if this is + // the case, it's not necessary and we can just go on our + // merry way. + int __ext_bom = __state.external_bom(); + if (__ext_bom) + { + size_t __size = __from_end - __from; + extern_type* __cfixed = static_cast<extern_type*> + (__builtin_alloca(sizeof(extern_type) * (__size + 1))); + __cfixed[0] = static_cast<extern_type>(__ext_bom); + char_traits<extern_type>::copy(__cfixed + 1, __from, __size); + __cfrom = reinterpret_cast<char*>(__cfixed); + __conv = __iconv_adaptor(iconv, __desc, &__cfrom, + &__flen, &__cto, &__tlen); + } + else + { + extern_type* __cfixed = const_cast<extern_type*>(__from); + __cfrom = reinterpret_cast<char*>(__cfixed); + __conv = __iconv_adaptor(iconv, __desc, &__cfrom, + &__flen, &__cto, &__tlen); + } + + + if (__conv != size_t(-1)) + { + __from_next = reinterpret_cast<const extern_type*>(__cfrom); + __to_next = reinterpret_cast<intern_type*>(__cto); + __ret = codecvt_base::ok; + } + else + { + if (__flen < static_cast<size_t>(__from_end - __from)) + { + __from_next = reinterpret_cast<const extern_type*>(__cfrom); + __to_next = reinterpret_cast<intern_type*>(__cto); + __ret = codecvt_base::partial; + } + else + __ret = codecvt_base::error; + } + } + return __ret; + } + + template<typename _InternT, typename _ExternT> + int + codecvt<_InternT, _ExternT, encoding_state>:: + do_encoding() const throw() + { + int __ret = 0; + if (sizeof(_ExternT) <= sizeof(_InternT)) + __ret = sizeof(_InternT) / sizeof(_ExternT); + return __ret; + } + + template<typename _InternT, typename _ExternT> + bool + codecvt<_InternT, _ExternT, encoding_state>:: + do_always_noconv() const throw() + { return false; } + + template<typename _InternT, typename _ExternT> + int + codecvt<_InternT, _ExternT, encoding_state>:: + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const + { return std::min(__max, static_cast<size_t>(__end - __from)); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 74. Garbled text for codecvt::do_max_length + template<typename _InternT, typename _ExternT> + int + codecvt<_InternT, _ExternT, encoding_state>:: + do_max_length() const throw() + { return 1; } + +_GLIBCXX_END_NAMESPACE + +#endif + +#endif diff --git a/libstdc++/include/ext/concurrence.h b/libstdc++/include/ext/concurrence.h new file mode 100644 index 0000000..56e07de --- /dev/null +++ b/libstdc++/include/ext/concurrence.h @@ -0,0 +1,225 @@ +// Support for concurrent programing -*- C++ -*- + +// Copyright (C) 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. + +/** @file concurrence.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CONCURRENCE_H +#define _CONCURRENCE_H 1 + +#include <cstdlib> +#include <exception> +#include <bits/gthr.h> +#include <bits/functexcept.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // Available locking policies: + // _S_single single-threaded code that doesn't need to be locked. + // _S_mutex multi-threaded code that requires additional support + // from gthr.h or abstraction layers in concurrance.h. + // _S_atomic multi-threaded code using atomic operations. + enum _Lock_policy { _S_single, _S_mutex, _S_atomic }; + + // Compile time constant that indicates prefered locking policy in + // the current configuration. + static const _Lock_policy __default_lock_policy = +#ifdef __GTHREADS + // NB: This macro doesn't actually exist yet in the compiler, but is + // set somewhat haphazardly at configure time. +#ifdef _GLIBCXX_ATOMIC_BUILTINS + _S_atomic; +#else + _S_mutex; +#endif +#else + _S_single; +#endif + + // NB: As this is used in libsupc++, need to only depend on + // exception. No stdexception classes, no use of std::string. + class __concurrence_lock_error : public std::exception + { + public: + virtual char const* + what() const throw() + { return "__gnu_cxx::__concurrence_lock_error"; } + }; + + class __concurrence_unlock_error : public std::exception + { + public: + virtual char const* + what() const throw() + { return "__gnu_cxx::__concurrence_unlock_error"; } + }; + + // Substitute for concurrence_error object in the case of -fno-exceptions. + inline void + __throw_concurrence_lock_error() + { +#if __EXCEPTIONS + throw __concurrence_lock_error(); +#else + std::abort(); +#endif + } + + inline void + __throw_concurrence_unlock_error() + { +#if __EXCEPTIONS + throw __concurrence_unlock_error(); +#else + std::abort(); +#endif + } + + class __mutex + { + private: + __gthread_mutex_t _M_mutex; + + __mutex(const __mutex&); + __mutex& operator=(const __mutex&); + + public: + __mutex() + { +#if __GTHREADS + if (__gthread_active_p()) + { +#if defined __GTHREAD_MUTEX_INIT + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + _M_mutex = __tmp; +#else + __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); +#endif + } +#endif + } + + void lock() + { +#if __GTHREADS + if (__gthread_active_p()) + { + if (__gthread_mutex_lock(&_M_mutex) != 0) + __throw_concurrence_lock_error(); + } +#endif + } + + void unlock() + { +#if __GTHREADS + if (__gthread_active_p()) + { + if (__gthread_mutex_unlock(&_M_mutex) != 0) + __throw_concurrence_unlock_error(); + } +#endif + } + }; + + class __recursive_mutex + { + private: + __gthread_recursive_mutex_t _M_mutex; + + __recursive_mutex(const __recursive_mutex&); + __recursive_mutex& operator=(const __recursive_mutex&); + + public: + __recursive_mutex() + { +#if __GTHREADS + if (__gthread_active_p()) + { +#if defined __GTHREAD_RECURSIVE_MUTEX_INIT + __gthread_recursive_mutex_t __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT; + _M_mutex = __tmp; +#else + __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); +#endif + } +#endif + } + + void lock() + { +#if __GTHREADS + if (__gthread_active_p()) + { + if (__gthread_recursive_mutex_lock(&_M_mutex) != 0) + __throw_concurrence_lock_error(); + } +#endif + } + + void unlock() + { +#if __GTHREADS + if (__gthread_active_p()) + { + if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0) + __throw_concurrence_unlock_error(); + } +#endif + } + }; + + /// @brief Scoped lock idiom. + // Acquire the mutex here with a constructor call, then release with + // the destructor call in accordance with RAII style. + class __scoped_lock + { + public: + typedef __mutex __mutex_type; + + private: + __mutex_type& _M_device; + + __scoped_lock(const __scoped_lock&); + __scoped_lock& operator=(const __scoped_lock&); + + public: + explicit __scoped_lock(__mutex_type& __name) : _M_device(__name) + { _M_device.lock(); } + + ~__scoped_lock() throw() + { _M_device.unlock(); } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/debug_allocator.h b/libstdc++/include/ext/debug_allocator.h new file mode 100644 index 0000000..43a9a87 --- /dev/null +++ b/libstdc++/include/ext/debug_allocator.h @@ -0,0 +1,128 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/debug_allocator.h + * This file is a GNU extension to the Standard C++ Library. + * You should only include this header if you are using GCC 3 or later. + */ + +#ifndef _DEBUG_ALLOCATOR_H +#define _DEBUG_ALLOCATOR_H 1 + +#include <stdexcept> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + + /** + * @brief A meta-allocator with debugging bits, as per [20.4]. + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls operator new + * - all deallocation calls operator delete + */ + template<typename _Alloc> + class debug_allocator + { + public: + typedef typename _Alloc::size_type size_type; + typedef typename _Alloc::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Alloc::value_type value_type; + + private: + // _M_extra is the number of objects that correspond to the + // extra space where debug information is stored. + size_type _M_extra; + + _Alloc _M_allocator; + + public: + debug_allocator() + { + const size_t __obj_size = sizeof(value_type); + _M_extra = (sizeof(size_type) + __obj_size - 1) / __obj_size; + } + + pointer + allocate(size_type __n) + { + pointer __res = _M_allocator.allocate(__n + _M_extra); + size_type* __ps = reinterpret_cast<size_type*>(__res); + *__ps = __n; + return __res + _M_extra; + } + + pointer + allocate(size_type __n, const void* __hint) + { + pointer __res = _M_allocator.allocate(__n + _M_extra, __hint); + size_type* __ps = reinterpret_cast<size_type*>(__res); + *__ps = __n; + return __res + _M_extra; + } + + void + deallocate(pointer __p, size_type __n) + { + if (__p) + { + pointer __real_p = __p - _M_extra; + if (*reinterpret_cast<size_type*>(__real_p) != __n) + { + throw std::runtime_error("debug_allocator::deallocate" + " wrong size"); + } + _M_allocator.deallocate(__real_p, __n + _M_extra); + } + else + throw std::runtime_error("debug_allocator::deallocate null pointer"); + } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/functional b/libstdc++/include/ext/functional new file mode 100644 index 0000000..f159e11 --- /dev/null +++ b/libstdc++/include/ext/functional @@ -0,0 +1,428 @@ +// Functional extensions -*- C++ -*- + +// Copyright (C) 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/functional + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _EXT_FUNCTIONAL +#define _EXT_FUNCTIONAL 1 + +#pragma GCC system_header + +#include <functional> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::unary_function; + using std::binary_function; + using std::mem_fun1_t; + using std::const_mem_fun1_t; + using std::mem_fun1_ref_t; + using std::const_mem_fun1_ref_t; + + /** The @c identity_element functions are not part of the C++ + * standard; SGI provided them as an extension. Its argument is an + * operation, and its return value is the identity element for that + * operation. It is overloaded for addition and multiplication, + * and you can overload it for your own nefarious operations. + * + * @addtogroup SGIextensions + * @{ + */ + /// An \link SGIextensions SGI extension \endlink. + template <class _Tp> + inline _Tp + identity_element(std::plus<_Tp>) + { return _Tp(0); } + + /// An \link SGIextensions SGI extension \endlink. + template <class _Tp> + inline _Tp + identity_element(std::multiplies<_Tp>) + { return _Tp(1); } + /** @} */ + + /** As an extension to the binders, SGI provided composition functors and + * wrapper functions to aid in their creation. The @c unary_compose + * functor is constructed from two functions/functors, @c f and @c g. + * Calling @c operator() with a single argument @c x returns @c f(g(x)). + * The function @c compose1 takes the two functions and constructs a + * @c unary_compose variable for you. + * + * @c binary_compose is constructed from three functors, @c f, @c g1, + * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function + * @compose2 takes f, g1, and g2, and constructs the @c binary_compose + * instance for you. For example, if @c f returns an int, then + * \code + * int answer = (compose2(f,g1,g2))(x); + * \endcode + * is equivalent to + * \code + * int temp1 = g1(x); + * int temp2 = g2(x); + * int answer = f(temp1,temp2); + * \endcode + * But the first form is more compact, and can be passed around as a + * functor to other algorithms. + * + * @addtogroup SGIextensions + * @{ + */ + /// An \link SGIextensions SGI extension \endlink. + template <class _Operation1, class _Operation2> + class unary_compose + : public unary_function<typename _Operation2::argument_type, + typename _Operation1::result_type> + { + protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; + + public: + unary_compose(const _Operation1& __x, const _Operation2& __y) + : _M_fn1(__x), _M_fn2(__y) {} + + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const + { return _M_fn1(_M_fn2(__x)); } + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Operation1, class _Operation2> + inline unary_compose<_Operation1, _Operation2> + compose1(const _Operation1& __fn1, const _Operation2& __fn2) + { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); } + + /// An \link SGIextensions SGI extension \endlink. + template <class _Operation1, class _Operation2, class _Operation3> + class binary_compose + : public unary_function<typename _Operation2::argument_type, + typename _Operation1::result_type> + { + protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; + _Operation3 _M_fn3; + + public: + binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) + : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } + + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const + { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); } + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Operation1, class _Operation2, class _Operation3> + inline binary_compose<_Operation1, _Operation2, _Operation3> + compose2(const _Operation1& __fn1, const _Operation2& __fn2, + const _Operation3& __fn3) + { return binary_compose<_Operation1, _Operation2, _Operation3> + (__fn1, __fn2, __fn3); } + /** @} */ + + /** As an extension, SGI provided a functor called @c identity. When a + * functor is required but no operations are desired, this can be used as a + * pass-through. Its @c operator() returns its argument unchanged. + * + * @addtogroup SGIextensions + */ + template <class _Tp> + struct identity : public std::_Identity<_Tp> {}; + + /** @c select1st and @c select2nd are extensions provided by SGI. Their + * @c operator()s + * take a @c std::pair as an argument, and return either the first member + * or the second member, respectively. They can be used (especially with + * the composition functors) to "strip" data from a sequence before + * performing the remainder of an algorithm. + * + * @addtogroup SGIextensions + * @{ + */ + /// An \link SGIextensions SGI extension \endlink. + template <class _Pair> + struct select1st : public std::_Select1st<_Pair> {}; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Pair> + struct select2nd : public std::_Select2nd<_Pair> {}; + /** @} */ + + // extension documented next + template <class _Arg1, class _Arg2> + struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> + { + _Arg1 + operator()(const _Arg1& __x, const _Arg2&) const + { return __x; } + }; + + template <class _Arg1, class _Arg2> + struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> + { + _Arg2 + operator()(const _Arg1&, const _Arg2& __y) const + { return __y; } + }; + + /** The @c operator() of the @c project1st functor takes two arbitrary + * arguments and returns the first one, while @c project2nd returns the + * second one. They are extensions provided by SGI. + * + * @addtogroup SGIextensions + * @{ + */ + + /// An \link SGIextensions SGI extension \endlink. + template <class _Arg1, class _Arg2> + struct project1st : public _Project1st<_Arg1, _Arg2> {}; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Arg1, class _Arg2> + struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; + /** @} */ + + // extension documented next + template <class _Result> + struct _Constant_void_fun + { + typedef _Result result_type; + result_type _M_val; + + _Constant_void_fun(const result_type& __v) : _M_val(__v) {} + + const result_type& + operator()() const + { return _M_val; } + }; + + template <class _Result, class _Argument> + struct _Constant_unary_fun + { + typedef _Argument argument_type; + typedef _Result result_type; + result_type _M_val; + + _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} + + const result_type& + operator()(const _Argument&) const + { return _M_val; } + }; + + template <class _Result, class _Arg1, class _Arg2> + struct _Constant_binary_fun + { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; + _Result _M_val; + + _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} + + const result_type& + operator()(const _Arg1&, const _Arg2&) const + { return _M_val; } + }; + + /** These three functors are each constructed from a single arbitrary + * variable/value. Later, their @c operator()s completely ignore any + * arguments passed, and return the stored value. + * - @c constant_void_fun's @c operator() takes no arguments + * - @c constant_unary_fun's @c operator() takes one argument (ignored) + * - @c constant_binary_fun's @c operator() takes two arguments (ignored) + * + * The helper creator functions @c constant0, @c constant1, and + * @c constant2 each take a "result" argument and construct variables of + * the appropriate functor type. + * + * @addtogroup SGIextensions + * @{ + */ + /// An \link SGIextensions SGI extension \endlink. + template <class _Result> + struct constant_void_fun + : public _Constant_void_fun<_Result> + { + constant_void_fun(const _Result& __v) + : _Constant_void_fun<_Result>(__v) {} + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result, class _Argument = _Result> + struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> + { + constant_unary_fun(const _Result& __v) + : _Constant_unary_fun<_Result, _Argument>(__v) {} + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1> + struct constant_binary_fun + : public _Constant_binary_fun<_Result, _Arg1, _Arg2> + { + constant_binary_fun(const _Result& __v) + : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result> + inline constant_void_fun<_Result> + constant0(const _Result& __val) + { return constant_void_fun<_Result>(__val); } + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result> + inline constant_unary_fun<_Result, _Result> + constant1(const _Result& __val) + { return constant_unary_fun<_Result, _Result>(__val); } + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result> + inline constant_binary_fun<_Result,_Result,_Result> + constant2(const _Result& __val) + { return constant_binary_fun<_Result, _Result, _Result>(__val); } + /** @} */ + + /** The @c subtractive_rng class is documented on + * <a href="http://www.sgi.com/tech/stl/">SGI's site</a>. + * Note that this code assumes that @c int is 32 bits. + * + * @ingroup SGIextensions + */ + class subtractive_rng + : public unary_function<unsigned int, unsigned int> + { + private: + unsigned int _M_table[55]; + size_t _M_index1; + size_t _M_index2; + + public: + /// Returns a number less than the argument. + unsigned int + operator()(unsigned int __limit) + { + _M_index1 = (_M_index1 + 1) % 55; + _M_index2 = (_M_index2 + 1) % 55; + _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; + return _M_table[_M_index1] % __limit; + } + + void + _M_initialize(unsigned int __seed) + { + unsigned int __k = 1; + _M_table[54] = __seed; + size_t __i; + for (__i = 0; __i < 54; __i++) + { + size_t __ii = (21 * (__i + 1) % 55) - 1; + _M_table[__ii] = __k; + __k = __seed - __k; + __seed = _M_table[__ii]; + } + for (int __loop = 0; __loop < 4; __loop++) + { + for (__i = 0; __i < 55; __i++) + _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; + } + _M_index1 = 0; + _M_index2 = 31; + } + + /// Ctor allowing you to initialize the seed. + subtractive_rng(unsigned int __seed) + { _M_initialize(__seed); } + + /// Default ctor; initializes its state with some number you don't see. + subtractive_rng() + { _M_initialize(161803398u); } + }; + + // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, + // provided for backward compatibility, they are no longer part of + // the C++ standard. + + template <class _Ret, class _Tp, class _Arg> + inline mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun1(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template <class _Ret, class _Tp, class _Arg> + inline const_mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun1(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template <class _Ret, class _Tp, class _Arg> + inline mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + template <class _Ret, class _Tp, class _Arg> + inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + +_GLIBCXX_END_NAMESPACE + +#endif + diff --git a/libstdc++/include/ext/hash_fun.h b/libstdc++/include/ext/hash_fun.h new file mode 100644 index 0000000..16c0458 --- /dev/null +++ b/libstdc++/include/ext/hash_fun.h @@ -0,0 +1,172 @@ +// 'struct hash' from SGI -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hash_fun.h + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _HASH_FUN_H +#define _HASH_FUN_H 1 + +#include <cstddef> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + + template<class _Key> + struct hash { }; + + inline size_t + __stl_hash_string(const char* __s) + { + unsigned long __h = 0; + for ( ; *__s; ++__s) + __h = 5 * __h + *__s; + return size_t(__h); + } + + template<> + struct hash<char*> + { + size_t + operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> + struct hash<const char*> + { + size_t + operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> + struct hash<char> + { + size_t + operator()(char __x) const + { return __x; } + }; + + template<> + struct hash<unsigned char> + { + size_t + operator()(unsigned char __x) const + { return __x; } + }; + + template<> + struct hash<signed char> + { + size_t + operator()(unsigned char __x) const + { return __x; } + }; + + template<> + struct hash<short> + { + size_t + operator()(short __x) const + { return __x; } + }; + + template<> + struct hash<unsigned short> + { + size_t + operator()(unsigned short __x) const + { return __x; } + }; + + template<> + struct hash<int> + { + size_t + operator()(int __x) const + { return __x; } + }; + + template<> + struct hash<unsigned int> + { + size_t + operator()(unsigned int __x) const + { return __x; } + }; + + template<> + struct hash<long> + { + size_t + operator()(long __x) const + { return __x; } + }; + + template<> + struct hash<unsigned long> + { + size_t + operator()(unsigned long __x) const + { return __x; } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/hash_map b/libstdc++/include/ext/hash_map new file mode 100644 index 0000000..b6855eb --- /dev/null +++ b/libstdc++/include/ext/hash_map @@ -0,0 +1,605 @@ +// Hashing map implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hash_map + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _HASH_MAP +#define _HASH_MAP 1 + +#include <bits/c++config.h> +#include <ext/hashtable.h> +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(__gnu_cxx, _GLIBCXX_EXT) + + using std::equal_to; + using std::allocator; + using std::pair; + using std::_Select1st; + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<class _Key, class _Tp, class _HashFn = hash<_Key>, + class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > + class hash_map + { + private: + typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn, + _Select1st<pair<const _Key, _Tp> >, + _EqualKey, _Alloc> _Ht; + + _Ht _M_ht; + + public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher + hash_funct() const + { return _M_ht.hash_funct(); } + + key_equal + key_eq() const + { return _M_ht.key_eq(); } + + allocator_type + get_allocator() const + { return _M_ht.get_allocator(); } + + public: + hash_map() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + + explicit + hash_map(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + + hash_map(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + + template<class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + public: + size_type + size() const + { return _M_ht.size(); } + + size_type + max_size() const + { return _M_ht.max_size(); } + + bool + empty() const + { return _M_ht.empty(); } + + void + swap(hash_map& __hs) + { _M_ht.swap(__hs._M_ht); } + + template<class _K1, class _T1, class _HF, class _EqK, class _Al> + friend bool + operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, + const hash_map<_K1, _T1, _HF, _EqK, _Al>&); + + iterator + begin() + { return _M_ht.begin(); } + + iterator + end() + { return _M_ht.end(); } + + const_iterator + begin() const + { return _M_ht.begin(); } + + const_iterator + end() const + { return _M_ht.end(); } + + public: + pair<iterator, bool> + insert(const value_type& __obj) + { return _M_ht.insert_unique(__obj); } + + template<class _InputIterator> + void + insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f, __l); } + + pair<iterator, bool> + insert_noresize(const value_type& __obj) + { return _M_ht.insert_unique_noresize(__obj); } + + iterator + find(const key_type& __key) + { return _M_ht.find(__key); } + + const_iterator + find(const key_type& __key) const + { return _M_ht.find(__key); } + + _Tp& + operator[](const key_type& __key) + { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } + + size_type + count(const key_type& __key) const + { return _M_ht.count(__key); } + + pair<iterator, iterator> + equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type + erase(const key_type& __key) + {return _M_ht.erase(__key); } + + void + erase(iterator __it) + { _M_ht.erase(__it); } + + void + erase(iterator __f, iterator __l) + { _M_ht.erase(__f, __l); } + + void + clear() + { _M_ht.clear(); } + + void + resize(size_type __hint) + { _M_ht.resize(__hint); } + + size_type + bucket_count() const + { return _M_ht.bucket_count(); } + + size_type + max_bucket_count() const + { return _M_ht.max_bucket_count(); } + + size_type + elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } + }; + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline bool + operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { return __hm1._M_ht == __hm2._M_ht; } + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline bool + operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { return !(__hm1 == __hm2); } + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline void + swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { __hm1.swap(__hm2); } + + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<class _Key, class _Tp, + class _HashFn = hash<_Key>, + class _EqualKey = equal_to<_Key>, + class _Alloc = allocator<_Tp> > + class hash_multimap + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept) + + private: + typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn, + _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> + _Ht; + + _Ht _M_ht; + + public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher + hash_funct() const + { return _M_ht.hash_funct(); } + + key_equal + key_eq() const + { return _M_ht.key_eq(); } + + allocator_type + get_allocator() const + { return _M_ht.get_allocator(); } + + public: + hash_multimap() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + + explicit + hash_multimap(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + + hash_multimap(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + + template<class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + public: + size_type + size() const + { return _M_ht.size(); } + + size_type + max_size() const + { return _M_ht.max_size(); } + + bool + empty() const + { return _M_ht.empty(); } + + void + swap(hash_multimap& __hs) + { _M_ht.swap(__hs._M_ht); } + + template<class _K1, class _T1, class _HF, class _EqK, class _Al> + friend bool + operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, + const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); + + iterator + begin() + { return _M_ht.begin(); } + + iterator + end() + { return _M_ht.end(); } + + const_iterator + begin() const + { return _M_ht.begin(); } + + const_iterator + end() const + { return _M_ht.end(); } + + public: + iterator + insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } + + template<class _InputIterator> + void + insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } + + iterator + insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } + + iterator + find(const key_type& __key) + { return _M_ht.find(__key); } + + const_iterator + find(const key_type& __key) const + { return _M_ht.find(__key); } + + size_type + count(const key_type& __key) const + { return _M_ht.count(__key); } + + pair<iterator, iterator> + equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type + erase(const key_type& __key) + { return _M_ht.erase(__key); } + + void + erase(iterator __it) + { _M_ht.erase(__it); } + + void + erase(iterator __f, iterator __l) + { _M_ht.erase(__f, __l); } + + void + clear() + { _M_ht.clear(); } + + public: + void + resize(size_type __hint) + { _M_ht.resize(__hint); } + + size_type + bucket_count() const + { return _M_ht.bucket_count(); } + + size_type + max_bucket_count() const + { return _M_ht.max_bucket_count(); } + + size_type + elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } + }; + + template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> + inline bool + operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, + const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) + { return __hm1._M_ht == __hm2._M_ht; } + + template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> + inline bool + operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, + const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) + { return !(__hm1 == __hm2); } + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline void + swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { __hm1.swap(__hm2); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#ifdef _GLIBCXX_DEBUG +# include <debug/hash_map> +#endif + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Specialization of insert_iterator so that it will work for hash_map + // and hash_multimap. + template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> + class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, + _EqKey, _Alloc> > + { + protected: + typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> + _Container; + _Container* container; + + public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) + : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + container->insert(__value); + return *this; + } + + insert_iterator<_Container>& + operator*() + { return *this; } + + insert_iterator<_Container>& + operator++() { return *this; } + + insert_iterator<_Container>& + operator++(int) + { return *this; } + }; + + template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> + class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, + _EqKey, _Alloc> > + { + protected: + typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> + _Container; + _Container* container; + typename _Container::iterator iter; + + public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) + : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + container->insert(__value); + return *this; + } + + insert_iterator<_Container>& + operator*() + { return *this; } + + insert_iterator<_Container>& + operator++() + { return *this; } + + insert_iterator<_Container>& + operator++(int) + { return *this; } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/hash_set b/libstdc++/include/ext/hash_set new file mode 100644 index 0000000..668fe13 --- /dev/null +++ b/libstdc++/include/ext/hash_set @@ -0,0 +1,574 @@ +// Hashing set implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hash_set + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _HASH_SET +#define _HASH_SET 1 + +#include <bits/c++config.h> +#include <ext/hashtable.h> +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(__gnu_cxx, _GLIBCXX_EXT) + + using std::equal_to; + using std::allocator; + using std::pair; + using std::_Identity; + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<class _Value, class _HashFcn = hash<_Value>, + class _EqualKey = equal_to<_Value>, + class _Alloc = allocator<_Value> > + class hash_set + { + // concept requirements + __glibcxx_class_requires(_Value, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) + + private: + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; + + public: + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher + hash_funct() const + { return _M_ht.hash_funct(); } + + key_equal + key_eq() const + { return _M_ht.key_eq(); } + + allocator_type + get_allocator() const + { return _M_ht.get_allocator(); } + + public: + hash_set() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + + explicit + hash_set(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + + hash_set(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + + template<class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + public: + size_type + size() const + { return _M_ht.size(); } + + size_type + max_size() const + { return _M_ht.max_size(); } + + bool + empty() const + { return _M_ht.empty(); } + + void + swap(hash_set& __hs) + { _M_ht.swap(__hs._M_ht); } + + template<class _Val, class _HF, class _EqK, class _Al> + friend bool + operator==(const hash_set<_Val, _HF, _EqK, _Al>&, + const hash_set<_Val, _HF, _EqK, _Al>&); + + iterator + begin() const + { return _M_ht.begin(); } + + iterator + end() const + { return _M_ht.end(); } + + public: + pair<iterator, bool> + insert(const value_type& __obj) + { + pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj); + return pair<iterator,bool>(__p.first, __p.second); + } + + template<class _InputIterator> + void + insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f, __l); } + + pair<iterator, bool> + insert_noresize(const value_type& __obj) + { + pair<typename _Ht::iterator, bool> __p + = _M_ht.insert_unique_noresize(__obj); + return pair<iterator, bool>(__p.first, __p.second); + } + + iterator + find(const key_type& __key) const + { return _M_ht.find(__key); } + + size_type + count(const key_type& __key) const + { return _M_ht.count(__key); } + + pair<iterator, iterator> + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type + erase(const key_type& __key) + {return _M_ht.erase(__key); } + + void + erase(iterator __it) + { _M_ht.erase(__it); } + + void + erase(iterator __f, iterator __l) + { _M_ht.erase(__f, __l); } + + void + clear() + { _M_ht.clear(); } + + public: + void + resize(size_type __hint) + { _M_ht.resize(__hint); } + + size_type + bucket_count() const + { return _M_ht.bucket_count(); } + + size_type + max_bucket_count() const + { return _M_ht.max_bucket_count(); } + + size_type + elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } + }; + + template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> + inline bool + operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) + { return __hs1._M_ht == __hs2._M_ht; } + + template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> + inline bool + operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) + { return !(__hs1 == __hs2); } + + template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> + inline void + swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, + hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) + { __hs1.swap(__hs2); } + + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<class _Value, + class _HashFcn = hash<_Value>, + class _EqualKey = equal_to<_Value>, + class _Alloc = allocator<_Value> > + class hash_multiset + { + // concept requirements + __glibcxx_class_requires(_Value, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) + + private: + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; + + public: + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher + hash_funct() const + { return _M_ht.hash_funct(); } + + key_equal + key_eq() const + { return _M_ht.key_eq(); } + + allocator_type + get_allocator() const + { return _M_ht.get_allocator(); } + + public: + hash_multiset() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + + explicit + hash_multiset(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + + hash_multiset(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + + template<class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + public: + size_type + size() const + { return _M_ht.size(); } + + size_type + max_size() const + { return _M_ht.max_size(); } + + bool + empty() const + { return _M_ht.empty(); } + + void + swap(hash_multiset& hs) + { _M_ht.swap(hs._M_ht); } + + template<class _Val, class _HF, class _EqK, class _Al> + friend bool + operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&, + const hash_multiset<_Val, _HF, _EqK, _Al>&); + + iterator + begin() const + { return _M_ht.begin(); } + + iterator + end() const + { return _M_ht.end(); } + + public: + iterator + insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } + + template<class _InputIterator> + void + insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } + + iterator + insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } + + iterator + find(const key_type& __key) const + { return _M_ht.find(__key); } + + size_type + count(const key_type& __key) const + { return _M_ht.count(__key); } + + pair<iterator, iterator> + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type + erase(const key_type& __key) + { return _M_ht.erase(__key); } + + void + erase(iterator __it) + { _M_ht.erase(__it); } + + void + erase(iterator __f, iterator __l) + { _M_ht.erase(__f, __l); } + + void + clear() + { _M_ht.clear(); } + + public: + void + resize(size_type __hint) + { _M_ht.resize(__hint); } + + size_type + bucket_count() const + { return _M_ht.bucket_count(); } + + size_type + max_bucket_count() const + { return _M_ht.max_bucket_count(); } + + size_type + elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } + }; + + template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> + inline bool + operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, + const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) + { return __hs1._M_ht == __hs2._M_ht; } + + template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> + inline bool + operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, + const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) + { return !(__hs1 == __hs2); } + + template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> + inline void + swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, + hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) + { __hs1.swap(__hs2); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#ifdef _GLIBCXX_DEBUG +# include <debug/hash_set> +#endif + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Specialization of insert_iterator so that it will work for hash_set + // and hash_multiset. + template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> + class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn, + _EqualKey, _Alloc> > + { + protected: + typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> + _Container; + _Container* container; + + public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) + : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + container->insert(__value); + return *this; + } + + insert_iterator<_Container>& + operator*() + { return *this; } + + insert_iterator<_Container>& + operator++() + { return *this; } + + insert_iterator<_Container>& + operator++(int) + { return *this; } + }; + + template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> + class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn, + _EqualKey, _Alloc> > + { + protected: + typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> + _Container; + _Container* container; + typename _Container::iterator iter; + + public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) + : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + container->insert(__value); + return *this; + } + + insert_iterator<_Container>& + operator*() + { return *this; } + + insert_iterator<_Container>& + operator++() + { return *this; } + + insert_iterator<_Container>& + operator++(int) { return *this; } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/hashtable.h b/libstdc++/include/ext/hashtable.h new file mode 100644 index 0000000..233806f --- /dev/null +++ b/libstdc++/include/ext/hashtable.h @@ -0,0 +1,1130 @@ +// Hashtable implementation used by containers -*- C++ -*- + +// Copyright (C) 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. + +/* + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hashtable.h + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _HASHTABLE_H +#define _HASHTABLE_H 1 + +// Hashtable class, used to implement the hashed associative containers +// hash_set, hash_map, hash_multiset, and hash_multimap. + +#include <vector> +#include <iterator> +#include <bits/stl_algo.h> +#include <bits/stl_function.h> +#include <ext/hash_fun.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + using std::forward_iterator_tag; + using std::input_iterator_tag; + using std::_Construct; + using std::_Destroy; + using std::distance; + using std::vector; + using std::pair; + using std::__iterator_category; + + template<class _Val> + struct _Hashtable_node + { + _Hashtable_node* _M_next; + _Val _M_val; + }; + + template<class _Val, class _Key, class _HashFcn, class _ExtractKey, + class _EqualKey, class _Alloc = std::allocator<_Val> > + class hashtable; + + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_iterator; + + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_const_iterator; + + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_iterator + { + typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _Val& reference; + typedef _Val* pointer; + + _Node* _M_cur; + _Hashtable* _M_ht; + + _Hashtable_iterator(_Node* __n, _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) { } + + _Hashtable_iterator() { } + + reference + operator*() const + { return _M_cur->_M_val; } + + pointer + operator->() const + { return &(operator*()); } + + iterator& + operator++(); + + iterator + operator++(int); + + bool + operator==(const iterator& __it) const + { return _M_cur == __it._M_cur; } + + bool + operator!=(const iterator& __it) const + { return _M_cur != __it._M_cur; } + }; + + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_const_iterator + { + typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn, + _ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef const _Val& reference; + typedef const _Val* pointer; + + const _Node* _M_cur; + const _Hashtable* _M_ht; + + _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) { } + + _Hashtable_const_iterator() { } + + _Hashtable_const_iterator(const iterator& __it) + : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { } + + reference + operator*() const + { return _M_cur->_M_val; } + + pointer + operator->() const + { return &(operator*()); } + + const_iterator& + operator++(); + + const_iterator + operator++(int); + + bool + operator==(const const_iterator& __it) const + { return _M_cur == __it._M_cur; } + + bool + operator!=(const const_iterator& __it) const + { return _M_cur != __it._M_cur; } + }; + + // Note: assumes long is at least 32 bits. + enum { _S_num_primes = 28 }; + + static const unsigned long __stl_prime_list[_S_num_primes] = + { + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul + }; + + inline unsigned long + __stl_next_prime(unsigned long __n) + { + const unsigned long* __first = __stl_prime_list; + const unsigned long* __last = __stl_prime_list + (int)_S_num_primes; + const unsigned long* pos = std::lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; + } + + // Forward declaration of operator==. + template<class _Val, class _Key, class _HF, class _Ex, + class _Eq, class _All> + class hashtable; + + template<class _Val, class _Key, class _HF, class _Ex, + class _Eq, class _All> + bool + operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, + const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2); + + // Hashtables handle allocators a bit differently than other + // containers do. If we're using standard-conforming allocators, then + // a hashtable unconditionally has a member variable to hold its + // allocator, even if it so happens that all instances of the + // allocator type are identical. This is because, for hashtables, + // this extra storage is negligible. Additionally, a base class + // wouldn't serve any other purposes; it wouldn't, for example, + // simplify the exception-handling code. + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + class hashtable + { + public: + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + hasher + hash_funct() const + { return _M_hash; } + + key_equal + key_eq() const + { return _M_equals; } + + private: + typedef _Hashtable_node<_Val> _Node; + + public: + typedef typename _Alloc::template rebind<value_type>::other allocator_type; + allocator_type + get_allocator() const + { return _M_node_allocator; } + + private: + typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; + typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; + typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type; + + _Node_Alloc _M_node_allocator; + + _Node* + _M_get_node() + { return _M_node_allocator.allocate(1); } + + void + _M_put_node(_Node* __p) + { _M_node_allocator.deallocate(__p, 1); } + + private: + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + _Vector_type _M_buckets; + size_type _M_num_elements; + + public: + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, + _EqualKey, _Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, + _EqualKey, _Alloc> + const_iterator; + + friend struct + _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>; + + friend struct + _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, + _EqualKey, _Alloc>; + + public: + hashtable(size_type __n, const _HashFcn& __hf, + const _EqualKey& __eql, const _ExtractKey& __ext, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), + _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0) + { _M_initialize_buckets(__n); } + + hashtable(size_type __n, const _HashFcn& __hf, + const _EqualKey& __eql, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), + _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0) + { _M_initialize_buckets(__n); } + + hashtable(const hashtable& __ht) + : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash), + _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key), + _M_buckets(__ht.get_allocator()), _M_num_elements(0) + { _M_copy_from(__ht); } + + hashtable& + operator= (const hashtable& __ht) + { + if (&__ht != this) + { + clear(); + _M_hash = __ht._M_hash; + _M_equals = __ht._M_equals; + _M_get_key = __ht._M_get_key; + _M_copy_from(__ht); + } + return *this; + } + + ~hashtable() + { clear(); } + + size_type + size() const + { return _M_num_elements; } + + size_type + max_size() const + { return size_type(-1); } + + bool + empty() const + { return size() == 0; } + + void + swap(hashtable& __ht) + { + std::swap(_M_hash, __ht._M_hash); + std::swap(_M_equals, __ht._M_equals); + std::swap(_M_get_key, __ht._M_get_key); + _M_buckets.swap(__ht._M_buckets); + std::swap(_M_num_elements, __ht._M_num_elements); + } + + iterator + begin() + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return iterator(_M_buckets[__n], this); + return end(); + } + + iterator + end() + { return iterator(0, this); } + + const_iterator + begin() const + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return const_iterator(_M_buckets[__n], this); + return end(); + } + + const_iterator + end() const + { return const_iterator(0, this); } + + template<class _Vl, class _Ky, class _HF, class _Ex, class _Eq, + class _Al> + friend bool + operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, + const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); + + public: + size_type + bucket_count() const + { return _M_buckets.size(); } + + size_type + max_bucket_count() const + { return __stl_prime_list[(int)_S_num_primes - 1]; } + + size_type + elems_in_bucket(size_type __bucket) const + { + size_type __result = 0; + for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next) + __result += 1; + return __result; + } + + pair<iterator, bool> + insert_unique(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_unique_noresize(__obj); + } + + iterator + insert_equal(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_equal_noresize(__obj); + } + + pair<iterator, bool> + insert_unique_noresize(const value_type& __obj); + + iterator + insert_equal_noresize(const value_type& __obj); + + template<class _InputIterator> + void + insert_unique(_InputIterator __f, _InputIterator __l) + { insert_unique(__f, __l, __iterator_category(__f)); } + + template<class _InputIterator> + void + insert_equal(_InputIterator __f, _InputIterator __l) + { insert_equal(__f, __l, __iterator_category(__f)); } + + template<class _InputIterator> + void + insert_unique(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_unique(*__f); + } + + template<class _InputIterator> + void + insert_equal(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_equal(*__f); + } + + template<class _ForwardIterator> + void + insert_unique(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + template<class _ForwardIterator> + void + insert_equal(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } + + reference + find_or_insert(const value_type& __obj); + + iterator + find(const key_type& __key) + { + size_type __n = _M_bkt_num_key(__key); + _Node* __first; + for (__first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + { } + return iterator(__first, this); + } + + const_iterator + find(const key_type& __key) const + { + size_type __n = _M_bkt_num_key(__key); + const _Node* __first; + for (__first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + { } + return const_iterator(__first, this); + } + + size_type + count(const key_type& __key) const + { + const size_type __n = _M_bkt_num_key(__key); + size_type __result = 0; + + for (const _Node* __cur = _M_buckets[__n]; __cur; + __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), __key)) + ++__result; + return __result; + } + + pair<iterator, iterator> + equal_range(const key_type& __key); + + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const; + + size_type + erase(const key_type& __key); + + void + erase(const iterator& __it); + + void + erase(iterator __first, iterator __last); + + void + erase(const const_iterator& __it); + + void + erase(const_iterator __first, const_iterator __last); + + void + resize(size_type __num_elements_hint); + + void + clear(); + + private: + size_type + _M_next_size(size_type __n) const + { return __stl_next_prime(__n); } + + void + _M_initialize_buckets(size_type __n) + { + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + _M_num_elements = 0; + } + + size_type + _M_bkt_num_key(const key_type& __key) const + { return _M_bkt_num_key(__key, _M_buckets.size()); } + + size_type + _M_bkt_num(const value_type& __obj) const + { return _M_bkt_num_key(_M_get_key(__obj)); } + + size_type + _M_bkt_num_key(const key_type& __key, size_t __n) const + { return _M_hash(__key) % __n; } + + size_type + _M_bkt_num(const value_type& __obj, size_t __n) const + { return _M_bkt_num_key(_M_get_key(__obj), __n); } + + _Node* + _M_new_node(const value_type& __obj) + { + _Node* __n = _M_get_node(); + __n->_M_next = 0; + try + { + this->get_allocator().construct(&__n->_M_val, __obj); + return __n; + } + catch(...) + { + _M_put_node(__n); + __throw_exception_again; + } + } + + void + _M_delete_node(_Node* __n) + { + this->get_allocator().destroy(&__n->_M_val); + _M_put_node(__n); + } + + void + _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); + + void + _M_erase_bucket(const size_type __n, _Node* __last); + + void + _M_copy_from(const hashtable& __ht); + }; + + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> + _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& + _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++() + { + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) + { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; + } + + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> + inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> + _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++(int) + { + iterator __tmp = *this; + ++*this; + return __tmp; + } + + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> + _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& + _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++() + { + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) + { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; + } + + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> + inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> + _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++(int) + { + const_iterator __tmp = *this; + ++*this; + return __tmp; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + bool + operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, + const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) + { + typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node; + + if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) + return false; + + for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) + { + _Node* __cur1 = __ht1._M_buckets[__n]; + _Node* __cur2 = __ht2._M_buckets[__n]; + // Check same length of lists + for (; __cur1 && __cur2; + __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) + { } + if (__cur1 || __cur2) + return false; + // Now check one's elements are in the other + for (__cur1 = __ht1._M_buckets[__n] ; __cur1; + __cur1 = __cur1->_M_next) + { + bool _found__cur1 = false; + for (__cur2 = __ht2._M_buckets[__n]; + __cur2; __cur2 = __cur2->_M_next) + { + if (__cur1->_M_val == __cur2->_M_val) + { + _found__cur1 = true; + break; + } + } + if (!_found__cur1) + return false; + } + } + return true; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + inline bool + operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, + const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) + { return !(__ht1 == __ht2); } + + template<class _Val, class _Key, class _HF, class _Extract, class _EqKey, + class _All> + inline void + swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) + { __ht1.swap(__ht2); } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool> + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + insert_unique_noresize(const value_type& __obj) + { + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return pair<iterator, bool>(iterator(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return pair<iterator, bool>(iterator(__tmp, this), true); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + insert_equal_noresize(const value_type& __obj) + { + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + { + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __cur->_M_next; + __cur->_M_next = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); + } + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + find_or_insert(const value_type& __obj) + { + resize(_M_num_elements + 1); + + size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return __cur->_M_val; + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return __tmp->_M_val; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator> + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + equal_range(const key_type& __key) + { + typedef pair<iterator, iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (_Node* __first = _M_buckets[__n]; __first; + __first = __first->_M_next) + if (_M_equals(_M_get_key(__first->_M_val), __key)) + { + for (_Node* __cur = __first->_M_next; __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(iterator(__first, this), iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(iterator(__first, this), + iterator(_M_buckets[__m], this)); + return _Pii(iterator(__first, this), end()); + } + return _Pii(end(), end()); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator, + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator> + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + equal_range(const key_type& __key) const + { + typedef pair<const_iterator, const_iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (const _Node* __first = _M_buckets[__n]; __first; + __first = __first->_M_next) + { + if (_M_equals(_M_get_key(__first->_M_val), __key)) + { + for (const _Node* __cur = __first->_M_next; __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(const_iterator(__first, this), + const_iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(const_iterator(__first, this), + const_iterator(_M_buckets[__m], this)); + return _Pii(const_iterator(__first, this), end()); + } + } + return _Pii(end(), end()); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(const key_type& __key) + { + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + size_type __erased = 0; + + if (__first) + { + _Node* __cur = __first; + _Node* __next = __cur->_M_next; + while (__next) + { + if (_M_equals(_M_get_key(__next->_M_val), __key)) + { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + ++__erased; + --_M_num_elements; + } + else + { + __cur = __next; + __next = __cur->_M_next; + } + } + if (_M_equals(_M_get_key(__first->_M_val), __key)) + { + _M_buckets[__n] = __first->_M_next; + _M_delete_node(__first); + ++__erased; + --_M_num_elements; + } + } + return __erased; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(const iterator& __it) + { + _Node* __p = __it._M_cur; + if (__p) + { + const size_type __n = _M_bkt_num(__p->_M_val); + _Node* __cur = _M_buckets[__n]; + + if (__cur == __p) + { + _M_buckets[__n] = __cur->_M_next; + _M_delete_node(__cur); + --_M_num_elements; + } + else + { + _Node* __next = __cur->_M_next; + while (__next) + { + if (__next == __p) + { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + --_M_num_elements; + break; + } + else + { + __cur = __next; + __next = __cur->_M_next; + } + } + } + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(iterator __first, iterator __last) + { + size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) + : _M_buckets.size(); + + size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) + : _M_buckets.size(); + + if (__first._M_cur == __last._M_cur) + return; + else if (__f_bucket == __l_bucket) + _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); + else + { + _M_erase_bucket(__f_bucket, __first._M_cur, 0); + for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) + _M_erase_bucket(__n, 0); + if (__l_bucket != _M_buckets.size()) + _M_erase_bucket(__l_bucket, __last._M_cur); + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + inline void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(const_iterator __first, const_iterator __last) + { + erase(iterator(const_cast<_Node*>(__first._M_cur), + const_cast<hashtable*>(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast<hashtable*>(__last._M_ht))); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + inline void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(const const_iterator& __it) + { erase(iterator(const_cast<_Node*>(__it._M_cur), + const_cast<hashtable*>(__it._M_ht))); } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + resize(size_type __num_elements_hint) + { + const size_type __old_n = _M_buckets.size(); + if (__num_elements_hint > __old_n) + { + const size_type __n = _M_next_size(__num_elements_hint); + if (__n > __old_n) + { + _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); + try + { + for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) + { + _Node* __first = _M_buckets[__bucket]; + while (__first) + { + size_type __new_bucket = _M_bkt_num(__first->_M_val, + __n); + _M_buckets[__bucket] = __first->_M_next; + __first->_M_next = __tmp[__new_bucket]; + __tmp[__new_bucket] = __first; + __first = _M_buckets[__bucket]; + } + } + _M_buckets.swap(__tmp); + } + catch(...) + { + for (size_type __bucket = 0; __bucket < __tmp.size(); + ++__bucket) + { + while (__tmp[__bucket]) + { + _Node* __next = __tmp[__bucket]->_M_next; + _M_delete_node(__tmp[__bucket]); + __tmp[__bucket] = __next; + } + } + __throw_exception_again; + } + } + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) + { + _Node* __cur = _M_buckets[__n]; + if (__cur == __first) + _M_erase_bucket(__n, __last); + else + { + _Node* __next; + for (__next = __cur->_M_next; + __next != __first; + __cur = __next, __next = __cur->_M_next) + ; + while (__next != __last) + { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; + } + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + _M_erase_bucket(const size_type __n, _Node* __last) + { + _Node* __cur = _M_buckets[__n]; + while (__cur != __last) + { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + _M_buckets[__n] = __cur; + --_M_num_elements; + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + clear() + { + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) + { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) + { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + } + _M_buckets[__i] = 0; + } + _M_num_elements = 0; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + _M_copy_from(const hashtable& __ht) + { + _M_buckets.clear(); + _M_buckets.reserve(__ht._M_buckets.size()); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); + try + { + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + const _Node* __cur = __ht._M_buckets[__i]; + if (__cur) + { + _Node* __local_copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = __local_copy; + + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) + { + __local_copy->_M_next = _M_new_node(__next->_M_val); + __local_copy = __local_copy->_M_next; + } + } + } + _M_num_elements = __ht._M_num_elements; + } + catch(...) + { + clear(); + __throw_exception_again; + } + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/iterator b/libstdc++/include/ext/iterator new file mode 100644 index 0000000..b59e5ca --- /dev/null +++ b/libstdc++/include/ext/iterator @@ -0,0 +1,118 @@ +// HP/SGI iterator extensions -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/iterator + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _EXT_ITERATOR +#define _EXT_ITERATOR 1 + +#pragma GCC system_header + +#include <bits/concept_check.h> +#include <iterator> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // There are two signatures for distance. In addition to the one + // taking two iterators and returning a result, there is another + // taking two iterators and a reference-to-result variable, and + // returning nothing. The latter seems to be an SGI extension. + // -- pedwards + template<typename _InputIterator, typename _Distance> + inline void + __distance(_InputIterator __first, _InputIterator __last, + _Distance& __n, std::input_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + while (__first != __last) + { + ++__first; + ++__n; + } + } + + template<typename _RandomAccessIterator, typename _Distance> + inline void + __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Distance& __n, std::random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __n += __last - __first; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _InputIterator, typename _Distance> + inline void + distance(_InputIterator __first, _InputIterator __last, + _Distance& __n) + { + // concept requirements -- taken care of in __distance + __distance(__first, __last, __n, std::__iterator_category(__first)); + } + +_GLIBCXX_END_NAMESPACE + +#endif + diff --git a/libstdc++/include/ext/malloc_allocator.h b/libstdc++/include/ext/malloc_allocator.h new file mode 100644 index 0000000..0f23e06 --- /dev/null +++ b/libstdc++/include/ext/malloc_allocator.h @@ -0,0 +1,129 @@ +// Allocator that wraps "C" malloc -*- C++ -*- + +// Copyright (C) 2001, 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. + +/** @file ext/malloc_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _MALLOC_ALLOCATOR_H +#define _MALLOC_ALLOCATOR_H 1 + +#include <cstdlib> +#include <new> +#include <bits/functexcept.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + + /** + * @brief An allocator that uses malloc. + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls malloc + * - all deallocation calls free + */ + template<typename _Tp> + class malloc_allocator + { + 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 malloc_allocator<_Tp1> other; }; + + malloc_allocator() throw() { } + + malloc_allocator(const malloc_allocator&) throw() { } + + template<typename _Tp1> + malloc_allocator(const malloc_allocator<_Tp1>&) throw() { } + + ~malloc_allocator() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + pointer + allocate(size_type __n, const void* = 0) + { + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); + + pointer __ret = static_cast<_Tp*>(malloc(__n * sizeof(_Tp))); + if (!__ret) + std::__throw_bad_alloc(); + return __ret; + } + + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type) + { free(static_cast<void*>(__p)); } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) value_type(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + + template<typename _Tp> + inline bool + operator==(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&) + { return true; } + + template<typename _Tp> + inline bool + operator!=(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&) + { return false; } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/memory b/libstdc++/include/ext/memory new file mode 100644 index 0000000..0755d89 --- /dev/null +++ b/libstdc++/include/ext/memory @@ -0,0 +1,199 @@ +// Memory extensions -*- C++ -*- + +// Copyright (C) 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/memory + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _EXT_MEMORY +#define _EXT_MEMORY 1 + +#pragma GCC system_header + +#include <memory> +#include <bits/stl_tempbuf.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::ptrdiff_t; + using std::pair; + using std::__iterator_category; + using std::_Temporary_buffer; + + template<typename _InputIter, typename _Size, typename _ForwardIter> + pair<_InputIter, _ForwardIter> + __uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result, std::input_iterator_tag) + { + _ForwardIter __cur = __result; + try + { + for (; __count > 0 ; --__count, ++__first, ++__cur) + std::_Construct(&*__cur, *__first); + return pair<_InputIter, _ForwardIter>(__first, __cur); + } + catch(...) + { + std::_Destroy(__result, __cur); + __throw_exception_again; + } + } + + template<typename _RandomAccessIter, typename _Size, typename _ForwardIter> + inline pair<_RandomAccessIter, _ForwardIter> + __uninitialized_copy_n(_RandomAccessIter __first, _Size __count, + _ForwardIter __result, + std::random_access_iterator_tag) + { + _RandomAccessIter __last = __first + __count; + return (pair<_RandomAccessIter, _ForwardIter> + (__last, std::uninitialized_copy(__first, __last, __result))); + } + + template<typename _InputIter, typename _Size, typename _ForwardIter> + inline pair<_InputIter, _ForwardIter> + __uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) + { return __uninitialized_copy_n(__first, __count, __result, + __iterator_category(__first)); } + + /** + * @brief Copies the range [first,last) into result. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return result + (first - last) + * @ingroup SGIextensions + * + * Like copy(), but does not require an initialized output range. + */ + template<typename _InputIter, typename _Size, typename _ForwardIter> + inline pair<_InputIter, _ForwardIter> + uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) + { return __uninitialized_copy_n(__first, __count, __result, + __iterator_category(__first)); } + + + // An alternative version of uninitialized_copy_n that constructs + // and destroys objects with a user-provided allocator. + template<typename _InputIter, typename _Size, typename _ForwardIter, + typename _Allocator> + pair<_InputIter, _ForwardIter> + __uninitialized_copy_n_a(_InputIter __first, _Size __count, + _ForwardIter __result, + _Allocator __alloc) + { + _ForwardIter __cur = __result; + try + { + for (; __count > 0 ; --__count, ++__first, ++__cur) + __alloc.construct(&*__cur, *__first); + return pair<_InputIter, _ForwardIter>(__first, __cur); + } + catch(...) + { + std::_Destroy(__result, __cur, __alloc); + __throw_exception_again; + } + } + + template<typename _InputIter, typename _Size, typename _ForwardIter, + typename _Tp> + inline pair<_InputIter, _ForwardIter> + __uninitialized_copy_n_a(_InputIter __first, _Size __count, + _ForwardIter __result, + std::allocator<_Tp>) + { + return uninitialized_copy_n(__first, __count, __result); + } + + /** + * This class provides similar behavior and semantics of the standard + * functions get_temporary_buffer() and return_temporary_buffer(), but + * encapsulated in a type vaguely resembling a standard container. + * + * By default, a temporary_buffer<Iter> stores space for objects of + * whatever type the Iter iterator points to. It is constructed from a + * typical [first,last) range, and provides the begin(), end(), size() + * functions, as well as requested_size(). For non-trivial types, copies + * of *first will be used to initialize the storage. + * + * @c malloc is used to obtain underlying storage. + * + * Like get_temporary_buffer(), not all the requested memory may be + * available. Ideally, the created buffer will be large enough to hold a + * copy of [first,last), but if size() is less than requested_size(), + * then this didn't happen. + * + * @ingroup SGIextensions + */ + template <class _ForwardIterator, class _Tp + = typename std::iterator_traits<_ForwardIterator>::value_type > + struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> + { + /// Requests storage large enough to hold a copy of [first,last). + temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) { } + + /// Destroys objects and frees storage. + ~temporary_buffer() { } + }; + +_GLIBCXX_END_NAMESPACE + +#endif + diff --git a/libstdc++/include/ext/mt_allocator.h b/libstdc++/include/ext/mt_allocator.h new file mode 100644 index 0000000..bc2d61f --- /dev/null +++ b/libstdc++/include/ext/mt_allocator.h @@ -0,0 +1,746 @@ +// MT-optimized allocator -*- C++ -*- + +// Copyright (C) 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. + +/** @file ext/mt_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _MT_ALLOCATOR_H +#define _MT_ALLOCATOR_H 1 + +#include <new> +#include <cstdlib> +#include <bits/functexcept.h> +#include <ext/atomicity.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + + typedef void (*__destroy_handler)(void*); + + /// @brief Base class for pool object. + struct __pool_base + { + // Using short int as type for the binmap implies we are never + // caching blocks larger than 32768 with this allocator. + typedef unsigned short int _Binmap_type; + + // Variables used to configure the behavior of the allocator, + // assigned and explained in detail below. + struct _Tune + { + // Compile time constants for the default _Tune values. + enum { _S_align = 8 }; + enum { _S_max_bytes = 128 }; + enum { _S_min_bin = 8 }; + enum { _S_chunk_size = 4096 - 4 * sizeof(void*) }; + enum { _S_max_threads = 4096 }; + enum { _S_freelist_headroom = 10 }; + + // Alignment needed. + // NB: In any case must be >= sizeof(_Block_record), that + // is 4 on 32 bit machines and 8 on 64 bit machines. + size_t _M_align; + + // Allocation requests (after round-up to power of 2) below + // this value will be handled by the allocator. A raw new/ + // call will be used for requests larger than this value. + // NB: Must be much smaller than _M_chunk_size and in any + // case <= 32768. + size_t _M_max_bytes; + + // Size in bytes of the smallest bin. + // NB: Must be a power of 2 and >= _M_align (and of course + // much smaller than _M_max_bytes). + size_t _M_min_bin; + + // In order to avoid fragmenting and minimize the number of + // new() calls we always request new memory using this + // value. Based on previous discussions on the libstdc++ + // mailing list we have choosen the value below. + // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html + // NB: At least one order of magnitude > _M_max_bytes. + size_t _M_chunk_size; + + // The maximum number of supported threads. For + // single-threaded operation, use one. Maximum values will + // vary depending on details of the underlying system. (For + // instance, Linux 2.4.18 reports 4070 in + // /proc/sys/kernel/threads-max, while Linux 2.6.6 reports + // 65534) + size_t _M_max_threads; + + // Each time a deallocation occurs in a threaded application + // we make sure that there are no more than + // _M_freelist_headroom % of used memory on the freelist. If + // the number of additional records is more than + // _M_freelist_headroom % of the freelist, we move these + // records back to the global pool. + size_t _M_freelist_headroom; + + // Set to true forces all allocations to use new(). + bool _M_force_new; + + explicit + _Tune() + : _M_align(_S_align), _M_max_bytes(_S_max_bytes), _M_min_bin(_S_min_bin), + _M_chunk_size(_S_chunk_size), _M_max_threads(_S_max_threads), + _M_freelist_headroom(_S_freelist_headroom), + _M_force_new(std::getenv("GLIBCXX_FORCE_NEW") ? true : false) + { } + + explicit + _Tune(size_t __align, size_t __maxb, size_t __minbin, size_t __chunk, + size_t __maxthreads, size_t __headroom, bool __force) + : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin), + _M_chunk_size(__chunk), _M_max_threads(__maxthreads), + _M_freelist_headroom(__headroom), _M_force_new(__force) + { } + }; + + struct _Block_address + { + void* _M_initial; + _Block_address* _M_next; + }; + + const _Tune& + _M_get_options() const + { return _M_options; } + + void + _M_set_options(_Tune __t) + { + if (!_M_init) + _M_options = __t; + } + + bool + _M_check_threshold(size_t __bytes) + { return __bytes > _M_options._M_max_bytes || _M_options._M_force_new; } + + size_t + _M_get_binmap(size_t __bytes) + { return _M_binmap[__bytes]; } + + const size_t + _M_get_align() + { return _M_options._M_align; } + + explicit + __pool_base() + : _M_options(_Tune()), _M_binmap(NULL), _M_init(false) { } + + explicit + __pool_base(const _Tune& __options) + : _M_options(__options), _M_binmap(NULL), _M_init(false) { } + + private: + explicit + __pool_base(const __pool_base&); + + __pool_base& + operator=(const __pool_base&); + + protected: + // Configuration options. + _Tune _M_options; + + _Binmap_type* _M_binmap; + + // Configuration of the pool object via _M_options can happen + // after construction but before initialization. After + // initialization is complete, this variable is set to true. + bool _M_init; + }; + + + /** + * @brief Data describing the underlying memory pool, parameterized on + * threading support. + */ + template<bool _Thread> + class __pool; + + /// Specialization for single thread. + template<> + class __pool<false> : public __pool_base + { + public: + union _Block_record + { + // Points to the block_record of the next free block. + _Block_record* _M_next; + }; + + struct _Bin_record + { + // An "array" of pointers to the first free block. + _Block_record** _M_first; + + // A list of the initial addresses of all allocated blocks. + _Block_address* _M_address; + }; + + void + _M_initialize_once() + { + if (__builtin_expect(_M_init == false, false)) + _M_initialize(); + } + + void + _M_destroy() throw(); + + char* + _M_reserve_block(size_t __bytes, const size_t __thread_id); + + void + _M_reclaim_block(char* __p, size_t __bytes); + + size_t + _M_get_thread_id() { return 0; } + + const _Bin_record& + _M_get_bin(size_t __which) + { return _M_bin[__which]; } + + void + _M_adjust_freelist(const _Bin_record&, _Block_record*, size_t) + { } + + explicit __pool() + : _M_bin(NULL), _M_bin_size(1) { } + + explicit __pool(const __pool_base::_Tune& __tune) + : __pool_base(__tune), _M_bin(NULL), _M_bin_size(1) { } + + private: + // An "array" of bin_records each of which represents a specific + // power of 2 size. Memory to this "array" is allocated in + // _M_initialize(). + _Bin_record* _M_bin; + + // Actual value calculated in _M_initialize(). + size_t _M_bin_size; + + void + _M_initialize(); + }; + +#ifdef __GTHREADS + /// Specialization for thread enabled, via gthreads.h. + template<> + class __pool<true> : public __pool_base + { + public: + // Each requesting thread is assigned an id ranging from 1 to + // _S_max_threads. Thread id 0 is used as a global memory pool. + // In order to get constant performance on the thread assignment + // routine, we keep a list of free ids. When a thread first + // requests memory we remove the first record in this list and + // stores the address in a __gthread_key. When initializing the + // __gthread_key we specify a destructor. When this destructor + // (i.e. the thread dies) is called, we return the thread id to + // the front of this list. + struct _Thread_record + { + // Points to next free thread id record. NULL if last record in list. + _Thread_record* _M_next; + + // Thread id ranging from 1 to _S_max_threads. + size_t _M_id; + }; + + union _Block_record + { + // Points to the block_record of the next free block. + _Block_record* _M_next; + + // The thread id of the thread which has requested this block. + size_t _M_thread_id; + }; + + struct _Bin_record + { + // An "array" of pointers to the first free block for each + // thread id. Memory to this "array" is allocated in + // _S_initialize() for _S_max_threads + global pool 0. + _Block_record** _M_first; + + // A list of the initial addresses of all allocated blocks. + _Block_address* _M_address; + + // An "array" of counters used to keep track of the amount of + // blocks that are on the freelist/used for each thread id. + // - Note that the second part of the allocated _M_used "array" + // actually hosts (atomic) counters of reclaimed blocks: in + // _M_reserve_block and in _M_reclaim_block those numbers are + // subtracted from the first ones to obtain the actual size + // of the "working set" of the given thread. + // - Memory to these "arrays" is allocated in _S_initialize() + // for _S_max_threads + global pool 0. + size_t* _M_free; + size_t* _M_used; + + // Each bin has its own mutex which is used to ensure data + // integrity while changing "ownership" on a block. The mutex + // is initialized in _S_initialize(). + __gthread_mutex_t* _M_mutex; + }; + + // XXX GLIBCXX_ABI Deprecated + void + _M_initialize(__destroy_handler); + + void + _M_initialize_once() + { + if (__builtin_expect(_M_init == false, false)) + _M_initialize(); + } + + void + _M_destroy() throw(); + + char* + _M_reserve_block(size_t __bytes, const size_t __thread_id); + + void + _M_reclaim_block(char* __p, size_t __bytes); + + const _Bin_record& + _M_get_bin(size_t __which) + { return _M_bin[__which]; } + + void + _M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block, + size_t __thread_id) + { + if (__gthread_active_p()) + { + __block->_M_thread_id = __thread_id; + --__bin._M_free[__thread_id]; + ++__bin._M_used[__thread_id]; + } + } + + // XXX GLIBCXX_ABI Deprecated + void + _M_destroy_thread_key(void*); + + size_t + _M_get_thread_id(); + + explicit __pool() + : _M_bin(NULL), _M_bin_size(1), _M_thread_freelist(NULL) + { } + + explicit __pool(const __pool_base::_Tune& __tune) + : __pool_base(__tune), _M_bin(NULL), _M_bin_size(1), + _M_thread_freelist(NULL) + { } + + private: + // An "array" of bin_records each of which represents a specific + // power of 2 size. Memory to this "array" is allocated in + // _M_initialize(). + _Bin_record* _M_bin; + + // Actual value calculated in _M_initialize(). + size_t _M_bin_size; + + _Thread_record* _M_thread_freelist; + void* _M_thread_freelist_initial; + + void + _M_initialize(); + }; +#endif + + template<template <bool> class _PoolTp, bool _Thread> + struct __common_pool + { + typedef _PoolTp<_Thread> pool_type; + + static pool_type& + _S_get_pool() + { + static pool_type _S_pool; + return _S_pool; + } + }; + + template<template <bool> class _PoolTp, bool _Thread> + struct __common_pool_base; + + template<template <bool> class _PoolTp> + struct __common_pool_base<_PoolTp, false> + : public __common_pool<_PoolTp, false> + { + using __common_pool<_PoolTp, false>::_S_get_pool; + + static void + _S_initialize_once() + { + static bool __init; + if (__builtin_expect(__init == false, false)) + { + _S_get_pool()._M_initialize_once(); + __init = true; + } + } + }; + +#ifdef __GTHREADS + template<template <bool> class _PoolTp> + struct __common_pool_base<_PoolTp, true> + : public __common_pool<_PoolTp, true> + { + using __common_pool<_PoolTp, true>::_S_get_pool; + + static void + _S_initialize() + { _S_get_pool()._M_initialize_once(); } + + static void + _S_initialize_once() + { + static bool __init; + if (__builtin_expect(__init == false, false)) + { + if (__gthread_active_p()) + { + // On some platforms, __gthread_once_t is an aggregate. + static __gthread_once_t __once = __GTHREAD_ONCE_INIT; + __gthread_once(&__once, _S_initialize); + } + + // Double check initialization. May be necessary on some + // systems for proper construction when not compiling with + // thread flags. + _S_get_pool()._M_initialize_once(); + __init = true; + } + } + }; +#endif + + /// @brief Policy for shared __pool objects. + template<template <bool> class _PoolTp, bool _Thread> + struct __common_pool_policy : public __common_pool_base<_PoolTp, _Thread> + { + template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, + bool _Thread1 = _Thread> + struct _M_rebind + { typedef __common_pool_policy<_PoolTp1, _Thread1> other; }; + + using __common_pool_base<_PoolTp, _Thread>::_S_get_pool; + using __common_pool_base<_PoolTp, _Thread>::_S_initialize_once; + }; + + + template<typename _Tp, template <bool> class _PoolTp, bool _Thread> + struct __per_type_pool + { + typedef _Tp value_type; + typedef _PoolTp<_Thread> pool_type; + + static pool_type& + _S_get_pool() + { + // Sane defaults for the _PoolTp. + typedef typename pool_type::_Block_record _Block_record; + const static size_t __a = (__alignof__(_Tp) >= sizeof(_Block_record) + ? __alignof__(_Tp) : sizeof(_Block_record)); + + typedef typename __pool_base::_Tune _Tune; + static _Tune _S_tune(__a, sizeof(_Tp) * 64, + sizeof(_Tp) * 2 >= __a ? sizeof(_Tp) * 2 : __a, + sizeof(_Tp) * size_t(_Tune::_S_chunk_size), + _Tune::_S_max_threads, + _Tune::_S_freelist_headroom, + std::getenv("GLIBCXX_FORCE_NEW") ? true : false); + static pool_type _S_pool(_S_tune); + return _S_pool; + } + }; + + template<typename _Tp, template <bool> class _PoolTp, bool _Thread> + struct __per_type_pool_base; + + template<typename _Tp, template <bool> class _PoolTp> + struct __per_type_pool_base<_Tp, _PoolTp, false> + : public __per_type_pool<_Tp, _PoolTp, false> + { + using __per_type_pool<_Tp, _PoolTp, false>::_S_get_pool; + + static void + _S_initialize_once() + { + static bool __init; + if (__builtin_expect(__init == false, false)) + { + _S_get_pool()._M_initialize_once(); + __init = true; + } + } + }; + + #ifdef __GTHREADS + template<typename _Tp, template <bool> class _PoolTp> + struct __per_type_pool_base<_Tp, _PoolTp, true> + : public __per_type_pool<_Tp, _PoolTp, true> + { + using __per_type_pool<_Tp, _PoolTp, true>::_S_get_pool; + + static void + _S_initialize() + { _S_get_pool()._M_initialize_once(); } + + static void + _S_initialize_once() + { + static bool __init; + if (__builtin_expect(__init == false, false)) + { + if (__gthread_active_p()) + { + // On some platforms, __gthread_once_t is an aggregate. + static __gthread_once_t __once = __GTHREAD_ONCE_INIT; + __gthread_once(&__once, _S_initialize); + } + + // Double check initialization. May be necessary on some + // systems for proper construction when not compiling with + // thread flags. + _S_get_pool()._M_initialize_once(); + __init = true; + } + } + }; +#endif + + /// @brief Policy for individual __pool objects. + template<typename _Tp, template <bool> class _PoolTp, bool _Thread> + struct __per_type_pool_policy + : public __per_type_pool_base<_Tp, _PoolTp, _Thread> + { + template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, + bool _Thread1 = _Thread> + struct _M_rebind + { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; }; + + using __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_get_pool; + using __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_initialize_once; + }; + + + /// @brief Base class for _Tp dependent member functions. + template<typename _Tp> + class __mt_alloc_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; + + pointer + address(reference __x) const + { return &__x; } + + const_pointer + address(const_reference __x) const + { return &__x; } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + +#ifdef __GTHREADS +#define __thread_default true +#else +#define __thread_default false +#endif + + /** + * @brief This is a fixed size (power of 2) allocator which - when + * compiled with thread support - will maintain one freelist per + * size per thread plus a "global" one. Steps are taken to limit + * the per thread freelist sizes (by returning excess back to + * the "global" list). + * + * Further details: + * http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html + */ + template<typename _Tp, + typename _Poolp = __common_pool_policy<__pool, __thread_default> > + class __mt_alloc : public __mt_alloc_base<_Tp> + { + 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; + typedef _Poolp __policy_type; + typedef typename _Poolp::pool_type __pool_type; + + template<typename _Tp1, typename _Poolp1 = _Poolp> + struct rebind + { + typedef typename _Poolp1::template _M_rebind<_Tp1>::other pol_type; + typedef __mt_alloc<_Tp1, pol_type> other; + }; + + __mt_alloc() throw() { } + + __mt_alloc(const __mt_alloc&) throw() { } + + template<typename _Tp1, typename _Poolp1> + __mt_alloc(const __mt_alloc<_Tp1, _Poolp1>&) throw() { } + + ~__mt_alloc() throw() { } + + pointer + allocate(size_type __n, const void* = 0); + + void + deallocate(pointer __p, size_type __n); + + const __pool_base::_Tune + _M_get_options() + { + // Return a copy, not a reference, for external consumption. + return __policy_type::_S_get_pool()._M_get_options(); + } + + void + _M_set_options(__pool_base::_Tune __t) + { __policy_type::_S_get_pool()._M_set_options(__t); } + }; + + template<typename _Tp, typename _Poolp> + typename __mt_alloc<_Tp, _Poolp>::pointer + __mt_alloc<_Tp, _Poolp>:: + allocate(size_type __n, const void*) + { + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); + + __policy_type::_S_initialize_once(); + + // Requests larger than _M_max_bytes are handled by operator + // new/delete directly. + __pool_type& __pool = __policy_type::_S_get_pool(); + const size_t __bytes = __n * sizeof(_Tp); + if (__pool._M_check_threshold(__bytes)) + { + void* __ret = ::operator new(__bytes); + return static_cast<_Tp*>(__ret); + } + + // Round up to power of 2 and figure out which bin to use. + const size_t __which = __pool._M_get_binmap(__bytes); + const size_t __thread_id = __pool._M_get_thread_id(); + + // Find out if we have blocks on our freelist. If so, go ahead + // and use them directly without having to lock anything. + char* __c; + typedef typename __pool_type::_Bin_record _Bin_record; + const _Bin_record& __bin = __pool._M_get_bin(__which); + if (__bin._M_first[__thread_id]) + { + // Already reserved. + typedef typename __pool_type::_Block_record _Block_record; + _Block_record* __block = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __block->_M_next; + + __pool._M_adjust_freelist(__bin, __block, __thread_id); + __c = reinterpret_cast<char*>(__block) + __pool._M_get_align(); + } + else + { + // Null, reserve. + __c = __pool._M_reserve_block(__bytes, __thread_id); + } + return static_cast<_Tp*>(static_cast<void*>(__c)); + } + + template<typename _Tp, typename _Poolp> + void + __mt_alloc<_Tp, _Poolp>:: + deallocate(pointer __p, size_type __n) + { + if (__builtin_expect(__p != 0, true)) + { + // Requests larger than _M_max_bytes are handled by + // operators new/delete directly. + __pool_type& __pool = __policy_type::_S_get_pool(); + const size_t __bytes = __n * sizeof(_Tp); + if (__pool._M_check_threshold(__bytes)) + ::operator delete(__p); + else + __pool._M_reclaim_block(reinterpret_cast<char*>(__p), __bytes); + } + } + + template<typename _Tp, typename _Poolp> + inline bool + operator==(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&) + { return true; } + + template<typename _Tp, typename _Poolp> + inline bool + operator!=(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&) + { return false; } + +#undef __thread_default + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/new_allocator.h b/libstdc++/include/ext/new_allocator.h new file mode 100644 index 0000000..938783c --- /dev/null +++ b/libstdc++/include/ext/new_allocator.h @@ -0,0 +1,125 @@ +// Allocator that wraps operator new -*- C++ -*- + +// Copyright (C) 2001, 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. + +/** @file ext/new_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _NEW_ALLOCATOR_H +#define _NEW_ALLOCATOR_H 1 + +#include <new> +#include <bits/functexcept.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + + /** + * @brief An allocator that uses global new, as per [20.4]. + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls operator new + * - all deallocation calls operator delete + */ + template<typename _Tp> + class new_allocator + { + 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 new_allocator<_Tp1> other; }; + + new_allocator() throw() { } + + new_allocator(const new_allocator&) throw() { } + + template<typename _Tp1> + new_allocator(const new_allocator<_Tp1>&) throw() { } + + ~new_allocator() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + pointer + allocate(size_type __n, const void* = 0) + { + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); + + return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); + } + + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type) + { ::operator delete(__p); } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + + template<typename _Tp> + inline bool + operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return true; } + + template<typename _Tp> + inline bool + operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return false; } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/numeric b/libstdc++/include/ext/numeric new file mode 100644 index 0000000..290d032 --- /dev/null +++ b/libstdc++/include/ext/numeric @@ -0,0 +1,151 @@ +// Numeric extensions -*- C++ -*- + +// Copyright (C) 2002, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/numeric + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _EXT_NUMERIC +#define _EXT_NUMERIC 1 + +#pragma GCC system_header + +#include <bits/concept_check.h> +#include <numeric> + +#include <ext/functional> // For identity_element + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // Returns __x ** __n, where __n >= 0. _Note that "multiplication" + // is required to be associative, but not necessarily commutative. + template<typename _Tp, typename _Integer, typename _MonoidOperation> + _Tp + __power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) + { + if (__n == 0) + return identity_element(__monoid_op); + else + { + while ((__n & 1) == 0) + { + __n >>= 1; + __x = __monoid_op(__x, __x); + } + + _Tp __result = __x; + __n >>= 1; + while (__n != 0) + { + __x = __monoid_op(__x, __x); + if ((__n & 1) != 0) + __result = __monoid_op(__result, __x); + __n >>= 1; + } + return __result; + } + } + + template<typename _Tp, typename _Integer> + inline _Tp + __power(_Tp __x, _Integer __n) + { return __power(__x, __n, std::multiplies<_Tp>()); } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + // Alias for the internal name __power. Note that power is an extension, + // not part of the C++ standard. + template<typename _Tp, typename _Integer, typename _MonoidOperation> + inline _Tp + power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) + { return __power(__x, __n, __monoid_op); } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<typename _Tp, typename _Integer> + inline _Tp + power(_Tp __x, _Integer __n) + { return __power(__x, __n); } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + // iota is not part of the C++ standard. It is an extension. + template<typename _ForwardIter, typename _Tp> + void + iota(_ForwardIter __first, _ForwardIter __last, _Tp __value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename std::iterator_traits<_ForwardIter>::value_type>) + + while (__first != __last) + *__first++ = __value++; + } + +_GLIBCXX_END_NAMESPACE + +#endif + diff --git a/libstdc++/include/ext/numeric_traits.h b/libstdc++/include/ext/numeric_traits.h new file mode 100644 index 0000000..cff5b70 --- /dev/null +++ b/libstdc++/include/ext/numeric_traits.h @@ -0,0 +1,98 @@ +// -*- C++ -*- + +// Copyright (C) 2007 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. + +/** @file ext/numeric_traits.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _EXT_NUMERIC_TRAITS +#define _EXT_NUMERIC_TRAITS 1 + +#pragma GCC system_header + +#include <limits> +#include <bits/cpp_type_traits.h> +#include <ext/type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // Compile time constants for builtin types. + // Sadly std::numeric_limits member functions cannot be used for this. +#define __glibcxx_signed(_Tp) ((_Tp)(-1) < 0) +#define __glibcxx_digits(_Tp) \ + (sizeof(_Tp) * __CHAR_BIT__ - __glibcxx_signed(_Tp)) + +#define __glibcxx_min(_Tp) \ + (__glibcxx_signed(_Tp) ? (_Tp)1 << __glibcxx_digits(_Tp) : (_Tp)0) + +#define __glibcxx_max(_Tp) \ + (__glibcxx_signed(_Tp) ? \ + (((((_Tp)1 << (__glibcxx_digits(_Tp) - 1)) - 1) << 1) + 1) : ~(_Tp)0) + + template<typename _Value> + struct __numeric_traits_integer + { + // Only integers for initialization of member constant. + static const _Value __min = __glibcxx_min(_Value); + static const _Value __max = __glibcxx_max(_Value); + }; + + template<typename _Value> + const _Value __numeric_traits_integer<_Value>::__min; + + template<typename _Value> + const _Value __numeric_traits_integer<_Value>::__max; + + template<typename _Value> + struct __numeric_traits_floating + { + // Only floating point types. See N1822. + static const int __max_digits10 = + 2 + std::numeric_limits<_Value>::digits * 3010/10000; + }; + + template<typename _Value> + const int __numeric_traits_floating<_Value>::__max_digits10; + + template<typename _Value> + struct __numeric_traits + : public __conditional_type<std::__is_integer<_Value>::__value, + __numeric_traits_integer<_Value>, + __numeric_traits_floating<_Value> >::__type + { }; + +_GLIBCXX_END_NAMESPACE + +#undef __glibcxx_signed +#undef __glibcxx_min +#undef __glibcxx_max +#undef __glibcxx_digits + +#endif diff --git a/libstdc++/include/ext/pb_ds/assoc_container.hpp b/libstdc++/include/ext/pb_ds/assoc_container.hpp new file mode 100644 index 0000000..271cc76 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/assoc_container.hpp @@ -0,0 +1,689 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file assoc_container.hpp + * Contains associative containers. + */ + +#ifndef PB_DS_ASSOC_CNTNR_HPP +#define PB_DS_ASSOC_CNTNR_HPP + +#include <ext/typelist.h> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/standard_policies.hpp> +#include <ext/pb_ds/detail/container_base_dispatch.hpp> +#include <ext/pb_ds/detail/basic_tree_policy/traits.hpp> + +namespace pb_ds +{ +#define PB_DS_BASE_C_DEC \ + detail::container_base_dispatch<Key, Mapped, Tag, Policy_Tl, Allocator>::type + + // An abstract basic associative container. + template<typename Key, + typename Mapped, + typename Tag, + typename Policy_Tl, + typename Allocator> + class container_base : public PB_DS_BASE_C_DEC + { + private: + typedef typename PB_DS_BASE_C_DEC base_type; + + public: + typedef Tag container_category; + typedef Allocator allocator; + typedef typename allocator::size_type size_type; + typedef typename allocator::difference_type difference_type; + + // key_type + typedef typename allocator::template rebind<Key>::other::value_type key_type; + typedef typename allocator::template rebind<key_type>::other key_rebind; + typedef typename key_rebind::reference key_reference; + typedef typename key_rebind::const_reference const_key_reference; + typedef typename key_rebind::pointer key_pointer; + typedef typename key_rebind::const_pointer const_key_pointer; + + // mapped_type + typedef Mapped mapped_type; + typedef typename allocator::template rebind<mapped_type>::other mapped_rebind; + typedef typename mapped_rebind::reference mapped_reference; + typedef typename mapped_rebind::const_reference const_mapped_reference; + typedef typename mapped_rebind::pointer mapped_pointer; + typedef typename mapped_rebind::const_pointer const_mapped_pointer; + + // value_type + typedef typename base_type::value_type value_type; + typedef typename allocator::template rebind<value_type>::other value_rebind; + typedef typename value_rebind::reference reference; + typedef typename value_rebind::const_reference const_reference; + typedef typename value_rebind::pointer pointer; + typedef typename value_rebind::const_pointer const_pointer; + + // iterators + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_point_iterator const_point_iterator; + + virtual + ~container_base() { } + + protected: +#define PB_DS_CLASS_NAME container_base +#include <ext/pb_ds/detail/constructors_destructor_fn_imps.hpp> +#undef PB_DS_CLASS_NAME + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_BASE_C_DEC \ + container_base<Key, Mapped, Tag, typename __gnu_cxx::typelist::append< \ + typename __gnu_cxx::typelist::create4<Hash_Fn, Eq_Fn, Resize_Policy, detail::integral_constant<int, Store_Hash> >::type, Policy_TL>::type, Allocator> + + // An abstract basic hash-based associative container. + template<typename Key, + typename Mapped, + typename Hash_Fn, + typename Eq_Fn, + typename Resize_Policy, + bool Store_Hash, + typename Tag, + typename Policy_TL, + typename Allocator> + class basic_hash_table : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + virtual + ~basic_hash_table() { } + + protected: +#define PB_DS_CLASS_NAME basic_hash_table +#include <ext/pb_ds/detail/constructors_destructor_fn_imps.hpp> +#undef PB_DS_CLASS_NAME + + private: + basic_hash_table& + operator=(const base_type&); + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_BASE_C_DEC \ + basic_hash_table<Key, Mapped, Hash_Fn, Eq_Fn, Resize_Policy, Store_Hash, \ + cc_hash_tag, \ + typename __gnu_cxx::typelist::create1<Comb_Hash_Fn>::type, Allocator> + + // A concrete collision-chaining hash-based associative container. + template<typename Key, + typename Mapped, + typename Hash_Fn = typename detail::default_hash_fn<Key>::type, + typename Eq_Fn = typename detail::default_eq_fn<Key>::type, + typename Comb_Hash_Fn = detail::default_comb_hash_fn::type, + typename Resize_Policy = typename detail::default_resize_policy<Comb_Hash_Fn>::type, + bool Store_Hash = detail::default_store_hash, + typename Allocator = std::allocator<char> > + class cc_hash_table : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Hash_Fn hash_fn; + typedef Eq_Fn eq_fn; + typedef Resize_Policy resize_policy; + typedef Comb_Hash_Fn comb_hash_fn; + + // Default constructor. + cc_hash_table() { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the Hash_Fn object of the container object. + cc_hash_table(const hash_fn& h) + : base_type(h) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, and + // r_eq_fn will be copied by the eq_fn object of the container + // object. + cc_hash_table(const hash_fn& h, const eq_fn& e) + : base_type(h, e) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, and + // r_comb_hash_fn will be copied by the comb_hash_fn object of the + // container object. + cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch) + : base_type(h, e, ch) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, + // r_comb_hash_fn will be copied by the comb_hash_fn object of the + // container object, and r_resize_policy will be copied by the + // resize_policy object of the container object. + cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch, + const resize_policy& rp) + : base_type(h, e, ch, rp) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + cc_hash_table(It first, It last) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. + template<typename It> + cc_hash_table(It first, It last, const hash_fn& h) + : base_type(h) + { copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // and r_eq_fn will be copied by the eq_fn object of the container + // object. + template<typename It> + cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) + : base_type(h, e) + { copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, and r_comb_hash_fn will be copied by the comb_hash_fn + // object of the container object. + template<typename It> + cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_hash_fn& ch) + : base_type(h, e, ch) + { copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, r_comb_hash_fn will be copied by the comb_hash_fn + // object of the container object, and r_resize_policy will be + // copied by the resize_policy object of the container object. + template<typename It> + cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_hash_fn& ch, const resize_policy& rp) + : base_type(h, e, ch, rp) + { copy_from_range(first, last); } + + cc_hash_table(const cc_hash_table& other) + : base_type((const base_type&)other) + { } + + virtual + ~cc_hash_table() { } + + cc_hash_table& + operator=(const cc_hash_table& other) + { + if (this != &other) + { + cc_hash_table tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(cc_hash_table& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_BASE_C_DEC \ + basic_hash_table<Key, Mapped, Hash_Fn, Eq_Fn, Resize_Policy, Store_Hash, \ + gp_hash_tag, \ + typename __gnu_cxx::typelist::create2<Comb_Probe_Fn, Probe_Fn>::type, Allocator> + + // A concrete general-probing hash-based associative container. + template<typename Key, + typename Mapped, + typename Hash_Fn = typename detail::default_hash_fn<Key>::type, + typename Eq_Fn = typename detail::default_eq_fn<Key>::type, + typename Comb_Probe_Fn = detail::default_comb_hash_fn::type, + typename Probe_Fn = typename detail::default_probe_fn<Comb_Probe_Fn>::type, + typename Resize_Policy = typename detail::default_resize_policy<Comb_Probe_Fn>::type, + bool Store_Hash = detail::default_store_hash, + typename Allocator = std::allocator<char> > + class gp_hash_table : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Hash_Fn hash_fn; + typedef Eq_Fn eq_fn; + typedef Comb_Probe_Fn comb_probe_fn; + typedef Probe_Fn probe_fn; + typedef Resize_Policy resize_policy; + + // Default constructor. + gp_hash_table() { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object. + gp_hash_table(const hash_fn& h) + : base_type(h) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, and + // r_eq_fn will be copied by the eq_fn object of the container + // object. + gp_hash_table(const hash_fn& h, const eq_fn& e) + : base_type(h, e) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, and + // r_comb_probe_fn will be copied by the comb_probe_fn object of + // the container object. + gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp) + : base_type(h, e, cp) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, + // r_comb_probe_fn will be copied by the comb_probe_fn object of + // the container object, and r_probe_fn will be copied by the + // probe_fn object of the container object. + gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, + const probe_fn& p) + : base_type(h, e, cp, p) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, + // r_comb_probe_fn will be copied by the comb_probe_fn object of + // the container object, r_probe_fn will be copied by the probe_fn + // object of the container object, and r_resize_policy will be + // copied by the Resize_Policy object of the container object. + gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, + const probe_fn& p, const resize_policy& rp) + : base_type(h, e, cp, p, rp) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + gp_hash_table(It first, It last) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h) + : base_type(h) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // and r_eq_fn will be copied by the eq_fn object of the container + // object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) + : base_type(h, e) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, and r_comb_probe_fn will be copied by the comb_probe_fn + // object of the container object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_probe_fn& cp) + : base_type(h, e, cp) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, r_comb_probe_fn will be copied by the comb_probe_fn + // object of the container object, and r_probe_fn will be copied + // by the probe_fn object of the container object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_probe_fn& cp, const probe_fn& p) + : base_type(h, e, cp, p) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, r_comb_probe_fn will be copied by the comb_probe_fn + // object of the container object, r_probe_fn will be copied by + // the probe_fn object of the container object, and + // r_resize_policy will be copied by the resize_policy object of + // the container object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_probe_fn& cp, const probe_fn& p, + const resize_policy& rp) + : base_type(h, e, cp, p, rp) + { base_type::copy_from_range(first, last); } + + gp_hash_table(const gp_hash_table& other) + : base_type((const base_type&)other) + { } + + virtual + ~gp_hash_table() { } + + gp_hash_table& + operator=(const gp_hash_table& other) + { + if (this != &other) + { + gp_hash_table tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(gp_hash_table& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_BASE_C_DEC \ + container_base<Key, Mapped, Tag, Policy_Tl, Allocator> + + // An abstract basic tree-like (tree, trie) associative container. + template<typename Key, typename Mapped, typename Tag, + typename Node_Update, typename Policy_Tl, typename Allocator> + class basic_tree : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Node_Update node_update; + + virtual + ~basic_tree() { } + + protected: +#define PB_DS_CLASS_NAME basic_tree +#include <ext/pb_ds/detail/constructors_destructor_fn_imps.hpp> +#undef PB_DS_CLASS_NAME + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_TREE_NODE_AND_IT_TRAITS_C_DEC \ + detail::tree_traits<Key, Mapped,Cmp_Fn,Node_Update,Tag, Allocator> + +#define PB_DS_BASE_C_DEC \ + basic_tree<Key,Mapped,Tag,typename PB_DS_TREE_NODE_AND_IT_TRAITS_C_DEC::node_update, \ + typename __gnu_cxx::typelist::create2<Cmp_Fn, PB_DS_TREE_NODE_AND_IT_TRAITS_C_DEC >::type, Allocator> + + // A concrete basic tree-based associative container. + template<typename Key, typename Mapped, typename Cmp_Fn = std::less<Key>, + typename Tag = rb_tree_tag, + template<typename Const_Node_Iterator, typename Node_Iterator, typename Cmp_Fn_, typename Allocator_> + class Node_Update = pb_ds::null_tree_node_update, + typename Allocator = std::allocator<char> > + class tree : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + // Comparison functor type. + typedef Cmp_Fn cmp_fn; + + tree() { } + + // Constructor taking some policy objects. r_cmp_fn will be copied + // by the Cmp_Fn object of the container object. + tree(const cmp_fn& c) + : base_type(c) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + tree(It first, It last) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_cmp_fn + // will be copied by the cmp_fn object of the container object. + template<typename It> + tree(It first, It last, const cmp_fn& c) + : base_type(c) + { base_type::copy_from_range(first, last); } + + tree(const tree& other) + : base_type((const base_type&)other) { } + + virtual + ~tree() { } + + tree& + operator=(const tree& other) + { + if (this != &other) + { + tree tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(tree& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC +#undef PB_DS_TREE_NODE_AND_IT_TRAITS_C_DEC + + +#define PB_DS_TRIE_NODE_AND_ITS_TRAITS \ + detail::trie_traits<Key,Mapped,E_Access_Traits,Node_Update,Tag,Allocator> + +#define PB_DS_BASE_C_DEC \ + basic_tree<Key,Mapped,Tag, typename PB_DS_TRIE_NODE_AND_ITS_TRAITS::node_update, \ + typename __gnu_cxx::typelist::create2<E_Access_Traits, PB_DS_TRIE_NODE_AND_ITS_TRAITS >::type, Allocator> + + // A concrete basic trie-based associative container. + template<typename Key, + typename Mapped, + typename E_Access_Traits = typename detail::default_trie_e_access_traits<Key>::type, + typename Tag = pat_trie_tag, + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename E_Access_Traits_, + typename Allocator_> + class Node_Update = null_trie_node_update, + typename Allocator = std::allocator<char> > + class trie : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + // Element access traits type. + typedef E_Access_Traits e_access_traits; + + trie() { } + + // Constructor taking some policy objects. r_e_access_traits will + // be copied by the E_Access_Traits object of the container + // object. + trie(const e_access_traits& t) + : base_type(t) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + trie(It first, It last) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. + template<typename It> + trie(It first, It last, const e_access_traits& t) + : base_type(t) + { base_type::copy_from_range(first, last); } + + trie(const trie& other) + : base_type((const base_type&)other) { } + + virtual + ~trie() { } + + trie& + operator=(const trie& other) + { + if (this != &other) + { + trie tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(trie& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC +#undef PB_DS_TRIE_NODE_AND_ITS_TRAITS + + +#define PB_DS_BASE_C_DEC \ + container_base<Key, Mapped, list_update_tag, \ + typename __gnu_cxx::typelist::create2<Eq_Fn, Update_Policy>::type, Allocator> + + // A list-update based associative container. + template<typename Key, + typename Mapped, + class Eq_Fn = typename detail::default_eq_fn<Key>::type, + class Update_Policy = detail::default_update_policy::type, + class Allocator = std::allocator<char> > + class list_update : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Eq_Fn eq_fn; + typedef Update_Policy update_policy; + typedef Allocator allocator; + + list_update() { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + list_update(It first, It last) + { base_type::copy_from_range(first, last); } + + list_update(const list_update& other) + : base_type((const base_type&)other) { } + + virtual + ~list_update() { } + + list_update& + operator=(const list_update& other) + { + if (this !=& other) + { + list_update tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(list_update& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC + +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp b/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp new file mode 100644 index 0000000..d396d7d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp @@ -0,0 +1,179 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file basic_tree_policy_base.hpp + * Contains a base class for tree_like policies. + */ + +#ifndef PB_DS_TREE_LIKE_POLICY_BASE_HPP +#define PB_DS_TREE_LIKE_POLICY_BASE_HPP + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_C_DEC \ + basic_tree_policy_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + Allocator> + + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename Allocator> + struct basic_tree_policy_base + { + protected: + typedef typename Node_Iterator::value_type it_type; + + typedef typename std::iterator_traits< it_type>::value_type value_type; + + typedef typename value_type::first_type key_type; + + typedef + typename Allocator::template rebind< + typename remove_const< + key_type>::type>::other::const_reference + const_key_reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::const_reference + const_reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::const_pointer + const_pointer; + + static inline const_key_reference + extract_key(const_reference r_val) + { + return (r_val.first); + } + + virtual it_type + end() = 0; + + it_type + end_iterator() const + { + return (const_cast<PB_DS_CLASS_C_DEC* >(this)->end()); + } + + virtual + ~basic_tree_policy_base() + { } + }; + + template<typename Const_Node_Iterator, typename Allocator> + struct basic_tree_policy_base< + Const_Node_Iterator, + Const_Node_Iterator, + Allocator> + { + protected: + typedef typename Const_Node_Iterator::value_type it_type; + + typedef typename std::iterator_traits< it_type>::value_type value_type; + + typedef value_type key_type; + + typedef + typename Allocator::template rebind< + typename remove_const< + key_type>::type>::other::const_reference + const_key_reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::const_reference + const_reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::const_pointer + const_pointer; + + static inline const_key_reference + extract_key(const_reference r_val) + { + return (r_val); + } + + virtual it_type + end() const = 0; + + it_type + end_iterator() const + { + return (end()); + } + + virtual + ~basic_tree_policy_base() + { } + }; + +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_TREE_LIKE_POLICY_BASE_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp b/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp new file mode 100644 index 0000000..2399198 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp @@ -0,0 +1,73 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file null_node_metadata.hpp + * Contains an implementation class for tree-like classes. + */ + +#ifndef PB_DS_NULL_NODE_METADATA_HPP +#define PB_DS_NULL_NODE_METADATA_HPP + +#include <ext/pb_ds/detail/types_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, class Data, class Allocator> + struct dumconst_node_iterator + { + private: + typedef typename types_traits<Key, Data, Allocator, false>::pointer const_iterator; + + public: + typedef const_iterator value_type; + typedef const_iterator const_reference; + typedef const_reference reference; + }; + + struct null_node_metadata + { }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/traits.hpp b/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/traits.hpp new file mode 100644 index 0000000..c574bc0 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/traits.hpp @@ -0,0 +1,91 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation class for tree-like classes. + */ + +#ifndef PB_DS_NODE_AND_IT_TRAITS_HPP +#define PB_DS_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/traits.hpp> +#include <ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp> +#include <ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, + typename Data, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator> + class Node_Update, + class Tag, + class Allocator> + struct tree_traits; + + template<typename Key, + typename Data, + class E_Access_Traits, + template<typename Const_Node_Iterator, + class Node_Iterator, + class E_Access_Traits_, + class Allocator> + class Node_Update, + class Tag, + class Allocator> + struct trie_traits; + + } // namespace detail +} // namespace pb_ds + +#include <ext/pb_ds/detail/rb_tree_map_/traits.hpp> +#include <ext/pb_ds/detail/splay_tree_/traits.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/traits.hpp> +#include <ext/pb_ds/detail/pat_trie_/traits.hpp> + +#endif // #ifndef PB_DS_NODE_AND_IT_TRAITS_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/basic_types.hpp b/libstdc++/include/ext/pb_ds/detail/basic_types.hpp new file mode 100644 index 0000000..69288ce --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/basic_types.hpp @@ -0,0 +1,217 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file basic_types.hpp + * Contains basic types used by containers. + */ + +#ifndef PB_DS_BASIC_TYPES_HPP +#define PB_DS_BASIC_TYPES_HPP + +#include <algorithm> +#include <utility> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, typename Mapped, typename Allocator, bool Store_Hash> + struct value_type_base; + + /** + * Specialization of value_type_base for the case where the hash value + * is not stored alongside each value. + **/ + template<typename Key, typename Mapped, typename Allocator> + struct value_type_base<Key, Mapped, Allocator, false> + { + typedef typename Allocator::template rebind<Mapped>::other mapped_type_allocator; + typedef typename mapped_type_allocator::value_type mapped_type; + typedef typename mapped_type_allocator::pointer mapped_pointer; + typedef typename mapped_type_allocator::const_pointer const_mapped_pointer; + typedef typename mapped_type_allocator::reference mapped_reference; + typedef typename mapped_type_allocator::const_reference const_mapped_reference; + + typedef typename Allocator::template rebind<std::pair<const Key, Mapped> >::other value_type_allocator; + typedef typename value_type_allocator::value_type value_type; + typedef typename value_type_allocator::pointer pointer; + typedef typename value_type_allocator::const_pointer const_pointer; + typedef typename value_type_allocator::reference reference; + typedef typename value_type_allocator::const_reference const_reference; + + struct stored_value_type + { + value_type m_value; + }; + }; + + /** + * Specialization of value_type_base for the case where the hash value + * is stored alongside each value. + **/ + template<typename Key, typename Mapped, typename Allocator> + struct value_type_base<Key, Mapped, Allocator, true> + { + typedef typename Allocator::template rebind<Mapped>::other mapped_type_allocator; + typedef typename mapped_type_allocator::value_type mapped_type; + typedef typename mapped_type_allocator::pointer mapped_pointer; + typedef typename mapped_type_allocator::const_pointer const_mapped_pointer; + typedef typename mapped_type_allocator::reference mapped_reference; + typedef typename mapped_type_allocator::const_reference const_mapped_reference; + + typedef typename Allocator::template rebind<std::pair<const Key, Mapped> >::other value_type_allocator; + typedef typename value_type_allocator::value_type value_type; + typedef typename value_type_allocator::pointer pointer; + typedef typename value_type_allocator::const_pointer const_pointer; + typedef typename value_type_allocator::reference reference; + typedef typename value_type_allocator::const_reference const_reference; + + struct stored_value_type + { + value_type m_value; + typename Allocator::size_type m_hash; + }; + }; + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + value_type_base<Key, null_mapped_type, Allocator, false> + + /** + * Specialization of value_type_base for the case where the hash value + * is not stored alongside each value. + **/ + template<typename Key, typename Allocator> + struct value_type_base<Key, null_mapped_type, Allocator, false> + { + typedef typename Allocator::template rebind<null_mapped_type>::other mapped_type_allocator; + typedef typename mapped_type_allocator::value_type mapped_type; + typedef typename mapped_type_allocator::pointer mapped_pointer; + typedef typename mapped_type_allocator::const_pointer const_mapped_pointer; + typedef typename mapped_type_allocator::reference mapped_reference; + typedef typename mapped_type_allocator::const_reference const_mapped_reference; + + typedef Key value_type; + + typedef typename Allocator::template rebind<value_type>::other value_type_allocator; + typedef typename value_type_allocator::pointer pointer; + typedef typename value_type_allocator::const_pointer const_pointer; + typedef typename value_type_allocator::reference reference; + typedef typename value_type_allocator::const_reference const_reference; + + struct stored_value_type + { + value_type m_value; + }; + + static null_mapped_type s_null_mapped; + }; + + PB_DS_CLASS_T_DEC + null_mapped_type PB_DS_CLASS_C_DEC::s_null_mapped; + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + value_type_base<Key, null_mapped_type, Allocator, true> + + /** + * Specialization of value_type_base for the case where the hash value + * is stored alongside each value. + **/ + template<typename Key, typename Allocator> + struct value_type_base<Key, null_mapped_type, Allocator, true> + { + typedef typename Allocator::template rebind<null_mapped_type>::other mapped_type_allocator; + typedef typename mapped_type_allocator::value_type mapped_type; + typedef typename mapped_type_allocator::pointer mapped_pointer; + typedef typename mapped_type_allocator::const_pointer const_mapped_pointer; + typedef typename mapped_type_allocator::reference mapped_reference; + typedef typename mapped_type_allocator::const_reference const_mapped_reference; + + typedef Key value_type; + + typedef typename Allocator::template rebind<value_type>::other value_type_allocator; + typedef typename value_type_allocator::pointer pointer; + typedef typename value_type_allocator::const_pointer const_pointer; + typedef typename value_type_allocator::reference reference; + typedef typename value_type_allocator::const_reference const_reference; + + struct stored_value_type + { + value_type m_value; + typename Allocator::size_type m_hash; + }; + + static null_mapped_type s_null_mapped; + }; + + PB_DS_CLASS_T_DEC + null_mapped_type PB_DS_CLASS_C_DEC::s_null_mapped; + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + template<typename Key, typename Mapped> + struct no_throw_copies + { + typedef integral_constant<int, is_simple<Key>::value && is_simple<Mapped>::value> indicator; + }; + + template<typename Key> + struct no_throw_copies<Key, null_mapped_type> + { + typedef integral_constant<int, is_simple<Key>::value> indicator; + }; + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp new file mode 100644 index 0000000..fa0ff41 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp @@ -0,0 +1,503 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file bin_search_tree_.hpp + * Contains an implementation class for bin_search_tree_. + */ +/* + * This implementation uses an idea from the SGI STL (using a "header" node + * which is needed for efficient iteration). + */ + +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/detail/map_debug_base.hpp> +#include <ext/pb_ds/tree_policy.hpp> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/tree_trace_base.hpp> +#include <utility> +#include <functional> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, class Cmp_Fn, \ + class Node_And_It_Traits, class Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME \ + bin_search_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME \ + bin_search_tree_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME< \ + Key, \ + Mapped, \ + Cmp_Fn, \ + Node_And_It_Traits, \ + Allocator> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits< \ + Key, \ + Mapped, \ + Allocator, \ + false> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, eq_by_less<Key, Cmp_Fn>, \ + typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + +#ifdef PB_DS_TREE_TRACE +#define PB_DS_TREE_TRACE_BASE_C_DEC \ + tree_trace_base< \ + typename Node_And_It_Traits::const_node_iterator, \ + typename Node_And_It_Traits::node_iterator, \ + Cmp_Fn, \ + true, \ + Allocator> +#endif + + /** + * class description = "8i|\|4ree $34rc|-| 7r33 74813."> + **/ + template<typename Key, + typename Mapped, + class Cmp_Fn, + class Node_And_It_Traits, + class Allocator> + class PB_DS_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + public PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif +#ifdef PB_DS_TREE_TRACE + public PB_DS_TREE_TRACE_BASE_C_DEC, +#endif + public Cmp_Fn, + public PB_DS_TYPES_TRAITS_C_DEC, + public Node_And_It_Traits::node_update + { + + protected: + typedef + typename Allocator::template rebind< + typename Node_And_It_Traits::node>::other + node_allocator; + + typedef typename node_allocator::value_type node; + + typedef typename node_allocator::pointer node_pointer; + + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + + typedef + typename Node_And_It_Traits::null_node_update_pointer + null_node_update_pointer; + + private: + typedef cond_dealtor< node, Allocator> cond_dealtor_t; + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_type key_type; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_pointer key_pointer; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_key_pointer + const_key_pointer; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_reference key_reference; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_key_reference + const_key_reference; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef typename PB_DS_TYPES_TRAITS_C_DEC::mapped_type mapped_type; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::mapped_pointer + mapped_pointer; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_pointer + const_mapped_pointer; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::mapped_reference + mapped_reference; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_reference + const_mapped_reference; +#endif + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::value_type value_type; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::pointer pointer; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::const_pointer const_pointer; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::reference reference; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_reference + const_reference; + + typedef + typename Node_And_It_Traits::const_point_iterator + const_point_iterator; + + typedef const_point_iterator const_iterator; + + typedef typename Node_And_It_Traits::point_iterator point_iterator; + + typedef point_iterator iterator; + + typedef + typename Node_And_It_Traits::const_reverse_iterator + const_reverse_iterator; + + typedef typename Node_And_It_Traits::reverse_iterator reverse_iterator; + + typedef + typename Node_And_It_Traits::const_node_iterator + const_node_iterator; + + typedef typename Node_And_It_Traits::node_iterator node_iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + typedef typename Node_And_It_Traits::node_update node_update; + + public: + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn); + + PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_update); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~PB_DS_CLASS_NAME(); + + inline bool + empty() const; + + inline size_type + size() const; + + inline size_type + max_size() const; + + Cmp_Fn& + get_cmp_fn(); + + const Cmp_Fn& + get_cmp_fn() const; + + inline point_iterator + lower_bound(const_key_reference r_key); + + inline const_point_iterator + lower_bound(const_key_reference r_key) const; + + inline point_iterator + upper_bound(const_key_reference r_key); + + inline const_point_iterator + upper_bound(const_key_reference r_key) const; + + inline point_iterator + find(const_key_reference r_key); + + inline const_point_iterator + find(const_key_reference r_key) const; + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + + inline reverse_iterator + rbegin(); + + inline const_reverse_iterator + rbegin() const; + + inline reverse_iterator + rend(); + + inline const_reverse_iterator + rend() const; + + inline const_node_iterator + node_begin() const; + + inline node_iterator + node_begin(); + + inline const_node_iterator + node_end() const; + + inline node_iterator + node_end(); + + void + clear(); + + protected: + + void + value_swap(PB_DS_CLASS_C_DEC& other); + + void + initialize_min_max(); + + inline iterator + insert_imp_empty(const_reference r_value); + + inline iterator + insert_leaf_new(const_reference r_value, node_pointer p_nd, bool left_nd); + + inline node_pointer + get_new_node_for_leaf_insert(const_reference r_val, false_type); + + inline node_pointer + get_new_node_for_leaf_insert(const_reference r_val, true_type); + + inline void + actual_erase_node(node_pointer p_nd); + + inline std::pair<node_pointer, bool> + erase(node_pointer p_nd); + + inline void + update_min_max_for_erased_node(node_pointer p_nd); + + static void + clear_imp(node_pointer p_nd); + + inline std::pair< + point_iterator, + bool> + insert_leaf(const_reference r_value); + + inline void + rotate_left(node_pointer p_x); + + inline void + rotate_right(node_pointer p_y); + + inline void + rotate_parent(node_pointer p_nd); + + inline void + apply_update(node_pointer p_nd, null_node_update_pointer); + + template<typename Node_Update_> + inline void + apply_update(node_pointer p_nd, Node_Update_* p_update); + + inline void + update_to_top(node_pointer p_nd, null_node_update_pointer); + + template<typename Node_Update_> + inline void + update_to_top(node_pointer p_nd, Node_Update_* p_update); + + bool + join_prep(PB_DS_CLASS_C_DEC& other); + + void + join_finish(PB_DS_CLASS_C_DEC& other); + + bool + split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other); + + void + split_finish(PB_DS_CLASS_C_DEC& other); + + size_type + recursive_count(node_pointer p_nd) const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + structure_only_assert_valid() const; + + void + assert_node_consistent(const node_pointer p_nd) const; +#endif + + private: +#ifdef _GLIBCXX_DEBUG + void + assert_iterators() const; + + void + assert_consistent_with_debug_base() const; + + void + assert_node_consistent_with_left(const node_pointer p_nd) const; + + void + assert_node_consistent_with_right(const node_pointer p_nd) const; + + void + assert_consistent_with_debug_base(const node_pointer p_nd) const; + + void + assert_min() const; + + void + assert_min_imp(const node_pointer p_nd) const; + + void + assert_max() const; + + void + assert_max_imp(const node_pointer p_nd) const; + + void + assert_size() const; + + typedef std::pair< const_pointer, const_pointer> node_consistent_t; + + node_consistent_t + assert_node_consistent_(const node_pointer p_nd) const; +#endif + + void + initialize(); + + node_pointer + recursive_copy_node(const node_pointer p_nd); + + protected: + node_pointer m_p_head; + + size_type m_size; + + static node_allocator s_node_allocator; + }; + +#include <ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_CLASS_NAME + +#undef PB_DS_TYPES_TRAITS_C_DEC + +#undef PB_DS_MAP_DEBUG_BASE_C_DEC + +#ifdef PB_DS_TREE_TRACE +#undef PB_DS_TREE_TRACE_BASE_C_DEC +#endif + +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S + + } // namespace detail +} // namespace pb_ds diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_dtor_entry_dealtor.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_dtor_entry_dealtor.hpp new file mode 100644 index 0000000..d14d7bf --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_dtor_entry_dealtor.hpp @@ -0,0 +1,76 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_dtor_entry_dealtor.hpp + * Contains a binary tree container conditional deallocator + */ + +class bin_search_tree_cond_dtor_entry_dealtor_ +{ +public: + inline + bin_search_tree_cond_dtor_entry_dealtor_(node_pointer p_nd) : m_p_nd(p_nd), + m_no_action_dtor(false) + { } + + inline void + set_no_action_dtor() + { + m_no_action_dtor = true; + } + + inline + ~bin_search_tree_cond_dtor_entry_dealtor_() + { + if (m_no_action_dtor) + return; + + typename Allocator::template rebind<Node>::other(). + deallocate(m_p_nd, 1); + } + +protected: + node_pointer m_p_nd; + + bool m_no_action_dtor; +}; + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_key_dtor_entry_dealtor.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_key_dtor_entry_dealtor.hpp new file mode 100644 index 0000000..5373e54 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_key_dtor_entry_dealtor.hpp @@ -0,0 +1,87 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_key_dtor_entry_dealtor.hpp + * Contains a binary tree container conditional deallocator + */ + +class bin_seach_tree_cond_key_dtor_entry_dealtor_ +{ +public: + inline + bin_seach_tree_cond_key_dtor_entry_dealtor_(node_pointer p_nd) : m_p_nd(p_nd), + m_no_action_dtor(false), + m_key_destruct(false) + { } + + inline void + set_no_action_dtor() + { + m_no_action_dtor = true; + } + + inline void + set_key_destruct() + { + m_key_destruct = true; + } + + inline + ~bin_seach_tree_cond_key_dtor_entry_dealtor_() + { + if (m_no_action_dtor) + return; + + if (m_key_destruct) + m_p_nd->m_value.first.~Key(); + + bin_tree_base::s_alloc.deallocate(m_p_nd, 1); + } + +protected: + node_pointer m_p_nd; + + bool m_no_action_dtor; + + bool m_key_destruct; +}; + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..a6ee920 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,224 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_allocator +PB_DS_CLASS_C_DEC::s_node_allocator; + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() : m_p_head(s_node_allocator.allocate(1)), m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn) : + Cmp_Fn(r_cmp_fn), m_p_head(s_node_allocator.allocate(1)), m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : + Cmp_Fn(r_cmp_fn), + node_update(r_node_update), + m_p_head(s_node_allocator.allocate(1)), + m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif +#ifdef PB_DS_TREE_TRACE + PB_DS_TREE_TRACE_BASE_C_DEC(other), +#endif + Cmp_Fn(other), + node_update(other), + m_p_head(s_node_allocator.allocate(1)), + m_size(0) +{ + initialize(); + m_size = other.m_size; + _GLIBCXX_DEBUG_ONLY(other.structure_only_assert_valid();) + + try + { + m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); + if (m_p_head->m_p_parent != NULL) + m_p_head->m_p_parent->m_p_parent = m_p_head; + m_size = other.m_size; + initialize_min_max(); + } + catch(...) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + s_node_allocator.deallocate(m_p_head, 1); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.structure_only_assert_valid();) + value_swap(other); + std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other);) + std::swap(m_p_head, other.m_p_head); + std::swap(m_size, other.m_size); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ + clear(); + s_node_allocator.deallocate(m_p_head, 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ + m_p_head->m_p_parent = NULL; + m_p_head->m_p_left = m_p_head; + m_p_head->m_p_right = m_p_head; + m_size = 0; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +recursive_copy_node(const node_pointer p_nd) +{ + if (p_nd == NULL) + return (NULL); + + node_pointer p_ret = s_node_allocator.allocate(1); + try + { + new (p_ret) node(*p_nd); + } + catch(...) + { + s_node_allocator.deallocate(p_ret, 1); + __throw_exception_again; + } + + p_ret->m_p_left = p_ret->m_p_right = NULL; + + try + { + p_ret->m_p_left = recursive_copy_node(p_nd->m_p_left); + p_ret->m_p_right = recursive_copy_node(p_nd->m_p_right); + } + catch(...) + { + clear_imp(p_ret); + __throw_exception_again; + } + + if (p_ret->m_p_left != NULL) + p_ret->m_p_left->m_p_parent = p_ret; + + if (p_ret->m_p_right != NULL) + p_ret->m_p_right->m_p_parent = p_ret; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_ret);) + return p_ret; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize_min_max() +{ + if (m_p_head->m_p_parent == NULL) + { + m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; + return; + } + + { + node_pointer p_min = m_p_head->m_p_parent; + while (p_min->m_p_left != NULL) + p_min = p_min->m_p_left; + m_p_head->m_p_left = p_min; + } + + { + node_pointer p_max = m_p_head->m_p_parent; + while (p_max->m_p_right != NULL) + p_max = p_max->m_p_right; + m_p_head->m_p_right = p_max; + } +} + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp new file mode 100644 index 0000000..eff970a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp @@ -0,0 +1,278 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + structure_only_assert_valid(); + assert_consistent_with_debug_base(); + assert_size(); + assert_iterators(); + if (m_p_head->m_p_parent == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_size == 0); + } + else + { + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +structure_only_assert_valid() const +{ + _GLIBCXX_DEBUG_ASSERT(m_p_head != NULL); + if (m_p_head->m_p_parent == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_left == m_p_head); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_right == m_p_head); + } + else + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent->m_p_parent == m_p_head); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_left != m_p_head); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_right != m_p_head); + } + + if (m_p_head->m_p_parent != NULL) + assert_node_consistent(m_p_head->m_p_parent); + assert_min(); + assert_max(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const node_pointer p_nd) const +{ + assert_node_consistent_(p_nd); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_consistent_t +PB_DS_CLASS_C_DEC:: +assert_node_consistent_(const node_pointer p_nd) const +{ + if (p_nd == NULL) + return (std::make_pair((const_pointer)NULL,(const_pointer)NULL)); + + assert_node_consistent_with_left(p_nd); + assert_node_consistent_with_right(p_nd); + + const std::pair<const_pointer, const_pointer> + l_range = assert_node_consistent_(p_nd->m_p_left); + + if (l_range.second != NULL) + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(*l_range.second), + PB_DS_V2F(p_nd->m_value))); + + const std::pair<const_pointer, const_pointer> + r_range = assert_node_consistent_(p_nd->m_p_right); + + if (r_range.first != NULL) + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), + PB_DS_V2F(*r_range.first))); + + return (std::make_pair((l_range.first != NULL)? l_range.first :& p_nd->m_value,(r_range.second != NULL)? r_range.second :& p_nd->m_value)); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent_with_left(const node_pointer p_nd) const +{ + if (p_nd->m_p_left == NULL) + return; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left->m_p_parent == p_nd); + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), + PB_DS_V2F(p_nd->m_p_left->m_value))); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent_with_right(const node_pointer p_nd) const +{ + if (p_nd->m_p_right == NULL) + return; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_right->m_p_parent == p_nd); + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_p_right->m_value), + PB_DS_V2F(p_nd->m_value))); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_min() const +{ + assert_min_imp(m_p_head->m_p_parent); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_min_imp(const node_pointer p_nd) const +{ + if (p_nd == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_left == m_p_head); + return; + } + + if (p_nd->m_p_left == NULL) + { + _GLIBCXX_DEBUG_ASSERT(p_nd == m_p_head->m_p_left); + return; + } + assert_min_imp(p_nd->m_p_left); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_max() const +{ + assert_max_imp(m_p_head->m_p_parent); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_max_imp(const node_pointer p_nd) const +{ + if (p_nd == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_right == m_p_head); + return; + } + + if (p_nd->m_p_right == NULL) + { + _GLIBCXX_DEBUG_ASSERT(p_nd == m_p_head->m_p_right); + return; + } + + assert_max_imp(p_nd->m_p_right); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_iterators() const +{ + size_type iterated_num = 0; + const_iterator prev_it = end(); + for (const_iterator it = begin(); it != end(); ++it) + { + ++iterated_num; + _GLIBCXX_DEBUG_ASSERT(lower_bound(PB_DS_V2F(*it)).m_p_nd == it.m_p_nd); + const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); + --upper_bound_it; + _GLIBCXX_DEBUG_ASSERT(upper_bound_it.m_p_nd == it.m_p_nd); + + if (prev_it != end()) + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), + PB_DS_V2F(*it))); + prev_it = it; + } + + _GLIBCXX_DEBUG_ASSERT(iterated_num == m_size); + size_type reverse_iterated_num = 0; + const_reverse_iterator reverse_prev_it = rend(); + for (const_reverse_iterator reverse_it = rbegin(); reverse_it != rend(); + ++reverse_it) + { + ++reverse_iterated_num; + _GLIBCXX_DEBUG_ASSERT(lower_bound( + PB_DS_V2F(*reverse_it)).m_p_nd == reverse_it.m_p_nd); + + const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*reverse_it)); + --upper_bound_it; + _GLIBCXX_DEBUG_ASSERT(upper_bound_it.m_p_nd == reverse_it.m_p_nd); + if (reverse_prev_it != rend()) + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(PB_DS_V2F(*reverse_prev_it), + PB_DS_V2F(*reverse_it))); + reverse_prev_it = reverse_it; + } + _GLIBCXX_DEBUG_ASSERT(reverse_iterated_num == m_size); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_consistent_with_debug_base() const +{ + map_debug_base::check_size(m_size); + assert_consistent_with_debug_base(m_p_head->m_p_parent); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_consistent_with_debug_base(const node_pointer p_nd) const +{ + if (p_nd == NULL) + return; + map_debug_base::check_key_exists(PB_DS_V2F(p_nd->m_value)); + assert_consistent_with_debug_base(p_nd->m_p_left); + assert_consistent_with_debug_base(p_nd->m_p_right); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_size() const +{ + _GLIBCXX_DEBUG_ASSERT(recursive_count(m_p_head->m_p_parent) == m_size); +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp new file mode 100644 index 0000000..2006a82 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp @@ -0,0 +1,126 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_node(node_pointer p_z) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + + _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value))); + + p_z->~node(); + + s_node_allocator.deallocate(p_z, 1); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_min_max_for_erased_node(node_pointer p_z) +{ + if (m_size == 1) + { + m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; + + return; + } + + if (m_p_head->m_p_left == p_z) + { + iterator it(p_z); + + ++it; + + m_p_head->m_p_left = it.m_p_nd; + } + else if (m_p_head->m_p_right == p_z) + { + iterator it(p_z); + + --it; + + m_p_head->m_p_right = it.m_p_nd; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + clear_imp(m_p_head->m_p_parent); + + m_size = 0; + + initialize(); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + if (p_nd == NULL) + return; + + clear_imp(p_nd->m_p_left); + + clear_imp(p_nd->m_p_right); + + p_nd->~node(); + + s_node_allocator.deallocate(p_nd, 1); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp new file mode 100644 index 0000000..5f534d1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp @@ -0,0 +1,188 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +lower_bound(const_key_reference r_key) const +{ + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (Cmp_Fn::operator()( + PB_DS_V2F(p_nd->m_value), + r_key)) + p_nd = p_nd->m_p_right; + else + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + + return (iterator(p_pot)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +lower_bound(const_key_reference r_key) +{ + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (Cmp_Fn::operator()( + PB_DS_V2F(p_nd->m_value), + r_key)) + p_nd = p_nd->m_p_right; + else + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + + return (iterator(p_pot)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +upper_bound(const_key_reference r_key) const +{ + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (Cmp_Fn::operator()(r_key, + PB_DS_V2F(p_nd->m_value))) + { + p_pot = p_nd, + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + return (const_iterator(p_pot)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +upper_bound(const_key_reference r_key) +{ + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (Cmp_Fn::operator()(r_key, + PB_DS_V2F(p_nd->m_value))) + { + p_pot = p_nd, + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + return (point_iterator(p_pot)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + return point_iterator((p_pot != m_p_head&& Cmp_Fn::operator()( + r_key, + PB_DS_V2F(p_pot->m_value)))? + m_p_head : p_pot); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + return const_point_iterator((p_pot != m_p_head&& Cmp_Fn::operator()( + r_key, + PB_DS_V2F(p_pot->m_value)))? + m_p_head : p_pot); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp new file mode 100644 index 0000000..4381efe --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp @@ -0,0 +1,70 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ + return (m_size == 0); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ + return (m_size); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ + return (s_node_allocator.max_size()); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp new file mode 100644 index 0000000..91fe41a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp @@ -0,0 +1,217 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_leaf(const_reference r_value) +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + if (m_size == 0) + return (std::make_pair( + insert_imp_empty(r_value), + true)); + + node_pointer p_nd = m_p_head->m_p_parent; + node_pointer p_pot = m_p_head; + + while (p_nd != NULL) + if (!Cmp_Fn::operator()( + PB_DS_V2F(p_nd->m_value), + PB_DS_V2F(r_value))) + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + if (p_pot == m_p_head) + return (std::make_pair( + insert_leaf_new(r_value, m_p_head->m_p_right, false), + true)); + + if (!Cmp_Fn::operator()( + PB_DS_V2F(r_value), + PB_DS_V2F(p_pot->m_value))) + { + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists( + PB_DS_V2F(r_value))); + + return (std::make_pair(p_pot, false)); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist( + PB_DS_V2F(r_value))); + + p_nd = p_pot->m_p_left; + if (p_nd == NULL) + return (std::make_pair( + insert_leaf_new(r_value, p_pot, true), + true)); + + while (p_nd->m_p_right != NULL) + p_nd = p_nd->m_p_right; + + return (std::make_pair( + insert_leaf_new(r_value, p_nd, false), + true)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +insert_leaf_new(const_reference r_value, node_pointer p_nd, bool left_nd) +{ + node_pointer p_new_nd = + get_new_node_for_leaf_insert( r_value, traits_base::m_no_throw_copies_indicator); + + if (left_nd) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == NULL); + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()( + PB_DS_V2F(r_value), + PB_DS_V2F(p_nd->m_value))); + + p_nd->m_p_left = p_new_nd; + + if (m_p_head->m_p_left == p_nd) + m_p_head->m_p_left = p_new_nd; + } + else + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_right == NULL); + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()( + PB_DS_V2F(p_nd->m_value), + PB_DS_V2F(r_value))); + + p_nd->m_p_right = p_new_nd; + + if (m_p_head->m_p_right == p_nd) + m_p_head->m_p_right = p_new_nd; + } + + p_new_nd->m_p_parent = p_nd; + + p_new_nd->m_p_left = p_new_nd->m_p_right = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_nd)); + + update_to_top(p_new_nd, (node_update* )this); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new( + PB_DS_V2F(r_value))); + + return (iterator(p_new_nd)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +insert_imp_empty(const_reference r_value) +{ + node_pointer p_new_node = + get_new_node_for_leaf_insert( r_value, traits_base::m_no_throw_copies_indicator); + + m_p_head->m_p_left = m_p_head->m_p_right = + m_p_head->m_p_parent = p_new_node; + + p_new_node->m_p_parent = m_p_head; + + p_new_node->m_p_left = p_new_node->m_p_right = NULL; + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new( + PB_DS_V2F(r_value))); + + update_to_top(m_p_head->m_p_parent, (node_update* )this); + + return (iterator(p_new_node)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_leaf_insert(const_reference r_val, false_type) +{ + node_pointer p_new_nd = s_node_allocator.allocate(1); + + cond_dealtor_t cond(p_new_nd); + + new (const_cast<void* >( + static_cast<const void* >(&p_new_nd->m_value))) + typename node::value_type(r_val); + + cond.set_no_action(); + + p_new_nd->m_p_left = p_new_nd->m_p_right = NULL; + + ++m_size; + + return (p_new_nd); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_leaf_insert(const_reference r_val, true_type) +{ + node_pointer p_new_nd = s_node_allocator.allocate(1); + + new (const_cast<void* >( + static_cast<const void* >(&p_new_nd->m_value))) + typename node::value_type(r_val); + + p_new_nd->m_p_left = p_new_nd->m_p_right = NULL; + + ++m_size; + + return (p_new_nd); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp new file mode 100644 index 0000000..3132a42 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp @@ -0,0 +1,142 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + return (iterator(m_p_head->m_p_left)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + return (const_iterator(m_p_head->m_p_left)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ + return (iterator(m_p_head)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ + return (const_iterator(m_p_head)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +rbegin() const +{ + return (const_reverse_iterator(m_p_head->m_p_right)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +rbegin() +{ + return (reverse_iterator(m_p_head->m_p_right)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +rend() +{ + return (reverse_iterator(m_p_head)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +rend() const +{ + return (const_reverse_iterator(m_p_head)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() const +{ + return (const_node_iterator(m_p_head->m_p_parent)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() +{ + return (node_iterator(m_p_head->m_p_parent)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_end() const +{ + return (const_node_iterator(NULL)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_end() +{ + return (node_iterator(NULL)); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp new file mode 100644 index 0000000..ce1cd22 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp @@ -0,0 +1,243 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_iterators.hpp + * Contains an implementation class for bin_search_tree_. + */ + +#ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP +#define PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC \ + bin_search_tree_const_node_it_< \ + Node, \ + Const_Iterator, \ + Iterator, \ + Allocator> + + // Const node iterator. + template<typename Node, + class Const_Iterator, + class Iterator, + class Allocator> + class bin_search_tree_const_node_it_ + { + private: + + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + public: + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // __Iterator's value type. + typedef Const_Iterator value_type; + + // __Iterator's reference type. + typedef Const_Iterator reference; + + // __Iterator's __const reference type. + typedef Const_Iterator const_reference; + + // Metadata type. + typedef typename Node::metadata_type metadata_type; + + // Const metadata reference type. + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + public: + + // Default constructor. + /* + inline + bin_search_tree_const_node_it_() + */ + + inline + bin_search_tree_const_node_it_(const node_pointer p_nd = NULL) : m_p_nd(const_cast<node_pointer>(p_nd)) + { } + + // Access. + inline const_reference + operator*() const + { + return (Const_Iterator(m_p_nd)); + } + + // Metadata access. + inline const_metadata_reference + get_metadata() const + { + return (m_p_nd->get_metadata()); + } + + // Returns the __const node iterator associated with the left node. + inline PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC + get_l_child() const + { + return (PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_left)); + } + + // Returns the __const node iterator associated with the right node. + inline PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC + get_r_child() const + { + return (PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_right)); + } + + // Compares to a different iterator object. + inline bool + operator==(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const + { + return (m_p_nd == other.m_p_nd); + } + + // Compares (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const + { + return (m_p_nd != other.m_p_nd); + } + + public: + node_pointer m_p_nd; + }; + +#define PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC \ + bin_search_tree_node_it_< \ + Node, \ + Const_Iterator, \ + Iterator, \ + Allocator> + + // Node iterator. + template<typename Node, + class Const_Iterator, + class Iterator, + class Allocator> + class bin_search_tree_node_it_ : + public PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC + + { + + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + public: + + // __Iterator's value type. + typedef Iterator value_type; + + // __Iterator's reference type. + typedef Iterator reference; + + // __Iterator's __const reference type. + typedef Iterator const_reference; + + public: + + // Default constructor. + /* + inline + bin_search_tree_node_it_(); + */ + + inline + bin_search_tree_node_it_(const node_pointer p_nd = NULL) : PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC( + const_cast<node_pointer>(p_nd)) + { } + + // Access. + inline Iterator + operator*() const + { + return (Iterator(PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd)); + } + + // Returns the node iterator associated with the left node. + inline PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC + get_l_child() const + { + return (PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( + PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_left)); + } + + // Returns the node iterator associated with the right node. + inline PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC + get_r_child() const + { + return (PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( + PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_right)); + } + + }; + +#undef PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC + +#undef PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp new file mode 100644 index 0000000..275177e --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp @@ -0,0 +1,387 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file point_iterators.hpp + * Contains an implementation class for bin_search_tree_. + */ + +#ifndef PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP +#define PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_TREE_CONST_IT_C_DEC \ + bin_search_tree_const_it_< \ + Node_Pointer, \ + Value_Type, \ + Pointer, \ + Const_Pointer, \ + Reference, \ + Const_Reference, \ + Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_TREE_CONST_ODIR_IT_C_DEC \ + bin_search_tree_const_it_< \ + Node_Pointer, \ + Value_Type, \ + Pointer, \ + Const_Pointer, \ + Reference, \ + Const_Reference, \ + !Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_TREE_IT_C_DEC \ + bin_search_tree_it_< \ + Node_Pointer, \ + Value_Type, \ + Pointer, \ + Const_Pointer, \ + Reference, \ + Const_Reference, \ + Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_TREE_ODIR_IT_C_DEC \ + bin_search_tree_it_< \ + Node_Pointer, \ + Value_Type, \ + Pointer, \ + Const_Pointer, \ + Reference, \ + Const_Reference, \ + !Is_Forward_Iterator, \ + Allocator> + + // Const iterator. + template<typename Node_Pointer, + typename Value_Type, + typename Pointer, + typename Const_Pointer, + typename Reference, + typename Const_Reference, + bool Is_Forward_Iterator, + class Allocator> + class bin_search_tree_const_it_ + { + + public: + + typedef std::bidirectional_iterator_tag iterator_category; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef Pointer pointer; + + typedef Const_Pointer const_pointer; + + typedef Reference reference; + + typedef Const_Reference const_reference; + + public: + + inline + bin_search_tree_const_it_(const Node_Pointer p_nd = NULL) + : m_p_nd(const_cast<Node_Pointer>(p_nd)) + { } + + inline + bin_search_tree_const_it_(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) + : m_p_nd(other.m_p_nd) + { } + + inline + PB_DS_TREE_CONST_IT_C_DEC& + operator=(const PB_DS_TREE_CONST_IT_C_DEC& other) + { + m_p_nd = other.m_p_nd; + return *this; + } + + inline + PB_DS_TREE_CONST_IT_C_DEC& + operator=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) + { + m_p_nd = other.m_p_nd; + return *this; + } + + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + return &m_p_nd->m_value; + } + + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + return m_p_nd->m_value; + } + + inline bool + operator==(const PB_DS_TREE_CONST_IT_C_DEC & other) const + { return m_p_nd == other.m_p_nd; } + + inline bool + operator==(const PB_DS_TREE_CONST_ODIR_IT_C_DEC & other) const + { return m_p_nd == other.m_p_nd; } + + inline bool + operator!=(const PB_DS_TREE_CONST_IT_C_DEC& other) const + { return m_p_nd != other.m_p_nd; } + + inline bool + operator!=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) const + { return m_p_nd != other.m_p_nd; } + + inline PB_DS_TREE_CONST_IT_C_DEC& + operator++() + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + inc(integral_constant<int,Is_Forward_Iterator>()); + return *this; + } + + inline PB_DS_TREE_CONST_IT_C_DEC + operator++(int) + { + PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); + operator++(); + return ret_it; + } + + inline PB_DS_TREE_CONST_IT_C_DEC& + operator--() + { + dec(integral_constant<int,Is_Forward_Iterator>()); + return *this; + } + + inline PB_DS_TREE_CONST_IT_C_DEC + operator--(int) + { + PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); + operator--(); + return ret_it; + } + + protected: + inline void + inc(false_type) + { dec(true_type()); } + + void + inc(true_type) + { + if (m_p_nd->special()&& + m_p_nd->m_p_parent->m_p_parent == m_p_nd) + { + m_p_nd = m_p_nd->m_p_left; + return; + } + + if (m_p_nd->m_p_right != NULL) + { + m_p_nd = m_p_nd->m_p_right; + while (m_p_nd->m_p_left != NULL) + m_p_nd = m_p_nd->m_p_left; + return; + } + + Node_Pointer p_y = m_p_nd->m_p_parent; + while (m_p_nd == p_y->m_p_right) + { + m_p_nd = p_y; + p_y = p_y->m_p_parent; + } + + if (m_p_nd->m_p_right != p_y) + m_p_nd = p_y; + } + + inline void + dec(false_type) + { inc(true_type()); } + + void + dec(true_type) + { + if (m_p_nd->special() && m_p_nd->m_p_parent->m_p_parent == m_p_nd) + { + m_p_nd = m_p_nd->m_p_right; + return; + } + + if (m_p_nd->m_p_left != NULL) + { + Node_Pointer p_y = m_p_nd->m_p_left; + while (p_y->m_p_right != NULL) + p_y = p_y->m_p_right; + m_p_nd = p_y; + return; + } + + Node_Pointer p_y = m_p_nd->m_p_parent; + while (m_p_nd == p_y->m_p_left) + { + m_p_nd = p_y; + p_y = p_y->m_p_parent; + } + if (m_p_nd->m_p_left != p_y) + m_p_nd = p_y; + } + + public: + Node_Pointer m_p_nd; + }; + + // Iterator. + template<typename Node_Pointer, + typename Value_Type, + typename Pointer, + typename Const_Pointer, + typename Reference, + typename Const_Reference, + bool Is_Forward_Iterator, + class Allocator> + class bin_search_tree_it_ : + public PB_DS_TREE_CONST_IT_C_DEC + + { + + public: + + inline + bin_search_tree_it_(const Node_Pointer p_nd = NULL) + : PB_DS_TREE_CONST_IT_C_DEC((Node_Pointer)p_nd) + { } + + inline + bin_search_tree_it_(const PB_DS_TREE_ODIR_IT_C_DEC& other) + : PB_DS_TREE_CONST_IT_C_DEC(other.m_p_nd) + { } + + inline + PB_DS_TREE_IT_C_DEC& + operator=(const PB_DS_TREE_IT_C_DEC& other) + { + base_it_type::m_p_nd = other.m_p_nd; + return *this; + } + + inline + PB_DS_TREE_IT_C_DEC& + operator=(const PB_DS_TREE_ODIR_IT_C_DEC& other) + { + base_it_type::m_p_nd = other.m_p_nd; + return *this; + } + + inline typename PB_DS_TREE_CONST_IT_C_DEC::pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != NULL); + return &base_it_type::m_p_nd->m_value; + } + + inline typename PB_DS_TREE_CONST_IT_C_DEC::reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != NULL); + return base_it_type::m_p_nd->m_value; + } + + inline PB_DS_TREE_IT_C_DEC& + operator++() + { + PB_DS_TREE_CONST_IT_C_DEC:: operator++(); + return *this; + } + + inline PB_DS_TREE_IT_C_DEC + operator++(int) + { + PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); + operator++(); + return ret_it; + } + + inline PB_DS_TREE_IT_C_DEC& + operator--() + { + PB_DS_TREE_CONST_IT_C_DEC:: operator--(); + return *this; + } + + inline PB_DS_TREE_IT_C_DEC + operator--(int) + { + PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); + operator--(); + return ret_it; + } + + protected: + typedef PB_DS_TREE_CONST_IT_C_DEC base_it_type; + }; + +#undef PB_DS_TREE_CONST_IT_C_DEC +#undef PB_DS_TREE_CONST_ODIR_IT_C_DEC +#undef PB_DS_TREE_IT_C_DEC +#undef PB_DS_TREE_ODIR_IT_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp new file mode 100644 index 0000000..eadb478 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp @@ -0,0 +1,62 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() +{ + return (*this); +} + +PB_DS_CLASS_T_DEC +const Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() const +{ + return (*this); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hpp new file mode 100644 index 0000000..2bad979 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hpp @@ -0,0 +1,126 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file r_erase_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_node(node_pointer p_z) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + + _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value))); + + p_z->~node(); + + s_node_allocator.deallocate(p_z, 1); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_min_max_for_erased_node(node_pointer p_z) +{ + if (m_size == 1) + { + m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; + + return; + } + + if (m_p_head->m_p_left == p_z) + { + iterator it(p_z); + + ++it; + + m_p_head->m_p_left = it.m_p_nd; + } + else if (m_p_head->m_p_right == p_z) + { + iterator it(p_z); + + --it; + + m_p_head->m_p_right = it.m_p_nd; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + clear_imp(m_p_head->m_p_parent); + + m_size = 0; + + initialize(); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + if (p_nd == NULL) + return; + + clear_imp(p_nd->m_p_left); + + clear_imp(p_nd->m_p_right); + + p_nd->~Node(); + + s_node_allocator.deallocate(p_nd, 1); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp new file mode 100644 index 0000000..4e32aae --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp @@ -0,0 +1,162 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rotate_fn_imps.hpp + * Contains imps for rotating nodes. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_left(node_pointer p_x) +{ + node_pointer p_y = p_x->m_p_right; + + p_x->m_p_right = p_y->m_p_left; + + if (p_y->m_p_left != NULL) + p_y->m_p_left->m_p_parent = p_x; + + p_y->m_p_parent = p_x->m_p_parent; + + if (p_x == m_p_head->m_p_parent) + m_p_head->m_p_parent = p_y; + else if (p_x == p_x->m_p_parent->m_p_left) + p_x->m_p_parent->m_p_left = p_y; + else + p_x->m_p_parent->m_p_right = p_y; + + p_y->m_p_left = p_x; + p_x->m_p_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) + + apply_update(p_x, (node_update* )this); + apply_update(p_x->m_p_parent, (node_update* )this); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_right(node_pointer p_x) +{ + node_pointer p_y = p_x->m_p_left; + + p_x->m_p_left = p_y->m_p_right; + + if (p_y->m_p_right != NULL) + p_y->m_p_right->m_p_parent = p_x; + + p_y->m_p_parent = p_x->m_p_parent; + + if (p_x == m_p_head->m_p_parent) + m_p_head->m_p_parent = p_y; + else if (p_x == p_x->m_p_parent->m_p_right) + p_x->m_p_parent->m_p_right = p_y; + else + p_x->m_p_parent->m_p_left = p_y; + + p_y->m_p_right = p_x; + p_x->m_p_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) + + apply_update(p_x, (node_update* )this); + apply_update(p_x->m_p_parent, (node_update* )this); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_parent(node_pointer p_nd) +{ + node_pointer p_parent = p_nd->m_p_parent; + + if (p_nd == p_parent->m_p_left) + rotate_right(p_parent); + else + rotate_left(p_parent); + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || + p_nd->m_p_right == p_parent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer p_nd, Node_Update_* /*p_update*/) +{ + node_update::operator()( + node_iterator(p_nd), + const_node_iterator(static_cast<node_pointer>(NULL))); +} + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +update_to_top(node_pointer p_nd, Node_Update_* p_update) +{ + while (p_nd != m_p_head) + { + apply_update(p_nd, p_update); + + p_nd = p_nd->m_p_parent; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_to_top(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) +{ } + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp new file mode 100644 index 0000000..2c8e77d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp @@ -0,0 +1,152 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +join_prep(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (other.m_size == 0) + return false; + + if (m_size == 0) + { + value_swap(other); + return false; + } + + const bool greater = Cmp_Fn::operator()(PB_DS_V2F(m_p_head->m_p_right->m_value), PB_DS_V2F(other.m_p_head->m_p_left->m_value)); + + const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(other.m_p_head->m_p_right->m_value), PB_DS_V2F(m_p_head->m_p_left->m_value)); + + if (!greater && !lesser) + __throw_join_error(); + + if (lesser) + value_swap(other); + + m_size += other.m_size; + _GLIBCXX_DEBUG_ONLY(map_debug_base::join(other);) + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +join_finish(PB_DS_CLASS_C_DEC& other) +{ + initialize_min_max(); + other.initialize(); +} + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + other.clear(); + + if (m_size == 0) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return false; + } + + if (Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_left->m_value))) + { + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return false; + } + + if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_right->m_value))) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return false; + } + + if (m_size == 1) + { + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return false; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::split(r_key,(Cmp_Fn& )(*this), other);) + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split_finish(PB_DS_CLASS_C_DEC& other) +{ + other.initialize_min_max(); + other.m_size = std::distance(other.begin(), other.end()); + m_size -= other.m_size; + initialize_min_max(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +recursive_count(node_pointer p) const +{ + if (p == NULL) + return 0; + return 1 + recursive_count(p->m_p_left) + recursive_count(p->m_p_right); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp new file mode 100644 index 0000000..4c57608 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp @@ -0,0 +1,256 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation for bin_search_tree_. + */ + +#ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Key, + typename Mapped, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn, + class Allocator> + class Node_Update, + class Node, + class Allocator> + struct bin_search_tree_traits + { + private: + typedef + types_traits< + Key, + Mapped, + Allocator, + false> + type_traits; + + public: + typedef Node node; + + typedef + bin_search_tree_const_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + true, + Allocator> + const_point_iterator; + + typedef + bin_search_tree_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + true, + Allocator> + point_iterator; + + typedef + bin_search_tree_const_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + false, + Allocator> + const_reverse_iterator; + + typedef + bin_search_tree_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + false, + Allocator> + reverse_iterator; + + typedef + bin_search_tree_const_node_it_< + Node, + const_point_iterator, + point_iterator, + Allocator> + const_node_iterator; + + typedef + bin_search_tree_node_it_< + Node, + const_point_iterator, + point_iterator, + Allocator> + node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator> + node_update; + + typedef + pb_ds::null_tree_node_update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator>* + null_node_update_pointer; + }; + + template<typename Key, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn, + class Allocator> + class Node_Update, + class Node, + class Allocator> + struct bin_search_tree_traits< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + Node, + Allocator> + { + private: + typedef + types_traits< + Key, + null_mapped_type, + Allocator, + false> + type_traits; + + public: + typedef Node node; + + typedef + bin_search_tree_const_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + true, + Allocator> + const_point_iterator; + + typedef const_point_iterator point_iterator; + + typedef + bin_search_tree_const_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + false, + Allocator> + const_reverse_iterator; + + typedef const_reverse_iterator reverse_iterator; + + typedef + bin_search_tree_const_node_it_< + Node, + const_point_iterator, + point_iterator, + Allocator> + const_node_iterator; + + typedef const_node_iterator node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator> + node_update; + + typedef + pb_ds::null_tree_node_update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator>* + null_node_update_pointer; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp new file mode 100644 index 0000000..659b773 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp @@ -0,0 +1,363 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file binary_heap_.hpp + * Contains an implementation class for a binary heap. + */ + +#ifndef PB_DS_BINARY_HEAP_HPP +#define PB_DS_BINARY_HEAP_HPP + +/* + * Based on CLRS. + */ + +#include <queue> +#include <algorithm> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/binary_heap_/entry_cmp.hpp> +#include <ext/pb_ds/detail/binary_heap_/entry_pred.hpp> +#include <ext/pb_ds/detail/binary_heap_/resize_policy.hpp> +#include <ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp> +#include <ext/pb_ds/detail/binary_heap_/const_iterator.hpp> +#ifdef PB_DS_BINARY_HEAP_TRACE_ +#include <iostream> +#endif +#include <ext/pb_ds/detail/type_utils.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + binary_heap_<Value_Type, Cmp_Fn, Allocator> + +#define PB_DS_ENTRY_CMP_DEC \ + entry_cmp<Value_Type, Cmp_Fn, is_simple<Value_Type>::value, Allocator>::type + +#define PB_DS_RESIZE_POLICY_DEC \ + resize_policy<typename Allocator::size_type> + + /** + * class description = "Base class for some types of h3ap$"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class binary_heap_ : public PB_DS_ENTRY_CMP_DEC, + public PB_DS_RESIZE_POLICY_DEC + { + + private: + enum + { + simple_value = is_simple<Value_Type>::value + }; + + typedef integral_constant<int, simple_value> no_throw_copies_t; + + typedef + typename Allocator::template rebind< + Value_Type>::other + value_allocator; + + typedef + typename __conditional_type< + simple_value, + Value_Type, + typename value_allocator::pointer>::__type + entry; + + typedef + typename Allocator::template rebind< + entry>::other + entry_allocator; + + typedef typename entry_allocator::pointer entry_pointer; + + typedef typename PB_DS_ENTRY_CMP_DEC entry_cmp; + + typedef PB_DS_RESIZE_POLICY_DEC resize_policy; + + typedef + cond_dealtor< + Value_Type, + Allocator> + cond_dealtor_t; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + binary_heap_const_point_iterator_< + value_type, + entry, + simple_value, + Allocator> + const_point_iterator; + + typedef const_point_iterator point_iterator; + + typedef + binary_heap_const_iterator_< + value_type, + entry, + simple_value, + Allocator> + const_iterator; + + typedef const_iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + public: + + binary_heap_(); + + binary_heap_(const Cmp_Fn& r_cmp_fn); + + binary_heap_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~binary_heap_(); + + inline bool + empty() const; + + inline size_type + size() const; + + inline size_type + max_size() const; + + Cmp_Fn& + get_cmp_fn(); + + const Cmp_Fn& + get_cmp_fn() const; + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline const_reference + top() const; + + inline void + pop(); + + inline void + erase(point_iterator it); + + template<typename Pred> + typename PB_DS_CLASS_C_DEC::size_type + erase_if(Pred pred); + + inline static void + erase_at(entry_pointer a_entries, size_type size, false_type); + + inline static void + erase_at(entry_pointer a_entries, size_type size, true_type); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + + void + clear(); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + void + trace() const; +#endif + + protected: + + template<typename It> + void + copy_from_range(It first_it, It last_it); + + private: + + void + value_swap(PB_DS_CLASS_C_DEC& other); + + inline void + insert_value(const_reference r_val, false_type); + + inline void + insert_value(value_type val, true_type); + + inline void + insert_entry(entry e); + + inline void + resize_for_insert_if_needed(); + + inline void + swap_value_imp(entry_pointer p_e, value_type new_val, true_type); + + inline void + swap_value_imp(entry_pointer p_e, const_reference r_new_val, false_type); + + void + fix(entry_pointer p_e); + + inline const_reference + top_imp(true_type) const; + + inline const_reference + top_imp(false_type) const; + + inline static size_type + left_child(size_type i); + + inline static size_type + right_child(size_type i); + + inline static size_type + parent(size_type i); + + inline void + resize_for_erase_if_needed(); + + template<typename Pred> + size_type + partition(Pred pred); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + void + trace_entry(const entry& r_e, false_type) const; + + void + trace_entry(const entry& r_e, true_type) const; +#endif + + private: + static entry_allocator s_entry_allocator; + + static value_allocator s_value_allocator; + + static no_throw_copies_t s_no_throw_copies_ind; + + size_type m_size; + + size_type m_actual_size; + + entry_pointer m_a_entries; + }; + +#include <ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_ENTRY_CMP_DEC +#undef PB_DS_RESIZE_POLICY_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_iterator.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_iterator.hpp new file mode 100644 index 0000000..12b96e7 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_iterator.hpp @@ -0,0 +1,158 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_iterator.hpp + * Contains an iterator class returned by the table's const find and insert + * methods. + */ + +#ifndef PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP +#define PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP + +#include <ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_C_DEC \ + binary_heap_const_iterator_<Value_Type, Entry, Simple, Allocator> + +#define PB_DS_BASE_C_DEC \ + binary_heap_const_point_iterator_<Value_Type, Entry, Simple, Allocator> + + // Const point-type iterator. + template<typename Value_Type, + typename Entry, + bool Simple, + class Allocator> + class binary_heap_const_iterator_ : public PB_DS_BASE_C_DEC + { + + private: + typedef typename PB_DS_BASE_C_DEC::entry_pointer entry_pointer; + + typedef PB_DS_BASE_C_DEC base_type; + + public: + + // Category. + typedef std::forward_iterator_tag iterator_category; + + // Difference type. + typedef typename Allocator::difference_type difference_type; + + // Iterator's value type. + typedef typename base_type::value_type value_type; + + // Iterator's pointer type. + typedef typename base_type::pointer pointer; + + // Iterator's const pointer type. + typedef typename base_type::const_pointer const_pointer; + + // Iterator's reference type. + typedef typename base_type::reference reference; + + // Iterator's const reference type. + typedef typename base_type::const_reference const_reference; + + public: + + inline + binary_heap_const_iterator_(entry_pointer p_e) : base_type(p_e) + { } + + // Default constructor. + inline + binary_heap_const_iterator_() + { } + + // Copy constructor. + inline + binary_heap_const_iterator_(const PB_DS_CLASS_C_DEC& other) : base_type(other) + { } + + // Compares content to a different iterator object. + inline bool + operator==(const PB_DS_CLASS_C_DEC& other) const + { + return base_type::m_p_e == other.m_p_e; + } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_CLASS_C_DEC& other) const + { + return base_type::m_p_e != other.m_p_e; + } + + inline PB_DS_CLASS_C_DEC& + operator++() + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_e != NULL); + inc(); + return *this; + } + + inline PB_DS_CLASS_C_DEC + operator++(int) + { + PB_DS_CLASS_C_DEC ret_it(base_type::m_p_e); + operator++(); + return ret_it; + } + + private: + void + inc() + { ++base_type::m_p_e; } + }; + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp new file mode 100644 index 0000000..3a50cd6 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp @@ -0,0 +1,150 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_point_iterator.hpp + * Contains an iterator class returned by the table's const find and insert + * methods. + */ + +#ifndef PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP +#define PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + // Const point-type iterator. + template<typename Value_Type, typename Entry, bool Simple, + typename Allocator> + class binary_heap_const_point_iterator_ + { + protected: + typedef typename Allocator::template rebind<Entry>::other::pointer entry_pointer; + + public: + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // Iterator's value type. + typedef Value_Type value_type; + + // Iterator's pointer type. + typedef typename Allocator::template rebind<value_type>::other::pointer + pointer; + + // Iterator's const pointer type. + typedef + typename Allocator::template rebind<value_type>::other::const_pointer + const_pointer; + + // Iterator's reference type. + typedef + typename Allocator::template rebind<value_type>::other::reference + reference; + + // Iterator's const reference type. + typedef + typename Allocator::template rebind<value_type>::other::const_reference + const_reference; + + inline + binary_heap_const_point_iterator_(entry_pointer p_e) : m_p_e(p_e) + { } + + // Default constructor. + inline + binary_heap_const_point_iterator_() : m_p_e(NULL) { } + + // Copy constructor. + inline + binary_heap_const_point_iterator_(const binary_heap_const_point_iterator_& other) + : m_p_e(other.m_p_e) + { } + + // Access. + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_e != NULL); + return to_ptr(integral_constant<int, Simple>()); + } + + // Access. + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_e != NULL); + return *to_ptr(integral_constant<int, Simple>()); + } + + // Compares content to a different iterator object. + inline bool + operator==(const binary_heap_const_point_iterator_& other) const + { return m_p_e == other.m_p_e; } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const binary_heap_const_point_iterator_& other) const + { return m_p_e != other.m_p_e; } + + private: + inline const_pointer + to_ptr(true_type) const + { return m_p_e; } + + inline const_pointer + to_ptr(false_type) const + { return *m_p_e; } + + public: + entry_pointer m_p_e; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..b43529b --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,165 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for binary_heap_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_allocator +PB_DS_CLASS_C_DEC::s_entry_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::value_allocator +PB_DS_CLASS_C_DEC::s_value_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::no_throw_copies_t +PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + { + insert_value(*first_it, s_no_throw_copies_ind); + ++first_it; + } + + std::make_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binary_heap_() : + m_size(0), + m_actual_size(resize_policy::min_size), + m_a_entries(s_entry_allocator.allocate(m_actual_size)) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binary_heap_(const Cmp_Fn& r_cmp_fn) : + entry_cmp(r_cmp_fn), + m_size(0), + m_actual_size(resize_policy::min_size), + m_a_entries(s_entry_allocator.allocate(m_actual_size)) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binary_heap_(const PB_DS_CLASS_C_DEC& other) : + entry_cmp(other), + resize_policy(other), + m_size(0), + m_actual_size(other.m_actual_size), + m_a_entries(s_entry_allocator.allocate(m_actual_size)) +{ + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); + + const_iterator first_it = other.begin(); + const_iterator last_it = other.end(); + + try + { + while (first_it != last_it) + { + insert_value(*first_it, s_no_throw_copies_ind); + ++first_it; + } + } + catch(...) + { + for (size_type i = 0; i < m_size; ++i) + erase_at(m_a_entries, i, s_no_throw_copies_ind); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); + + value_swap(other); + std::swap((entry_cmp& )(*this), (entry_cmp& )other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_a_entries, other.m_a_entries); + std::swap(m_size, other.m_size); + std::swap(m_actual_size, other.m_actual_size); + static_cast<resize_policy*>(this)->swap(other); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~binary_heap_() +{ + for (size_type i = 0; i < m_size; ++i) + erase_at(m_a_entries, i, s_no_throw_copies_ind); + s_entry_allocator.deallocate(m_a_entries, m_actual_size); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp new file mode 100644 index 0000000..198d660 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ +#ifdef PB_DS_REGRESSION + s_entry_allocator.check_allocated(m_a_entries, m_actual_size); +#endif + + resize_policy::assert_valid(); + _GLIBCXX_DEBUG_ASSERT(m_size <= m_actual_size); + for (size_type i = 0; i < m_size; ++i) + { +#ifdef PB_DS_REGRESSION + s_value_allocator.check_allocated(m_a_entries[i], 1); +#endif + + if (left_child(i) < m_size) + _GLIBCXX_DEBUG_ASSERT(!entry_cmp::operator()(m_a_entries[i], m_a_entries[left_child(i)])); + + _GLIBCXX_DEBUG_ASSERT(parent(left_child(i)) == i); + + if (right_child(i) < m_size) + _GLIBCXX_DEBUG_ASSERT(!entry_cmp::operator()(m_a_entries[i], m_a_entries[right_child(i)])); + + _GLIBCXX_DEBUG_ASSERT(parent(right_child(i)) == i); + } +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_cmp.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_cmp.hpp new file mode 100644 index 0000000..c98dae7 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_cmp.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file entry_cmp.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP +#define PB_DS_BINARY_HEAP_ENTRY_CMP_HPP + +namespace pb_ds +{ + namespace detail + { + + template<typename Value_Type, + class Cmp_Fn, + bool No_Throw, + class Allocator> + struct entry_cmp + { + typedef Cmp_Fn type; + }; + + template<typename Value_Type, class Cmp_Fn, class Allocator> + struct entry_cmp< + Value_Type, + Cmp_Fn, + false, + Allocator> + { + public: + typedef + typename Allocator::template rebind< + Value_Type>::other::const_pointer + entry; + + struct type : public Cmp_Fn + { + public: + inline + type() + { } + + inline + type(const Cmp_Fn& other) : Cmp_Fn(other) + { } + + inline bool + operator()(entry p_lhs, entry p_rhs) const + { + return Cmp_Fn::operator()(*p_lhs, * p_rhs); + } + }; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_pred.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_pred.hpp new file mode 100644 index 0000000..25102f2 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_pred.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file entry_pred.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP +#define PB_DS_BINARY_HEAP_ENTRY_PRED_HPP + +namespace pb_ds +{ + namespace detail + { + + template<typename Value_Type, + class Pred, + bool No_Throw, + class Allocator> + struct entry_pred + { + typedef Pred type; + }; + + template<typename Value_Type, class Pred, class Allocator> + struct entry_pred< + Value_Type, + Pred, + false, + Allocator> + { + public: + typedef + typename Allocator::template rebind< + Value_Type>::other::const_pointer + entry; + + struct type : public Pred + { + public: + inline + type() + { } + + inline + type(const Pred& other) : Pred(other) + { } + + inline bool + operator()(entry p_v) const + { + return Pred::operator()(*p_v); + } + }; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp new file mode 100644 index 0000000..72686d1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp @@ -0,0 +1,252 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + for (size_type i = 0; i < m_size; ++i) + erase_at(m_a_entries, i, s_no_throw_copies_ind); + + try + { + const size_type actual_size = resize_policy::get_new_size_for_arbitrary(0); + + entry_pointer a_entries = s_entry_allocator.allocate(actual_size); + + resize_policy::notify_arbitrary(actual_size); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + + m_actual_size = actual_size; + + m_a_entries = a_entries; + } + catch(...) + { } + + m_size = 0; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_at(entry_pointer a_entries, size_type i, false_type) +{ + a_entries[i]->~value_type(); + + s_value_allocator.deallocate(a_entries[i], 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_at(entry_pointer, size_type, true_type) +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +pop() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + + erase_at(m_a_entries, 0, s_no_throw_copies_ind); + + std::pop_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + resize_for_erase_if_needed(); + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + typedef + typename entry_pred< + value_type, + Pred, + simple_value, + Allocator>::type + pred_t; + + const size_type left = partition(pred_t(pred)); + + _GLIBCXX_DEBUG_ASSERT(m_size >= left); + + const size_type ersd = m_size - left; + + for (size_type i = left; i < m_size; ++i) + erase_at(m_a_entries, i, s_no_throw_copies_ind); + + try + { + const size_type actual_size = + resize_policy::get_new_size_for_arbitrary(left); + + entry_pointer a_entries = s_entry_allocator.allocate(actual_size); + + std::copy(m_a_entries, m_a_entries + left, a_entries); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + + m_actual_size = actual_size; + + resize_policy::notify_arbitrary(m_actual_size); + } + catch(...) + { }; + + m_size = left; + + std::make_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return ersd; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + + const size_type fix_pos = it.m_p_e - m_a_entries; + + std::swap(*it.m_p_e, m_a_entries[m_size - 1]); + + erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind); + + resize_for_erase_if_needed(); + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + + _GLIBCXX_DEBUG_ASSERT(fix_pos <= m_size); + + if (fix_pos != m_size) + fix(m_a_entries + fix_pos); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +resize_for_erase_if_needed() +{ + if (!resize_policy::resize_needed_for_shrink(m_size)) + return; + + try + { + const size_type new_actual_size = + resize_policy::get_new_size_for_shrink(); + + entry_pointer a_new_entries = s_entry_allocator.allocate(new_actual_size); + + resize_policy::notify_shrink_resize(); + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + std::copy(m_a_entries, m_a_entries + m_size - 1, a_new_entries); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + + m_actual_size = new_actual_size; + + m_a_entries = a_new_entries; + } + catch(...) + { } +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +partition(Pred pred) +{ + size_type left = 0; + size_type right = m_size - 1; + + while (right + 1 != left) + { + _GLIBCXX_DEBUG_ASSERT(left <= m_size); + + if (!pred(m_a_entries[left])) + ++left; + else if (pred(m_a_entries[right])) + --right; + else + { + _GLIBCXX_DEBUG_ASSERT(left < right); + + std::swap(m_a_entries[left], m_a_entries[right]); + + ++left; + --right; + } + } + + return left; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp new file mode 100644 index 0000000..b7606b6 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + + return top_imp(s_no_throw_copies_ind); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top_imp(true_type) const +{ + return* m_a_entries; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top_imp(false_type) const +{ + return** m_a_entries; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +left_child(size_type i) +{ + return i* 2 + 1; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +right_child(size_type i) +{ + return i* 2 + 2; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +parent(size_type i) +{ + return (i - 1) / 2; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp new file mode 100644 index 0000000..eb227d3 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp @@ -0,0 +1,70 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ + return (m_size == 0); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ + return (m_size); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ + return (s_entry_allocator.max_size()); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp new file mode 100644 index 0000000..489ccc1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp @@ -0,0 +1,220 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + insert_value(r_val, s_no_throw_copies_ind); + + std::push_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(m_a_entries); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_value(value_type val, true_type) +{ + resize_for_insert_if_needed(); + + m_a_entries[m_size++] = val; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_value(const_reference r_val, false_type) +{ + resize_for_insert_if_needed(); + + pointer p_new = s_value_allocator.allocate(1); + + cond_dealtor_t cond(p_new); + + new (p_new) value_type(r_val); + + cond.set_no_action(); + + m_a_entries[m_size++] = p_new; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_entry(entry e) +{ + resize_for_insert_if_needed(); + + m_a_entries[m_size++] = e; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +resize_for_insert_if_needed() +{ + if (!resize_policy::resize_needed_for_grow(m_size)) + { + _GLIBCXX_DEBUG_ASSERT(m_size < m_actual_size); + + return; + } + + const size_type new_actual_size = + resize_policy::get_new_size_for_grow(); + + entry_pointer a_new_entries = s_entry_allocator.allocate(new_actual_size); + + resize_policy::notify_grow_resize(); + + std::copy(m_a_entries, m_a_entries + m_size, a_new_entries); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + + m_actual_size = new_actual_size; + + m_a_entries = a_new_entries; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + swap_value_imp(it.m_p_e, r_new_val, s_no_throw_copies_ind); + + fix(it.m_p_e); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +fix(entry_pointer p_e) +{ + size_type i = p_e - m_a_entries; + + if (i > 0&& entry_cmp::operator()(m_a_entries[parent(i)], m_a_entries[i])) + { + size_type parent_i = parent(i); + + while (i > 0&& entry_cmp::operator()(m_a_entries[parent_i], m_a_entries[i])) + { + std::swap(m_a_entries[i], m_a_entries[parent_i]); + + i = parent_i; + + parent_i = parent(i); + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return; + } + + while (i < m_size) + { + const size_type left_child_i = left_child(i); + const size_type right_child_i = right_child(i); + + _GLIBCXX_DEBUG_ASSERT(right_child_i > left_child_i); + + const bool smaller_than_left_child = + left_child_i < m_size&& + entry_cmp::operator()(m_a_entries[i], m_a_entries[left_child_i]); + + const bool smaller_than_right_child = + right_child_i < m_size&& + entry_cmp::operator()(m_a_entries[i], m_a_entries[right_child_i]); + + const bool swap_with_r_child = smaller_than_right_child&& (!smaller_than_left_child || + entry_cmp::operator()(m_a_entries[left_child_i], m_a_entries[right_child_i])); + + const bool swap_with_l_child = !swap_with_r_child&& smaller_than_left_child; + + if (swap_with_l_child) + { + std::swap(m_a_entries[i], m_a_entries[left_child_i]); + + i = left_child_i; + } + else if (swap_with_r_child) + { + std::swap(m_a_entries[i], m_a_entries[right_child_i]); + + i = right_child_i; + } + else + i = m_size; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap_value_imp(entry_pointer p_e, value_type new_val, true_type) +{ + * p_e = new_val; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap_value_imp(entry_pointer p_e, const_reference r_new_val, false_type) +{ + value_type tmp(r_new_val); + (*p_e)->swap(tmp); +} diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp new file mode 100644 index 0000000..7a647c3 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + return (iterator(m_a_entries)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + return (const_iterator(m_a_entries)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ + return (iterator(m_a_entries + m_size)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ + return (const_iterator(m_a_entries + m_size)); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp new file mode 100644 index 0000000..6c019c08 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp @@ -0,0 +1,62 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() +{ + return (*this); +} + +PB_DS_CLASS_T_DEC +const Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() const +{ + return (*this); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/resize_policy.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/resize_policy.hpp new file mode 100644 index 0000000..c6021a9 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/resize_policy.hpp @@ -0,0 +1,259 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_policy.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifndef PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP +#define PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> + +#define PB_DS_CLASS_C_DEC resize_policy<Size_Type> + + template<typename Size_Type> + class resize_policy + { + public: + typedef Size_Type size_type; + + enum + { + min_size = 16 + }; + + public: + inline + resize_policy(); + + inline void + swap(PB_DS_CLASS_C_DEC& other); + + inline bool + resize_needed_for_grow(size_type size) const; + + inline bool + resize_needed_for_shrink(size_type size) const; + + inline bool + grow_needed(size_type size) const; + + inline bool + shrink_needed(size_type size) const; + + inline size_type + get_new_size_for_grow() const; + + inline size_type + get_new_size_for_shrink() const; + + size_type + get_new_size_for_arbitrary(size_type size) const; + + inline void + notify_grow_resize(); + + inline void + notify_shrink_resize(); + + void + notify_arbitrary(size_type actual_size); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + void + trace() const; +#endif + + private: + enum + { + ratio = 8, + factor = 2 + }; + + private: + size_type m_next_shrink_size; + size_type m_next_grow_size; + }; + + PB_DS_CLASS_T_DEC + inline + PB_DS_CLASS_C_DEC:: + resize_policy() : + m_next_shrink_size(0), + m_next_grow_size(min_size) + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + std::swap(m_next_shrink_size, other.m_next_shrink_size); + std::swap(m_next_grow_size, other.m_next_grow_size); + } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + resize_needed_for_grow(size_type size) const + { + _GLIBCXX_DEBUG_ASSERT(size <= m_next_grow_size); + return size == m_next_grow_size; + } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + resize_needed_for_shrink(size_type size) const + { + _GLIBCXX_DEBUG_ASSERT(size <= m_next_grow_size); + return size == m_next_shrink_size; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_new_size_for_grow() const + { return m_next_grow_size* factor; } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_new_size_for_shrink() const + { + const size_type half_size = m_next_grow_size / factor; + return std::max(static_cast<size_type>(min_size), half_size); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_new_size_for_arbitrary(size_type size) const + { + size_type ret = min_size; + while (ret < size) + ret *= factor; + return ret; + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + notify_grow_resize() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(m_next_grow_size >= min_size); + m_next_grow_size *= factor; + m_next_shrink_size = m_next_grow_size / ratio; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + notify_shrink_resize() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + m_next_shrink_size /= factor; + if (m_next_shrink_size == 1) + m_next_shrink_size = 0; + + m_next_grow_size = + std::max(m_next_grow_size / factor, static_cast<size_type>(min_size)); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + notify_arbitrary(size_type actual_size) + { + m_next_grow_size = actual_size; + m_next_shrink_size = m_next_grow_size / ratio; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + assert_valid() const + { + _GLIBCXX_DEBUG_ASSERT(m_next_shrink_size == 0 || + m_next_shrink_size* ratio == m_next_grow_size); + + _GLIBCXX_DEBUG_ASSERT(m_next_grow_size >= min_size); + } +#endif + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace() const + { + std::cerr << "shrink = " << m_next_shrink_size << + " grow = " << m_next_grow_size << std::endl; + } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp new file mode 100644 index 0000000..679efa5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp @@ -0,0 +1,178 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + typedef + typename entry_pred< + value_type, + Pred, + simple_value, + Allocator>::type + pred_t; + + const size_type left = partition(pred_t(pred)); + + _GLIBCXX_DEBUG_ASSERT(m_size >= left); + + const size_type ersd = m_size - left; + + _GLIBCXX_DEBUG_ASSERT(m_size >= ersd); + + const size_type actual_size = + resize_policy::get_new_size_for_arbitrary(left); + + const size_type other_actual_size = + other.get_new_size_for_arbitrary(ersd); + + entry_pointer a_entries = NULL; + entry_pointer a_other_entries = NULL; + + try + { + a_entries = s_entry_allocator.allocate(actual_size); + + a_other_entries = s_entry_allocator.allocate(other_actual_size); + } + catch(...) + { + if (a_entries != NULL) + s_entry_allocator.deallocate(a_entries, actual_size); + + if (a_other_entries != NULL) + s_entry_allocator.deallocate(a_other_entries, other_actual_size); + + __throw_exception_again; + }; + + for (size_type i = 0; i < other.m_size; ++i) + erase_at(other.m_a_entries, i, s_no_throw_copies_ind); + + _GLIBCXX_DEBUG_ASSERT(actual_size >= left); + std::copy(m_a_entries, m_a_entries + left, a_entries); + std::copy(m_a_entries + left, m_a_entries + m_size, a_other_entries); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); + + m_actual_size = actual_size; + other.m_actual_size = other_actual_size; + + m_size = left; + other.m_size = ersd; + + m_a_entries = a_entries; + other.m_a_entries = a_other_entries; + + std::make_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + std::make_heap(other.m_a_entries, other.m_a_entries + other.m_size, static_cast<entry_cmp& >(other)); + + resize_policy::notify_arbitrary(m_actual_size); + other.notify_arbitrary(other.m_actual_size); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + const size_type len = m_size + other.m_size; + const size_type actual_size = resize_policy::get_new_size_for_arbitrary(len); + + entry_pointer a_entries = NULL; + entry_pointer a_other_entries = NULL; + + try + { + a_entries = s_entry_allocator.allocate(actual_size); + a_other_entries = s_entry_allocator.allocate(resize_policy::min_size); + } + catch(...) + { + if (a_entries != NULL) + s_entry_allocator.deallocate(a_entries, actual_size); + + if (a_other_entries != NULL) + s_entry_allocator.deallocate(a_other_entries, resize_policy::min_size); + + __throw_exception_again; + } + + std::copy(m_a_entries, m_a_entries + m_size, a_entries); + std::copy(other.m_a_entries, other.m_a_entries + other.m_size, a_entries + m_size); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + m_a_entries = a_entries; + m_size = len; + m_actual_size = actual_size; + + resize_policy::notify_arbitrary(actual_size); + + std::make_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); + other.m_a_entries = a_other_entries; + other.m_size = 0; + other.m_actual_size = resize_policy::min_size; + + other.notify_arbitrary(resize_policy::min_size); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + diff --git a/libstdc++/include/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp new file mode 100644 index 0000000..bcc1065 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp @@ -0,0 +1,84 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << this << std::endl; + + std::cerr << m_a_entries << std::endl; + + for (size_type i = 0; i < m_size; ++i) + trace_entry(m_a_entries[i], s_no_throw_copies_ind); + + std::cerr << std::endl; + + std::cerr << "size = " << m_size << " " << "actual_size = " << m_actual_size << std::endl; + + resize_policy::trace(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_entry(const entry& r_e, false_type) const +{ + std::cout << r_e << " " <<* r_e << std::endl; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_entry(const entry& r_e, true_type) const +{ + std::cout << r_e << std::endl; +} + +#endif // #ifdef PB_DS_BINARY_HEAP_TRACE_ diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp new file mode 100644 index 0000000..c6f361d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp @@ -0,0 +1,122 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file binomial_heap_.hpp + * Contains an implementation class for a binomial heap. + */ + +/* + * Binomial heap. + * Vuillemin J is the mastah. + * Modified from CLRS. + */ + +#include <debug/debug.h> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + binomial_heap_<Value_Type, Cmp_Fn, Allocator> + +#define PB_DS_BASE_C_DEC \ + binomial_heap_base_<Value_Type, Cmp_Fn, Allocator> + + /** + * class description = "8y|\|0|\/|i41 h34p 74813"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class binomial_heap_ : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + typedef typename base_type::node_pointer node_pointer; + typedef typename base_type::const_node_pointer const_node_pointer; + + public: + typedef Value_Type value_type; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + typedef typename base_type::const_point_iterator const_point_iterator; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::iterator iterator; + typedef typename base_type::cmp_fn cmp_fn; + typedef typename base_type::allocator allocator; + + binomial_heap_(); + + binomial_heap_(const Cmp_Fn& r_cmp_fn); + + binomial_heap_(const PB_DS_CLASS_C_DEC& other); + + ~binomial_heap_(); + + protected: +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + }; + +#include <ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_BASE_C_DEC + } // namespace detail +} // namespace pb_ds diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..2e63cf8 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,67 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation for binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn) +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other) +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~binomial_heap_() { } + diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp new file mode 100644 index 0000000..540bd7c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp @@ -0,0 +1,55 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation for binomial_heap_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ base_type::assert_valid(true); } + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp new file mode 100644 index 0000000..09af8cf --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp @@ -0,0 +1,240 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file binomial_heap_base_.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +#ifndef PB_DS_BINOMIAL_HEAP_BASE_HPP +#define PB_DS_BINOMIAL_HEAP_BASE_HPP + +/* + * Binomial heap base. + * Vuillemin J is the mastah. + * Modified from CLRS. + */ + +#include <debug/debug.h> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + binomial_heap_base_<Value_Type, Cmp_Fn, Allocator> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_<Value_Type, Cmp_Fn, \ + typename Allocator::size_type, \ + Allocator, false> +#else +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_<Value_Type, Cmp_Fn, \ + typename Allocator::size_type, Allocator> +#endif + + /** + * class description = "8y|\|0|\/|i41 h34p 74813"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class binomial_heap_base_ : public PB_DS_BASE_C_DEC + { + + private: + typedef PB_DS_BASE_C_DEC base_type; + + protected: + typedef typename base_type::node node; + + typedef typename base_type::node_pointer node_pointer; + + typedef typename base_type::const_node_pointer const_node_pointer; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + typename PB_DS_BASE_C_DEC::const_point_iterator + const_point_iterator; + + typedef typename PB_DS_BASE_C_DEC::point_iterator point_iterator; + + typedef typename PB_DS_BASE_C_DEC::const_iterator const_iterator; + + typedef typename PB_DS_BASE_C_DEC::iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + public: + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline const_reference + top() const; + + void + pop(); + + void + erase(point_iterator it); + + inline void + clear(); + + template<typename Pred> + size_type + erase_if(Pred pred); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + + protected: + + binomial_heap_base_(); + + binomial_heap_base_(const Cmp_Fn& r_cmp_fn); + + binomial_heap_base_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~binomial_heap_base_(); + + template<typename It> + void + copy_from_range(It first_it, It last_it); + + inline void + find_max(); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid(bool strictly_binomial) const; + + void + assert_max() const; +#endif + + private: + + inline node_pointer + fix(node_pointer p_nd) const; + + inline void + insert_node(node_pointer p_nd); + + inline void + remove_parentless_node(node_pointer p_nd); + + inline node_pointer + join(node_pointer p_lhs, node_pointer p_rhs) const; + +#ifdef _GLIBCXX_DEBUG + void + assert_node_consistent(const_node_pointer, bool, bool) const; +#endif + + protected: + node_pointer m_p_max; + }; + +#include <ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_BASE_C_DEC + + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..24ea295 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,103 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + push(*(first_it++)); + + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_base_() : + m_p_max(NULL) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_base_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn), + m_p_max(NULL) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_base_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other), + m_p_max(NULL) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + + base_type::swap(other); + + std::swap(m_p_max, other.m_p_max); + + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~binomial_heap_base_() +{ } + diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp new file mode 100644 index 0000000..200249d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid(bool strictly_binomial) const +{ + base_type::assert_valid(); + assert_node_consistent(base_type::m_p_root, strictly_binomial, true); + assert_max(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_max() const +{ + if (m_p_max == NULL) + return; + _GLIBCXX_DEBUG_ASSERT(base_type::parent(m_p_max) == NULL); + for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const_node_pointer p_nd, bool strictly_binomial, bool increasing) const +{ + _GLIBCXX_DEBUG_ASSERT(increasing || strictly_binomial); + base_type::assert_node_consistent(p_nd, false); + if (p_nd == NULL) + return; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == base_type::degree(p_nd)); + _GLIBCXX_DEBUG_ASSERT(base_type::size_under_node(p_nd) == + static_cast<size_type>(1 << p_nd->m_metadata)); + assert_node_consistent(p_nd->m_p_next_sibling, strictly_binomial, increasing); + assert_node_consistent(p_nd->m_p_l_child, true, false); + if (p_nd->m_p_next_sibling != NULL) + if (increasing) + { + if (strictly_binomial) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < p_nd->m_p_next_sibling->m_metadata); + else + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata <= p_nd->m_p_next_sibling->m_metadata); + } + else + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata > p_nd->m_p_next_sibling->m_metadata); +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp new file mode 100644 index 0000000..8109b53e --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp @@ -0,0 +1,198 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +pop() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + if (m_p_max == NULL) + find_max(); + + _GLIBCXX_DEBUG_ASSERT(m_p_max != NULL); + + node_pointer p_nd = m_p_max; + + remove_parentless_node(m_p_max); + + base_type::actual_erase_node(p_nd); + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +remove_parentless_node(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(base_type::parent(p_nd) == NULL); + + node_pointer p_cur_root = p_nd == base_type::m_p_root? + p_nd->m_p_next_sibling : + base_type::m_p_root; + + if (p_cur_root != NULL) + p_cur_root->m_p_prev_or_parent = NULL; + + if (p_nd->m_p_prev_or_parent != NULL) + p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + + node_pointer p_child = p_nd->m_p_l_child; + + if (p_child != NULL) + { + p_child->m_p_prev_or_parent = NULL; + + while (p_child->m_p_next_sibling != NULL) + p_child = p_child->m_p_next_sibling; + } + + m_p_max = NULL; + + base_type::m_p_root = join(p_cur_root, p_child); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +clear() +{ + base_type::clear(); + + m_p_max = NULL; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + base_type::bubble_to_top(it.m_p_nd); + + remove_parentless_node(it.m_p_nd); + + base_type::actual_erase_node(it.m_p_nd); + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + } + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + return 0; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + size_type ersd = 0; + + while (p_out != NULL) + { + ++ersd; + + node_pointer p_next = p_out->m_p_next_sibling; + + base_type::actual_erase_node(p_out); + + p_out = p_next; + } + + node_pointer p_cur = base_type::m_p_root; + + base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = NULL; + + p_cur->m_metadata = 0; + + p_cur->m_p_next_sibling = base_type::m_p_root; + + if (base_type::m_p_root != NULL) + base_type::m_p_root->m_p_prev_or_parent = p_cur; + + base_type::m_p_root = p_cur; + + base_type::m_p_root = fix(base_type::m_p_root); + + p_cur = p_next; + } + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + return ersd; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp new file mode 100644 index 0000000..6014c07 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp @@ -0,0 +1,79 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + if (m_p_max == NULL) + const_cast<PB_DS_CLASS_C_DEC* >(this)->find_max(); + + _GLIBCXX_DEBUG_ASSERT(m_p_max != NULL); + return m_p_max->m_value; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +find_max() +{ + node_pointer p_cur = base_type::m_p_root; + + m_p_max = p_cur; + + while (p_cur != NULL) + { + if (Cmp_Fn::operator()(m_p_max->m_value, p_cur->m_value)) + m_p_max = p_cur; + + p_cur = p_cur->m_p_next_sibling; + } +} + diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp new file mode 100644 index 0000000..91b04e1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp @@ -0,0 +1,222 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + node_pointer p_nd = base_type::get_new_node_for_insert(r_val); + + insert_node(p_nd); + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + return point_iterator(p_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_node(node_pointer p_nd) +{ + if (base_type::m_p_root == NULL) + { + p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = + p_nd->m_p_l_child = NULL; + + p_nd->m_metadata = 0; + + base_type::m_p_root = p_nd; + + return; + } + + if (base_type::m_p_root->m_metadata > 0) + { + p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = NULL; + + p_nd->m_p_next_sibling = base_type::m_p_root; + + base_type::m_p_root->m_p_prev_or_parent = p_nd; + + base_type::m_p_root = p_nd; + + p_nd->m_metadata = 0; + + return; + } + + if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) + { + p_nd->m_p_next_sibling = base_type::m_p_root->m_p_next_sibling; + + p_nd->m_p_prev_or_parent = NULL; + + p_nd->m_metadata = 1; + + p_nd->m_p_l_child = base_type::m_p_root; + + base_type::m_p_root->m_p_prev_or_parent = p_nd; + + base_type::m_p_root->m_p_next_sibling = NULL; + + base_type::m_p_root = p_nd; + } + else + { + p_nd->m_p_next_sibling = NULL; + + p_nd->m_p_l_child = NULL; + + p_nd->m_p_prev_or_parent = base_type::m_p_root; + + p_nd->m_metadata = 0; + + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_root->m_p_l_child == 0); + base_type::m_p_root->m_p_l_child = p_nd; + + base_type::m_p_root->m_metadata = 1; + } + + base_type::m_p_root = fix(base_type::m_p_root); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +fix(node_pointer p_nd) const +{ + while (p_nd->m_p_next_sibling != NULL&& + p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata) + { + node_pointer p_next = p_nd->m_p_next_sibling; + + if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) + { + p_next->m_p_prev_or_parent = + p_nd->m_p_prev_or_parent; + + if (p_nd->m_p_prev_or_parent != NULL) + p_nd->m_p_prev_or_parent->m_p_next_sibling = p_next; + + base_type::make_child_of(p_nd, p_next); + + ++p_next->m_metadata; + + p_nd = p_next; + } + else + { + p_nd->m_p_next_sibling = p_next->m_p_next_sibling; + + if (p_nd->m_p_next_sibling != NULL) + p_next->m_p_next_sibling = NULL; + + base_type::make_child_of(p_next, p_nd); + + ++p_nd->m_metadata; + } + } + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; + + return p_nd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + node_pointer p_nd = it.m_p_nd; + + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false);) + + const bool bubble_up = Cmp_Fn::operator()(p_nd->m_value, r_new_val); + + p_nd->m_value = r_new_val; + + if (bubble_up) + { + node_pointer p_parent = base_type::parent(p_nd); + + while (p_parent != NULL&& + Cmp_Fn::operator()(p_parent->m_value, p_nd->m_value)) + { + base_type::swap_with_parent(p_nd, p_parent); + + p_parent = base_type::parent(p_nd); + } + + if (p_nd->m_p_prev_or_parent == NULL) + base_type::m_p_root = p_nd; + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + return; + } + + base_type::bubble_to_top(p_nd); + + remove_parentless_node(p_nd); + + insert_node(p_nd); + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + } + diff --git a/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp new file mode 100644 index 0000000..05f9f12 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp @@ -0,0 +1,238 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + + other.clear(); + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + + return; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + while (p_out != NULL) + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); + --base_type::m_size; + + ++other.m_size; + + node_pointer p_next = p_out->m_p_next_sibling; + + p_out->m_p_l_child = p_out->m_p_prev_or_parent = NULL; + + p_out->m_metadata = 0; + + p_out->m_p_next_sibling = other.m_p_root; + + if (other.m_p_root != NULL) + other.m_p_root->m_p_prev_or_parent = p_out; + + other.m_p_root = p_out; + + other.m_p_root = other.fix(other.m_p_root); + + p_out = p_next; + } + + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + + node_pointer p_cur = base_type::m_p_root; + + base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = NULL; + + p_cur->m_metadata = 0; + + p_cur->m_p_next_sibling = base_type::m_p_root; + + if (base_type::m_p_root != NULL) + base_type::m_p_root->m_p_prev_or_parent = p_cur; + + base_type::m_p_root = p_cur; + + base_type::m_p_root = fix(base_type::m_p_root); + + p_cur = p_next; + } + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + + node_pointer p_other = other.m_p_root; + + if (p_other != NULL) + do + { + node_pointer p_next = p_other->m_p_next_sibling; + + std::swap(p_other->m_p_next_sibling, p_other->m_p_prev_or_parent); + + p_other = p_next; + } + while (p_other != NULL); + + base_type::m_p_root = join(base_type::m_p_root, other.m_p_root); + base_type::m_size += other.m_size; + m_p_max = NULL; + + other.m_p_root = NULL; + other.m_size = 0; + other.m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +join(node_pointer p_lhs, node_pointer p_rhs) const +{ + node_pointer p_ret = NULL; + + node_pointer p_cur = NULL; + + while (p_lhs != NULL || p_rhs != NULL) + { + if (p_rhs == NULL) + { + if (p_cur == NULL) + p_ret = p_cur = p_lhs; + else + { + p_cur->m_p_next_sibling = p_lhs; + + p_lhs->m_p_prev_or_parent = p_cur; + } + + p_cur = p_lhs = NULL; + } + else if (p_lhs == NULL || p_rhs->m_metadata < p_lhs->m_metadata) + { + if (p_cur == NULL) + { + p_ret = p_cur = p_rhs; + + p_rhs = p_rhs->m_p_prev_or_parent; + } + else + { + p_cur->m_p_next_sibling = p_rhs; + + p_rhs = p_rhs->m_p_prev_or_parent; + + p_cur->m_p_next_sibling->m_p_prev_or_parent = p_cur; + + p_cur = p_cur->m_p_next_sibling; + } + } + else if (p_lhs->m_metadata < p_rhs->m_metadata) + { + if (p_cur == NULL) + p_ret = p_cur = p_lhs; + else + { + p_cur->m_p_next_sibling = p_lhs; + + p_lhs->m_p_prev_or_parent = p_cur; + + p_cur = p_cur->m_p_next_sibling; + } + + p_lhs = p_cur->m_p_next_sibling; + } + else + { + node_pointer p_next_rhs = p_rhs->m_p_prev_or_parent; + + p_rhs->m_p_next_sibling = p_lhs; + + p_lhs = fix(p_rhs); + + p_rhs = p_next_rhs; + } + } + + if (p_cur != NULL) + p_cur->m_p_next_sibling = NULL; + + if (p_ret != NULL) + p_ret->m_p_prev_or_parent = NULL; + + return p_ret; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp new file mode 100644 index 0000000..c2b95e8 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp @@ -0,0 +1,647 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cc_ht_map_.hpp + * Contains an implementation class for cc_ht_map_. + */ + +#include <utility> +#include <iterator> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp> +#ifdef _GLIBCXX_DEBUG +#include <ext/pb_ds/detail/map_debug_base.hpp> +#endif +#ifdef PB_DS_HT_MAP_TRACE_ +#include <iostream> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Hash_Fn, \ + typename Eq_Fn, typename Allocator, bool Store_Hash, \ + typename Comb_Hash_Fn, typename Resize_Policy> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME cc_ht_map_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME cc_ht_map_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Hash_Fn, Eq_Fn, Allocator, \ + Store_Hash, Comb_Hash_Fn, Resize_Policy> + +#define PB_DS_HASH_EQ_FN_C_DEC \ + hash_eq_fn<Key, Eq_Fn, Allocator, Store_Hash> + +#define PB_DS_RANGED_HASH_FN_C_DEC \ + ranged_hash_fn<Key, Hash_Fn, Allocator, Comb_Hash_Fn, Store_Hash> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, Store_Hash> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, Eq_Fn, typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#endif + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> \ + UNIQUE##static_assert_type + + // <011i$i0|\|-<|-|4i|\|i|\|g |-|4$|-| 74813. + template<typename Key, + typename Mapped, + typename Hash_Fn, + typename Eq_Fn, + typename Allocator, + bool Store_Hash, + typename Comb_Hash_Fn, + typename Resize_Policy > + class PB_DS_CLASS_NAME: +#ifdef _GLIBCXX_DEBUG + protected PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif + public PB_DS_HASH_EQ_FN_C_DEC, + public Resize_Policy, + public PB_DS_RANGED_HASH_FN_C_DEC, + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + typedef typename traits_base::comp_hash comp_hash; + typedef typename traits_base::value_type value_type_; + typedef typename traits_base::pointer pointer_; + typedef typename traits_base::const_pointer const_pointer_; + typedef typename traits_base::reference reference_; + typedef typename traits_base::const_reference const_reference_; + + struct entry : public traits_base::stored_value_type + { + typename Allocator::template rebind<entry>::other::pointer m_p_next; + }; + + typedef cond_dealtor<entry, Allocator> cond_dealtor_t; + + typedef typename Allocator::template rebind<entry>::other entry_allocator; + typedef typename entry_allocator::pointer entry_pointer; + typedef typename entry_allocator::const_pointer const_entry_pointer; + typedef typename entry_allocator::reference entry_reference; + typedef typename entry_allocator::const_reference const_entry_reference; + + typedef typename Allocator::template rebind<entry_pointer>::other entry_pointer_allocator; + typedef typename entry_pointer_allocator::pointer entry_pointer_array; + + typedef PB_DS_RANGED_HASH_FN_C_DEC ranged_hash_fn_base; + typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; + typedef Resize_Policy resize_base; + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + +#define PB_DS_GEN_POS std::pair<entry_pointer, typename Allocator::size_type> + +#include <ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> + +#undef PB_DS_GEN_POS + + public: + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef Hash_Fn hash_fn; + typedef Eq_Fn eq_fn; + typedef Comb_Hash_Fn comb_hash_fn; + typedef Resize_Policy resize_policy; + + enum + { + store_hash = Store_Hash + }; + + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef point_iterator_ point_iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_point_iterator_ point_iterator; +#endif + + typedef const_point_iterator_ const_point_iterator; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef iterator_ iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_iterator_ iterator; +#endif + + typedef const_iterator_ const_iterator; + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const Hash_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&, + const Resize_Policy&); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + virtual + ~PB_DS_CLASS_NAME(); + + void + swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_range(It, It); + + void + initialize(); + + inline size_type + size() const; + + inline size_type + max_size() const; + + inline bool + empty() const; + + Hash_Fn& + get_hash_fn(); + + const Hash_Fn& + get_hash_fn() const; + + Eq_Fn& + get_eq_fn(); + + const Eq_Fn& + get_eq_fn() const; + + Comb_Hash_Fn& + get_comb_hash_fn(); + + const Comb_Hash_Fn& + get_comb_hash_fn() const; + + Resize_Policy& + get_resize_policy(); + + const Resize_Policy& + get_resize_policy() const; + + inline std::pair<point_iterator, bool> + insert(const_reference r_val) + { return insert_imp(r_val, traits_base::m_store_extra_indicator); } + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + return (subscript_imp(r_key, traits_base::m_store_extra_indicator)); +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline point_iterator + find(const_key_reference); + + inline const_point_iterator + find(const_key_reference) const; + + inline point_iterator + find_end(); + + inline const_point_iterator + find_end() const; + + inline bool + erase(const_key_reference); + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + clear(); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_HT_MAP_TRACE_ + void + trace() const; +#endif + + private: + void + deallocate_all(); + + inline bool + do_resize_if_needed(); + + inline void + do_resize_if_needed_no_throw(); + + void + resize_imp(size_type new_size); + + void + do_resize(size_type new_size); + + void + resize_imp_no_exceptions(size_type, entry_pointer_array, size_type); + + inline entry_pointer + resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, false_type); + + inline entry_pointer + resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, true_type); + + void + deallocate_links_in_list(entry_pointer); + + inline entry_pointer + get_entry(const_reference, false_type); + + inline entry_pointer + get_entry(const_reference, true_type); + + inline void + rels_entry(entry_pointer); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + inline mapped_reference + subscript_imp(const_key_reference r_key, false_type) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const size_type pos = ranged_hash_fn_base::operator()(r_key); + entry_pointer p_e = m_entries[pos]; + resize_base::notify_insert_search_start(); + + while (p_e != NULL + && !hash_eq_fn_base::operator()(p_e->m_value.first, r_key)) + { + resize_base::notify_insert_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_insert_search_end(); + if (p_e != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return (p_e->m_value.second); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return insert_new_imp(value_type(r_key, mapped_type()), pos)->second; + } + + inline mapped_reference + subscript_imp(const_key_reference r_key, true_type) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); + entry_pointer p_e = m_entries[pos_hash_pair.first]; + resize_base::notify_insert_search_start(); + while (p_e != NULL && + !hash_eq_fn_base::operator()(p_e->m_value.first, p_e->m_hash, r_key, pos_hash_pair.second)) + { + resize_base::notify_insert_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_insert_search_end(); + if (p_e != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return p_e->m_value.second; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return insert_new_imp(value_type(r_key, mapped_type()), + pos_hash_pair)->second; + } +#endif + + inline std::pair<point_iterator, bool> + insert_imp(const_reference, false_type); + + inline std::pair<point_iterator, bool> + insert_imp(const_reference, true_type); + + inline pointer + insert_new_imp(const_reference r_val, size_type pos) + { + if (do_resize_if_needed()) + pos = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); + + // Following lines might throw an exception. + entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); + + // At this point no exceptions can be thrown. + p_e->m_p_next = m_entries[pos]; + m_entries[pos] = p_e; + resize_base::notify_inserted(++m_num_used_e); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return &p_e->m_value; + } + + inline pointer + insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) + { + // Following lines might throw an exception. + if (do_resize_if_needed()) + r_pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); + + entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); + + // At this point no exceptions can be thrown. + p_e->m_hash = r_pos_hash_pair.second; + p_e->m_p_next = m_entries[r_pos_hash_pair.first]; + m_entries[r_pos_hash_pair.first] = p_e; + resize_base::notify_inserted(++m_num_used_e); + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return &p_e->m_value; + } + + inline pointer + find_key_pointer(const_key_reference r_key, false_type) + { + entry_pointer p_e = m_entries[ranged_hash_fn_base::operator()(r_key)]; + resize_base::notify_find_search_start(); + while (p_e != NULL && + !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) + { + resize_base::notify_find_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_find_search_end(); + +#ifdef _GLIBCXX_DEBUG + if (p_e == NULL) + map_debug_base::check_key_does_not_exist(r_key); + else + map_debug_base::check_key_exists(r_key); +#endif + return &p_e->m_value; + } + + inline pointer + find_key_pointer(const_key_reference r_key, true_type) + { + comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); + entry_pointer p_e = m_entries[pos_hash_pair.first]; + resize_base::notify_find_search_start(); + while (p_e != NULL && + !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), + p_e->m_hash, + r_key, pos_hash_pair.second)) + { + resize_base::notify_find_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_find_search_end(); + +#ifdef _GLIBCXX_DEBUG + if (p_e == NULL) + map_debug_base::check_key_does_not_exist(r_key); + else + map_debug_base::check_key_exists(r_key); +#endif + return &p_e->m_value; + } + + inline bool + erase_in_pos_imp(const_key_reference, size_type); + + inline bool + erase_in_pos_imp(const_key_reference, const comp_hash&); + + inline void + erase_entry_pointer(entry_pointer&); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + void + inc_it_state(pointer& r_p_value, + std::pair<entry_pointer, size_type>& r_pos) const + { + inc_it_state((const_mapped_pointer& )r_p_value, r_pos); + } +#endif + + void + inc_it_state(const_pointer& r_p_value, + std::pair<entry_pointer, size_type>& r_pos) const + { + _GLIBCXX_DEBUG_ASSERT(r_p_value != NULL); + r_pos.first = r_pos.first->m_p_next; + if (r_pos.first != NULL) + { + r_p_value = &r_pos.first->m_value; + return; + } + + for (++r_pos.second; r_pos.second < m_num_e; ++r_pos.second) + if (m_entries[r_pos.second] != NULL) + { + r_pos.first = m_entries[r_pos.second]; + r_p_value = &r_pos.first->m_value; + return; + } + r_p_value = NULL; + } + + void + get_start_it_state(pointer& r_p_value, + std::pair<entry_pointer, size_type>& r_pos) const + { + for (r_pos.second = 0; r_pos.second < m_num_e; ++r_pos.second) + if (m_entries[r_pos.second] != NULL) + { + r_pos.first = m_entries[r_pos.second]; + r_p_value = &r_pos.first->m_value; + return; + } + r_p_value = NULL; + } + +#ifdef _GLIBCXX_DEBUG + void + assert_entry_pointer_array_valid(const entry_pointer_array) const; + + void + assert_entry_pointer_valid(const entry_pointer, true_type) const; + + void + assert_entry_pointer_valid(const entry_pointer, false_type) const; +#endif + +#ifdef PB_DS_HT_MAP_TRACE_ + void + trace_list(const_entry_pointer) const; +#endif + + private: +#ifdef PB_DS_DATA_TRUE_INDICATOR + friend class iterator_; +#endif + + friend class const_iterator_; + + static entry_allocator s_entry_allocator; + static entry_pointer_allocator s_entry_pointer_allocator; + static iterator s_end_it; + static const_iterator s_const_end_it; + static point_iterator s_find_end_it; + static const_point_iterator s_const_find_end_it; + + size_type m_num_e; + size_type m_num_used_e; + entry_pointer_array m_entries; + + enum + { + store_hash_ok = !Store_Hash + || !is_same<Hash_Fn, pb_ds::null_hash_fn>::value + }; + + PB_DS_STATIC_ASSERT(sth, store_hash_ok); + }; + +#include <ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_HASH_EQ_FN_C_DEC +#undef PB_DS_RANGED_HASH_FN_C_DEC +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_V2F +#undef PB_DS_V2S +#undef PB_DS_STATIC_ASSERT + + } // namespace detail +} // namespace pb_ds + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hpp new file mode 100644 index 0000000..9223da5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hpp @@ -0,0 +1,89 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cmp_fn_imps.hpp + * Contains implementations of cc_ht_map_'s entire container comparison related + * functions. + */ + +PB_DS_CLASS_T_DEC +template<typename Other_HT_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +operator==(const Other_HT_Map_Type& other) const +{ return cmp_with_other(other); } + +PB_DS_CLASS_T_DEC +template<typename Other_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +cmp_with_other(const Other_Map_Type& other) const +{ + if (size() != other.size()) + return false; + + for (typename Other_Map_Type::const_iterator it = other.begin(); + it != other.end(); ++it) + { + const_key_reference r_key = const_key_reference(PB_DS_V2F(*it)); + + const_mapped_pointer p_mapped_value = + const_cast<PB_DS_CLASS_C_DEC& >(*this). + find_key_pointer(r_key, traits_base::m_store_hash_indicator); + + if (p_mapped_value == NULL) + return false; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + if (p_mapped_value->second != it->second) + return false; +#endif + } + return true; +} + +PB_DS_CLASS_T_DEC +template<typename Other_HT_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +operator!=(const Other_HT_Map_Type& other) const +{ return !operator==(other); } diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp new file mode 100644 index 0000000..bf5e0bd --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp @@ -0,0 +1,123 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_key_dtor_entry_dealtor.hpp + * Contains a conditional key destructor, used for exception handling. + */ + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC template<typename HT_Map> +#define PB_DS_CLASS_C_DEC PB_DS_CKDED_CLASS_NAME<HT_Map> + + /** + * A conditional key destructor, used for exception handling. + **/ + template<typename HT_Map> + class PB_DS_CKDED_CLASS_NAME + { + public: + typedef typename HT_Map::entry entry; + typedef typename HT_Map::entry_allocator entry_allocator; + typedef typename HT_Map::key_type key_type; + + inline + PB_DS_CKDED_CLASS_NAME(entry_allocator* p_a, entry* p_e); + + inline + ~PB_DS_CKDED_CLASS_NAME(); + + inline void + set_key_destruct(); + + inline void + set_no_action_destructor(); + + protected: + entry_allocator* const m_p_a; + entry* const m_p_e; + + bool m_key_destruct; + bool m_no_action_destructor; + }; + + PB_DS_CLASS_T_DEC + inline + PB_DS_CLASS_C_DEC:: + PB_DS_CKDED_CLASS_NAME(entry_allocator* p_a, entry* p_e) + : m_p_a(p_a), m_p_e(p_e), m_key_destruct(false), + m_no_action_destructor(false) + { } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + set_key_destruct() + { m_key_destruct = true; } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + set_no_action_destructor() + { m_no_action_destructor = true; } + + PB_DS_CLASS_T_DEC + inline + PB_DS_CLASS_C_DEC:: + ~PB_DS_CKDED_CLASS_NAME() + { + if (m_no_action_destructor) + return; + if (m_key_destruct) + m_p_e->m_value.first.~key_type(); + m_p_a->deallocate(m_p_e, 1); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp new file mode 100644 index 0000000..7da4d8a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp @@ -0,0 +1,197 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_fn_imps.hpp + * Contains implementations of cc_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_allocator +PB_DS_CLASS_C_DEC::s_entry_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_pointer_allocator +PB_DS_CLASS_C_DEC::s_entry_pointer_allocator; + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() : + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1)), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn) : + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) : + PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + std::fill(m_entries, m_entries + m_num_e, (entry_pointer)NULL); + Resize_Policy::notify_cleared(); + ranged_hash_fn_base::notify_resized(m_num_e); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn) : + PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, r_comb_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn, const Resize_Policy& r_resize_policy) : + PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), + Resize_Policy(r_resize_policy), + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, r_comb_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif + PB_DS_HASH_EQ_FN_C_DEC(other), + resize_base(other), ranged_hash_fn_base(other), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(m_entries = s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + try + { + copy_from_range(other.begin(), other.end()); + } + catch(...) + { + deallocate_all(); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ deallocate_all(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + + std::swap(m_entries, other.m_entries); + std::swap(m_num_e, other.m_num_e); + std::swap(m_num_used_e, other.m_num_used_e); + ranged_hash_fn_base::swap(other); + hash_eq_fn_base::swap(other); + resize_base::swap(other); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +deallocate_all() +{ + clear(); + s_entry_pointer_allocator.deallocate(m_entries, m_num_e); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ + std::fill(m_entries, m_entries + m_num_e, entry_pointer(NULL)); + Resize_Policy::notify_resized(m_num_e); + Resize_Policy::notify_cleared(); + ranged_hash_fn_base::notify_resized(m_num_e); +} diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..f2b41b3 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +constructor_insert_new_imp(const_mapped_reference r_val, size_type pos, + false_type) +{ + // Following lines might throw an exception. + entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); + + // At this point no exceptions can be thrown. + p->m_p_next = m_entries[pos]; + m_entries[pos] = p; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(r_key);) +} diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp new file mode 100644 index 0000000..08a0b7b --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp @@ -0,0 +1,62 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +constructor_insert_new_imp(const_reference r_val, size_type pos, true_type) +{ + // Following lines might throw an exception. + entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); + + // At this point no exceptions can be thrown. + p->m_p_next = m_entries[pos]; + p->m_hash = ranged_hash_fn_base::operator()((const_key_reference)(PB_DS_V2F(p->m_value))).second; + + m_entries[pos] = p; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(r_key);) +} diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp new file mode 100644 index 0000000..61cbfa9 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains implementations of cc_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + map_debug_base::check_size(m_num_used_e); + assert_entry_pointer_array_valid(m_entries); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_pointer_array_valid(const entry_pointer_array a_p_entries) const +{ + size_type iterated_num_used_e = 0; + for (size_type pos = 0; pos < m_num_e; ++pos) + { + entry_pointer p_e = a_p_entries[pos]; + while (p_e != NULL) + { + ++iterated_num_used_e; + assert_entry_pointer_valid(p_e, traits_base::m_store_hash_indicator); + p_e = p_e->m_p_next; + } + } + _GLIBCXX_DEBUG_ASSERT(iterated_num_used_e == m_num_used_e); +} + +#include <ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp> + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..d179a3d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp @@ -0,0 +1,55 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_pointer_valid(const entry_pointer p, false_type) const +{ map_debug_base::check_key_exists(PB_DS_V2F(p->m_value)); } + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp new file mode 100644 index 0000000..48dc555 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_pointer_valid(const entry_pointer p_e, true_type) const +{ + map_debug_base::check_key_exists(PB_DS_V2F(p_e->m_value)); + comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); + _GLIBCXX_DEBUG_ASSERT(p_e->m_hash == pos_hash_pair.second); +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp new file mode 100644 index 0000000..b887163 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file entry_list_fn_imps.hpp + * Contains implementations of cc_ht_map_'s entry-list related functions. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +deallocate_links_in_list(entry_pointer p_e) +{ + while (p_e != NULL) + { + entry_pointer p_dealloc_e = p_e; + p_e = p_e->m_p_next; + s_entry_allocator.deallocate(p_dealloc_e, 1); + } +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +get_entry(const_reference r_val, true_type) +{ + // Following line might throw an exception. + entry_pointer p_e = s_entry_allocator.allocate(1); + + // Following lines* cannot* throw an exception. + new (&p_e->m_value) value_type(r_val); + return p_e; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +get_entry(const_reference r_val, false_type) +{ + // Following line might throw an exception. + entry_pointer p_e = s_entry_allocator.allocate(1); + cond_dealtor_t cond(p_e); + + // Following lines might throw an exception. + new (&p_e->m_value) value_type(r_val); + cond.set_no_action(); + return p_e; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rels_entry(entry_pointer p_e) +{ + // The following lines cannot throw exceptions (unless if key-data dtors do). + p_e->m_value.~value_type(); + s_entry_allocator.deallocate(p_e, 1); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp new file mode 100644 index 0000000..265a705 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp @@ -0,0 +1,109 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains implementations of cc_ht_map_'s erase related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +erase_entry_pointer(entry_pointer& r_p_e) +{ + _GLIBCXX_DEBUG_ONLY(map_debug_base::erase_existing(PB_DS_V2F(r_p_e->m_value))); + + entry_pointer p_e = r_p_e; + r_p_e = r_p_e->m_p_next; + rels_entry(p_e); + _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); + resize_base::notify_erased(--m_num_used_e); +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + size_type num_ersd = 0; + for (size_type pos = 0; pos < m_num_e; ++pos) + { + while (m_entries[pos] != NULL && pred(m_entries[pos]->m_value)) + { + ++num_ersd; + entry_pointer p_next_e = m_entries[pos]->m_p_next; + erase_entry_pointer(m_entries[pos]); + m_entries[pos] = p_next_e; + } + + entry_pointer p_e = m_entries[pos]; + while (p_e != NULL && p_e->m_p_next != NULL) + { + if (pred(p_e->m_p_next->m_value)) + { + ++num_ersd; + erase_entry_pointer(p_e->m_p_next); + } + else + p_e = p_e->m_p_next; + } + } + + do_resize_if_needed_no_throw(); + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + for (size_type pos = 0; pos < m_num_e; ++pos) + while (m_entries[pos] != NULL) + erase_entry_pointer(m_entries[pos]); + do_resize_if_needed_no_throw(); + resize_base::notify_cleared(); +} + +#include <ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp> + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..13a3a6d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp @@ -0,0 +1,107 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s erase related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return erase_in_pos_imp(r_key, ranged_hash_fn_base::operator()(r_key)); +} + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase_in_pos_imp(const_key_reference r_key, size_type pos) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_e = m_entries[pos]; + resize_base::notify_erase_search_start(); + if (p_e == NULL) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return false; + } + + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base:: check_key_exists(r_key);) + erase_entry_pointer(m_entries[pos]); + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; + } + + while (true) + { + entry_pointer p_next_e = p_e->m_p_next; + if (p_next_e == NULL) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return false; + } + + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), r_key)) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + erase_entry_pointer(p_e->m_p_next); + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; + } + resize_base::notify_erase_search_collision(); + p_e = p_next_e; + } +} + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp new file mode 100644 index 0000000..7eb821e --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp @@ -0,0 +1,101 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s erase related functions, + * when the hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase_in_pos_imp(const_key_reference r_key, const comp_hash& r_pos_hash_pair) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_e = m_entries[r_pos_hash_pair.first]; + resize_base::notify_erase_search_start(); + if (p_e == NULL) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base:: check_key_does_not_exist(r_key);) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return false; + } + + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, + r_key, r_pos_hash_pair.second)) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + erase_entry_pointer(m_entries[r_pos_hash_pair.first]); + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; + } + + while (true) + { + entry_pointer p_next_e = p_e->m_p_next; + if (p_next_e == NULL) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return false; + } + + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), + p_next_e->m_hash, r_key, + r_pos_hash_pair.second)) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + erase_entry_pointer(p_e->m_p_next); + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; + } + resize_base::notify_erase_search_collision(); + p_e = p_next_e; + } +} + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp new file mode 100644 index 0000000..1a72664 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp @@ -0,0 +1,77 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains implementations of cc_ht_map_'s find related functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return find_key_pointer(r_key, traits_base::m_store_extra_indicator); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return const_cast<PB_DS_CLASS_C_DEC& >(*this).find_key_pointer(r_key, + traits_base::m_store_extra_indicator); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find_end() +{ return NULL; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find_end() const +{ return NULL; } + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp new file mode 100644 index 0000000..423a59a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp @@ -0,0 +1,47 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s find related functions, + * when the hash value is stored. + */ + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp new file mode 100644 index 0000000..519072a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp @@ -0,0 +1,106 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains implementations of cc_ht_map_'s entire container info related + * functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return m_num_used_e; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return m_entry_allocator.max_size(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (size() == 0); } + +PB_DS_CLASS_T_DEC +template<typename Other_HT_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +operator==(const Other_HT_Map_Type& other) const +{ return cmp_with_other(other); } + +PB_DS_CLASS_T_DEC +template<typename Other_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +cmp_with_other(const Other_Map_Type& other) const +{ + if (size() != other.size()) + return false; + + for (typename Other_Map_Type::const_iterator it = other.begin(); + it != other.end(); ++it) + { + const_key_reference r_key =(const_key_reference)PB_DS_V2F(*it); + const_mapped_pointer p_mapped_value = + const_cast<PB_DS_CLASS_C_DEC& >(*this). + find_key_pointer(r_key, traits_base::m_store_hash_indicator); + + if (p_mapped_value == NULL) + return false; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + if (p_mapped_value->second != it->second) + return false; +#endif + } + return true; +} + +PB_DS_CLASS_T_DEC +template<typename Other_HT_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +operator!=(const Other_HT_Map_Type& other) const +{ return !operator==(other); } diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp new file mode 100644 index 0000000..2726073 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp @@ -0,0 +1,49 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains implementations of cc_ht_map_'s insert related functions. + */ + +#include <ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp> + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..fd158f9 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp @@ -0,0 +1,76 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s insert related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_imp(const_reference r_val, false_type) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const_key_reference r_key = PB_DS_V2F(r_val); + const size_type pos = ranged_hash_fn_base::operator()(r_key); + entry_pointer p_e = m_entries[pos]; + resize_base::notify_insert_search_start(); + + while (p_e != NULL && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), + r_key)) + { + resize_base::notify_insert_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_insert_search_end(); + if (p_e != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return std::make_pair(&p_e->m_value, false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return std::make_pair(insert_new_imp(r_val, pos), true); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp new file mode 100644 index 0000000..128e11f --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp @@ -0,0 +1,77 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s insert related functions, + * when the hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_imp(const_reference r_val, true_type) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const_key_reference key = PB_DS_V2F(r_val); + comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(key); + entry_pointer p_e = m_entries[pos_hash_pair.first]; + resize_base::notify_insert_search_start(); + + while (p_e != NULL && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), + p_e->m_hash, + key, pos_hash_pair.second)) + { + resize_base::notify_insert_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_insert_search_end(); + if (p_e != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key);) + return std::make_pair(&p_e->m_value, false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp new file mode 100644 index 0000000..2c4f6ae --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp @@ -0,0 +1,89 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains implementations of cc_ht_map_'s iterators related functions, e.g., + * begin(). + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC::s_end_it; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC::s_const_end_it; + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + pointer p_value; + std::pair<entry_pointer, size_type> pos; + get_start_it_state(p_value, pos); + return iterator(p_value, pos, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ return s_end_it; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + pointer p_value; + std::pair<entry_pointer, size_type> pos; + get_start_it_state(p_value, pos); + return const_iterator(p_value, pos, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ return s_const_end_it; } + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp new file mode 100644 index 0000000..6c03d45 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp @@ -0,0 +1,94 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains implementations of cc_ht_map_'s policy access + * functions. + */ + +PB_DS_CLASS_T_DEC +Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_hash_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_hash_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Eq_Fn& +PB_DS_CLASS_C_DEC:: +get_eq_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Eq_Fn& +PB_DS_CLASS_C_DEC:: +get_eq_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Comb_Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_comb_hash_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Comb_Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_comb_hash_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Resize_Policy& +PB_DS_CLASS_C_DEC:: +get_resize_policy() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Resize_Policy& +PB_DS_CLASS_C_DEC:: +get_resize_policy() const +{ return *this; } diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp new file mode 100644 index 0000000..eda2c48 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp @@ -0,0 +1,139 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_fn_imps.hpp + * Contains implementations of cc_ht_map_'s resize related functions. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +do_resize_if_needed() +{ + if (!resize_base::is_resize_needed()) + return false; + resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +do_resize(size_type len) +{ resize_imp(resize_base::get_nearest_larger_size(len)); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +do_resize_if_needed_no_throw() +{ + if (!resize_base::is_resize_needed()) + return; + + try + { + resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); + } + catch(...) + { } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize_imp(size_type new_size) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (new_size == m_num_e) + return; + + const size_type old_size = m_num_e; + entry_pointer_array a_p_entries_resized; + + // Following line might throw an exception. + ranged_hash_fn_base::notify_resized(new_size); + + try + { + // Following line might throw an exception. + a_p_entries_resized = s_entry_pointer_allocator.allocate(new_size); + m_num_e = new_size; + } + catch(...) + { + ranged_hash_fn_base::notify_resized(old_size); + __throw_exception_again; + } + + // At this point no exceptions can be thrown. + resize_imp_no_exceptions(new_size, a_p_entries_resized, old_size); + Resize_Policy::notify_resized(new_size); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize_imp_no_exceptions(size_type new_size, entry_pointer_array a_p_entries_resized, size_type old_size) +{ + std::fill(a_p_entries_resized, a_p_entries_resized + m_num_e, + entry_pointer(NULL)); + + for (size_type pos = 0; pos < old_size; ++pos) + { + entry_pointer p_e = m_entries[pos]; + while (p_e != NULL) + p_e = resize_imp_no_exceptions_reassign_pointer(p_e, a_p_entries_resized, traits_base::m_store_extra_indicator); + } + + m_num_e = new_size; + _GLIBCXX_DEBUG_ONLY(assert_entry_pointer_array_valid(a_p_entries_resized);) + s_entry_pointer_allocator.deallocate(m_entries, old_size); + m_entries = a_p_entries_resized; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +#include <ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp> + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..5fb7f9d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp @@ -0,0 +1,60 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s resize related functions, when the + * hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, false_type) +{ + const size_type hash_pos = + ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); + + entry_pointer const p_next_e = p_e->m_p_next; + p_e->m_p_next = a_p_entries_resized[hash_pos]; + a_p_entries_resized[hash_pos] = p_e; + return p_next_e; +} diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp new file mode 100644 index 0000000..3874105 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp @@ -0,0 +1,60 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s resize related functions, when the + * hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, true_type) +{ + const comp_hash pos_hash_pair = + ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash); + + entry_pointer const p_next_e = p_e->m_p_next; + p_e->m_p_next = a_p_entries_resized[pos_hash_pair.first]; + a_p_entries_resized[pos_hash_pair.first] = p_e; + return p_next_e; +} diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp new file mode 100644 index 0000000..8fee010 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp @@ -0,0 +1,65 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file size_fn_imps.hpp + * Contains implementations of cc_ht_map_'s entire container size related + * functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return m_num_used_e; } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (size() == 0); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_entry_allocator.max_size(); } + diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/standard_policies.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/standard_policies.hpp new file mode 100644 index 0000000..dc175b1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/standard_policies.hpp @@ -0,0 +1,52 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file standard_policies.hpp + * Contains standard policies for cc_ht_map types. + */ + +#ifndef PB_DS_CC_HT_MAP_STANDARD_POLICIES_HPP +#define PB_DS_CC_HT_MAP_STANDARD_POLICIES_HPP + +#include <ext/pb_ds/detail/standard_policies.hpp> + +#endif // #ifndef PB_DS_CC_HT_MAP_STANDARD_POLICIES_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp new file mode 100644 index 0000000..21097de --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains implementations of cc_ht_map_'s trace-mode functions. + */ + +#ifdef PB_DS_HT_MAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << static_cast<unsigned long>(m_num_e) << " " + << static_cast<unsigned long>(m_num_used_e) << std::endl; + + for (size_type i = 0; i < m_num_e; ++i) + { + std::cerr << static_cast<unsigned long>(i) << " "; + trace_list(m_entries[i]); + std::cerr << std::endl; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_list(const_entry_pointer p_l) const +{ + size_type iterated_num_used_e = 0; + while (p_l != NULL) + { + std::cerr << PB_DS_V2F(p_l->m_value) << " "; + p_l = p_l->m_p_next; + } +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/cond_dealtor.hpp b/libstdc++/include/ext/pb_ds/detail/cond_dealtor.hpp new file mode 100644 index 0000000..3cf9ea9 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/cond_dealtor.hpp @@ -0,0 +1,131 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_dealtor.hpp + * Contains a conditional deallocator. + */ + +#ifndef PB_DS_COND_DEALTOR_HPP +#define PB_DS_COND_DEALTOR_HPP + +namespace pb_ds +{ + + namespace detail + { + +#define PB_DS_COND_DEALTOR_CLASS_T_DEC \ + template<typename Entry, class Allocator> + +#define PB_DS_COND_DEALTOR_CLASS_C_DEC \ + cond_dealtor< \ + Entry, \ + Allocator> + + template<typename Entry, class Allocator> + class cond_dealtor + { + public: + typedef + typename Allocator::template rebind<Entry>::other + entry_allocator; + + typedef typename entry_allocator::pointer entry_pointer; + + public: + inline + cond_dealtor(entry_pointer p_e); + + inline + ~cond_dealtor(); + + inline void + set_no_action(); + + private: + entry_pointer m_p_e; + + bool m_no_action_destructor; + + static entry_allocator s_alloc; + }; + + PB_DS_COND_DEALTOR_CLASS_T_DEC + typename PB_DS_COND_DEALTOR_CLASS_C_DEC::entry_allocator + PB_DS_COND_DEALTOR_CLASS_C_DEC::s_alloc; + + PB_DS_COND_DEALTOR_CLASS_T_DEC + inline + PB_DS_COND_DEALTOR_CLASS_C_DEC:: + cond_dealtor(entry_pointer p_e) : + m_p_e(p_e), + m_no_action_destructor(false) + { } + + PB_DS_COND_DEALTOR_CLASS_T_DEC + inline void + PB_DS_COND_DEALTOR_CLASS_C_DEC:: + set_no_action() + { + m_no_action_destructor = true; + } + + PB_DS_COND_DEALTOR_CLASS_T_DEC + inline + PB_DS_COND_DEALTOR_CLASS_C_DEC:: + ~cond_dealtor() + { + if (m_no_action_destructor) + return; + + s_alloc.deallocate(m_p_e, 1); + } + +#undef PB_DS_COND_DEALTOR_CLASS_T_DEC +#undef PB_DS_COND_DEALTOR_CLASS_C_DEC + + } // namespace detail + +} // namespace pb_ds + +#endif // #ifndef PB_DS_COND_DEALTOR_HPP + diff --git a/libstdc++/include/ext/pb_ds/detail/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..9176366 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/constructors_destructor_fn_imps.hpp @@ -0,0 +1,109 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains constructors_destructor_fn_imps applicable to different containers. + */ + +inline +PB_DS_CLASS_NAME() +{ } + +inline +PB_DS_CLASS_NAME(const PB_DS_CLASS_NAME& other) +: base_type((const base_type&)other) +{ } + +template<typename T0> +inline +PB_DS_CLASS_NAME(T0 t0) : base_type(t0) +{ } + +template<typename T0, typename T1> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1) : base_type(t0, t1) +{ } + +template<typename T0, typename T1, typename T2> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2) : base_type(t0, t1, t2) +{ } + +template<typename T0, typename T1, typename T2, typename T3> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3) +: base_type(t0, t1, t2, t3) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) +: base_type(t0, t1, t2, t3, t4) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) +: base_type(t0, t1, t2, t3, t4, t5) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) +: base_type(t0, t1, t2, t3, t4, t5, t6) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) +: base_type(t0, t1, t2, t3, t4, t5, t6, t7) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) +: base_type(t0, t1, t2, t3, t4, t5, t6, t7, t8) +{ } diff --git a/libstdc++/include/ext/pb_ds/detail/container_base_dispatch.hpp b/libstdc++/include/ext/pb_ds/detail/container_base_dispatch.hpp new file mode 100644 index 0000000..37db003 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/container_base_dispatch.hpp @@ -0,0 +1,338 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file container_base_dispatch.hpp + * Contains an associative container dispatching base. + */ + +#ifndef PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP +#define PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP + +#include <ext/typelist.h> + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/list_update_map_/lu_map_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/list_update_map_/lu_map_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/splay_tree_/splay_tree_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/splay_tree_/splay_tree_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/pat_trie_/pat_trie_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/pat_trie_/pat_trie_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +namespace pb_ds +{ +namespace detail +{ + // Primary template. + template<typename Key, typename Mapped, typename Data_Structure_Taq, + typename Policy_Tl, typename Alloc> + struct container_base_dispatch; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, list_update_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef lu_map_data_<Key, Mapped, at0t, Alloc, at1t> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, list_update_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef lu_map_no_data_<Key, null_mapped_type, at0t, Alloc, at1t> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, pat_trie_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef pat_trie_data_<Key, Mapped, at1t, Alloc> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, pat_trie_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef pat_trie_no_data_<Key, null_mapped_type, at1t, Alloc> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, rb_tree_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef rb_tree_data_<Key, Mapped, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, rb_tree_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef rb_tree_no_data_<Key, null_mapped_type, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, splay_tree_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef splay_tree_data_<Key, Mapped, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, splay_tree_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef splay_tree_no_data_<Key, null_mapped_type, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, ov_tree_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef ov_tree_data_<Key, Mapped, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, ov_tree_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef ov_tree_no_data_<Key, null_mapped_type, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, cc_hash_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; + typedef typename at2::type at2t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; + typedef typename at3::type at3t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; + typedef typename at4::type at4t; + + public: + typedef cc_ht_map_data_<Key, Mapped, at0t, at1t, Alloc, at3t::value, + at4t, at2t> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, cc_hash_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; + typedef typename at2::type at2t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; + typedef typename at3::type at3t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; + typedef typename at4::type at4t; + + public: + typedef cc_ht_map_no_data_<Key, null_mapped_type, at0t, at1t, Alloc, + at3t::value, at4t, at2t> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, gp_hash_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; + typedef typename at2::type at2t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; + typedef typename at3::type at3t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; + typedef typename at4::type at4t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 5> at5; + typedef typename at5::type at5t; + + public: + typedef gp_ht_map_data_<Key, Mapped, at0t, at1t, Alloc, at3t::value, + at4t, at5t, at2t> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, gp_hash_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; + typedef typename at2::type at2t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; + typedef typename at3::type at3t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; + typedef typename at4::type at4t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 5> at5; + typedef typename at5::type at5t; + + public: + typedef gp_ht_map_no_data_<Key, null_mapped_type, at0t, at1t, Alloc, + at3t::value, at4t, at5t, at2t> type; + }; +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/eq_fn/eq_by_less.hpp b/libstdc++/include/ext/pb_ds/detail/eq_fn/eq_by_less.hpp new file mode 100644 index 0000000..6e37b54 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/eq_fn/eq_by_less.hpp @@ -0,0 +1,74 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file eq_by_less.hpp + * Contains an equivalence function. + */ + +#ifndef PB_DS_EQ_BY_LESS_HPP +#define PB_DS_EQ_BY_LESS_HPP + +#include <utility> +#include <functional> +#include <vector> +#include <assert.h> +#include <ext/pb_ds/detail/types_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, class Cmp_Fn> + struct eq_by_less : private Cmp_Fn + { + bool + operator()(const Key& r_lhs, const Key& r_rhs) const + { + const bool l = Cmp_Fn::operator()(r_lhs, r_rhs); + const bool g = Cmp_Fn::operator()(r_rhs, r_lhs); + return !(l || g); + } + }; + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_EQ_BY_LESS_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp b/libstdc++/include/ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp new file mode 100644 index 0000000..8218ea4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp @@ -0,0 +1,185 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_eq_fn.hpp + * Contains 2 eqivalence functions, one employing a hash value, + * and one ignoring it. + */ + +#ifndef PB_DS_HASH_EQ_FN_HPP +#define PB_DS_HASH_EQ_FN_HPP + +#include <utility> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, class Eq_Fn, class Allocator, bool Store_Hash> + struct hash_eq_fn; + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, class Eq_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + hash_eq_fn<Key, Eq_Fn, Allocator, false> + + /** + * Specialization 1- The client requests that hash values not be stored. + **/ + template<typename Key, class Eq_Fn, class Allocator> + struct hash_eq_fn<Key, Eq_Fn, Allocator, false> : public Eq_Fn + { + typedef Eq_Fn eq_fn_base; + + typedef typename Allocator::template rebind<Key>::other key_allocator; + + typedef typename key_allocator::const_reference const_key_reference; + + hash_eq_fn(); + + hash_eq_fn(const Eq_Fn& r_eq_fn); + + inline bool + operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const; + + inline void + swap(const PB_DS_CLASS_C_DEC& other); + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + hash_eq_fn() + { } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + swap(const PB_DS_CLASS_C_DEC& other) + { std::swap((Eq_Fn& )(*this), (Eq_Fn& )other); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + hash_eq_fn(const Eq_Fn& r_eq_fn) : + Eq_Fn(r_eq_fn) + { } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const + { return (eq_fn_base::operator()(r_lhs_key, r_rhs_key)); } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, class Eq_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + hash_eq_fn<Key, Eq_Fn, Allocator, true> + + /** + * Specialization 2- The client requests that hash values be stored. + **/ + template<typename Key, class Eq_Fn, class Allocator> + struct hash_eq_fn<Key, Eq_Fn, Allocator, true> : + public Eq_Fn + { + typedef typename Allocator::size_type size_type; + + typedef Eq_Fn eq_fn_base; + + typedef typename Allocator::template rebind<Key>::other key_allocator; + + typedef typename key_allocator::const_reference const_key_reference; + + hash_eq_fn(); + + hash_eq_fn(const Eq_Fn& r_eq_fn); + + inline bool + operator()(const_key_reference r_lhs_key, size_type lhs_hash, + const_key_reference r_rhs_key, size_type rhs_hash) const; + + inline void + swap(const PB_DS_CLASS_C_DEC& other); + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + hash_eq_fn() + { } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + hash_eq_fn(const Eq_Fn& r_eq_fn) : + Eq_Fn(r_eq_fn) + { } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_lhs_key, size_type lhs_hash, + const_key_reference r_rhs_key, size_type rhs_hash) const + { + _GLIBCXX_DEBUG_ASSERT(!eq_fn_base::operator()(r_lhs_key, r_rhs_key) + || lhs_hash == rhs_hash); + + return (lhs_hash == rhs_hash && + eq_fn_base::operator()(r_lhs_key, r_rhs_key)); + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + swap(const PB_DS_CLASS_C_DEC& other) + { std::swap((Eq_Fn& )(*this), (Eq_Fn& )(other)); } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp new file mode 100644 index 0000000..30b8d3e --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp @@ -0,0 +1,229 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_fn_imps.hpp + * Contains implementations of gp_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_allocator +PB_DS_CLASS_C_DEC::s_entry_allocator; + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() +: ranged_probe_fn_base(resize_base::get_nearest_larger_size(1)), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn) +: ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) +: hash_eq_fn_base(r_eq_fn), + ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, + const Comb_Probe_Fn& r_comb_hash_fn) +: hash_eq_fn_base(r_eq_fn), + ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, r_comb_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, + const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober) +: hash_eq_fn_base(r_eq_fn), + ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, comb_hash_fn, prober), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, + const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober, + const Resize_Policy& r_resize_policy) +: hash_eq_fn_base(r_eq_fn), resize_base(r_resize_policy), + ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, comb_hash_fn, prober), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif + hash_eq_fn_base(other), + resize_base(other), + ranged_probe_fn_base(other), + m_num_e(other.m_num_e), + m_num_used_e(other.m_num_used_e), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + for (size_type i = 0; i < m_num_e; ++i) + m_entries[i].m_stat = (entry_status)empty_entry_status; + + try + { + for (size_type i = 0; i < m_num_e; ++i) + { + m_entries[i].m_stat = other.m_entries[i].m_stat; + if (m_entries[i].m_stat == valid_entry_status) + new (m_entries + i) entry(other.m_entries[i]); + } + } + catch(...) + { + deallocate_all(); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ deallocate_all(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + std::swap(m_num_e, other.m_num_e); + std::swap(m_num_used_e, other.m_num_used_e); + std::swap(m_entries, other.m_entries); + ranged_probe_fn_base::swap(other); + hash_eq_fn_base::swap(other); + resize_base::swap(other); + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +deallocate_all() +{ + clear(); + erase_all_valid_entries(m_entries, m_num_e); + s_entry_allocator.deallocate(m_entries, m_num_e); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_all_valid_entries(entry_array a_entries_resized, size_type len) +{ + for (size_type pos = 0; pos < len; ++pos) + { + entry_pointer p_e = &a_entries_resized[pos]; + if (p_e->m_stat == valid_entry_status) + p_e->m_value.~value_type(); + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ + Resize_Policy::notify_resized(m_num_e); + Resize_Policy::notify_cleared(); + ranged_probe_fn_base::notify_resized(m_num_e); + for (size_type i = 0; i < m_num_e; ++i) + m_entries[i].m_stat = empty_entry_status; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..df4af95 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +constructor_insert_new_imp(const_mapped_reference r_val, size_type pos, + false_type) +{ + _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status)k; + entry* const p_e = m_entries + pos; + new (&p_e->m_value) mapped_value_type(r_val); + p_e->m_stat = valid_entry_status; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(p_e->m_value.first);) +} diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp new file mode 100644 index 0000000..0e17e36 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp @@ -0,0 +1,60 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +constructor_insert_new_imp(const_mapped_reference r_val, size_type pos, + true_type) +{ + _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); + entry* const p_e = m_entries + pos; + new (&p_e->m_value) mapped_value_type(r_val); + p_e->m_hash = ranged_probe_fn_base::operator()(PB_DS_V2F(r_val)).second; + p_e->m_stat = valid_entry_status; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(p_e->m_value.first);) +} diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp new file mode 100644 index 0000000..fd8ca9a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains implementations of gp_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + map_debug_base::check_size(m_num_used_e); + assert_entry_array_valid(m_entries, traits_base::m_store_extra_indicator); +} + +#include <ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp> + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..9d3d428 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp @@ -0,0 +1,77 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_array_valid(const entry_array a_entries, false_type) const +{ + size_type iterated_num_used_e = 0; + for (size_type pos = 0; pos < m_num_e; ++pos) + { + const_entry_pointer p_e = &a_entries[pos]; + switch(p_e->m_stat) + { + case empty_entry_status: + case erased_entry_status: + break; + case valid_entry_status: + { + const_key_reference r_key = PB_DS_V2F(p_e->m_value); + map_debug_base::check_key_exists(r_key); + ++iterated_num_used_e; + break; + } + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + } + _GLIBCXX_DEBUG_ASSERT(iterated_num_used_e == m_num_used_e); +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp new file mode 100644 index 0000000..a4d8b6c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp @@ -0,0 +1,83 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_array_valid(const entry_array a_entries, true_type) const +{ + size_type iterated_num_used_e = 0; + + for (size_type pos = 0; pos < m_num_e; ++pos) + { + const_entry_pointer p_e =& a_entries[pos]; + switch(p_e->m_stat) + { + case empty_entry_status: + case erased_entry_status: + break; + case valid_entry_status: + { + const_key_reference r_key = PB_DS_V2F(p_e->m_value); + map_debug_base::check_key_exists(r_key); + + const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); + + _GLIBCXX_DEBUG_ASSERT(p_e->m_hash == pos_hash_pair.second); + ++iterated_num_used_e; + break; + } + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + } + + _GLIBCXX_DEBUG_ASSERT(iterated_num_used_e == m_num_used_e); +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp new file mode 100644 index 0000000..9da8507 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp @@ -0,0 +1,106 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains implementations of gp_ht_map_'s erase related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +erase_entry(entry_pointer p_e) +{ + _GLIBCXX_DEBUG_ASSERT(p_e->m_stat = valid_entry_status); + _GLIBCXX_DEBUG_ONLY(map_debug_base::erase_existing(PB_DS_V2F(p_e->m_value));) + p_e->m_value.~value_type(); + p_e->m_stat = erased_entry_status; + _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); + resize_base::notify_erased(--m_num_used_e); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + for (size_type pos = 0; pos < m_num_e; ++pos) + { + entry_pointer p_e = &m_entries[pos]; + if (p_e->m_stat == valid_entry_status) + erase_entry(p_e); + } + do_resize_if_needed_no_throw(); + resize_base::notify_cleared(); +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + size_type num_ersd = 0; + for (size_type pos = 0; pos < m_num_e; ++pos) + { + entry_pointer p_e = &m_entries[pos]; + if (p_e->m_stat == valid_entry_status) + if (pred(p_e->m_value)) + { + ++num_ersd; + erase_entry(p_e); + } + } + + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ return erase_imp(r_key, traits_base::m_store_extra_indicator); } + +#include <ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp> diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..51acec9 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp @@ -0,0 +1,91 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s erase related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase_imp(const_key_reference r_key, false_type) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + size_type hash = ranged_probe_fn_base::operator()(r_key); + size_type i; + resize_base::notify_erase_search_start(); + + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); + entry* const p_e = m_entries + pos; + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist( + r_key)); + return false; + } + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) + { + resize_base::notify_erase_search_end(); + erase_entry(p_e); + do_resize_if_needed_no_throw(); + return true; + } + break; + case erased_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + resize_base::notify_erase_search_collision(); + } + resize_base::notify_erase_search_end(); + return false; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp new file mode 100644 index 0000000..71c498b --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp @@ -0,0 +1,92 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s erase related functions, + * when the hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase_imp(const_key_reference r_key, true_type) +{ + const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); + size_type i; + resize_base::notify_erase_search_start(); + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); + + entry* const p_e = m_entries + pos; + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist( + r_key)); + return false; + } + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, + r_key, pos_hash_pair.second)) + { + resize_base::notify_erase_search_end(); + erase_entry(p_e); + do_resize_if_needed_no_throw(); + return true; + } + break; + case erased_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + resize_base::notify_erase_search_collision(); + } + resize_base::notify_erase_search_end(); + return false; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp new file mode 100644 index 0000000..604dc40 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp @@ -0,0 +1,76 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains implementations of gp_ht_map_'s find related functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return find_key_pointer(r_key, traits_base::m_store_extra_indicator); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return const_cast<PB_DS_CLASS_C_DEC&>(*this).find_key_pointer(r_key, traits_base::m_store_extra_indicator); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find_end() +{ return NULL; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find_end() const +{ return NULL; } + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..a134f33 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp @@ -0,0 +1,52 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s find related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::pointer +PB_DS_CLASS_C_DEC:: +find_key_pointer(const_key_reference r_key, false_type) + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp new file mode 100644 index 0000000..e43c129 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp @@ -0,0 +1,46 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s insert related functions, + * when the hash value is stored. + */ diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp new file mode 100644 index 0000000..4a2ae40 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp @@ -0,0 +1,688 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file gp_ht_map_.hpp + * Contains an implementation class for gp_ht_map_. + */ + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp> +#include <utility> +#ifdef PB_DS_HT_MAP_TRACE_ +#include <iostream> +#endif +#ifdef _GLIBCXX_DEBUG +#include <ext/pb_ds/detail/map_debug_base.hpp> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Hash_Fn, typename Eq_Fn, \ + typename Allocator, bool Store_Hash, typename Comb_Probe_Fn, \ + typename Probe_Fn, typename Resize_Policy> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME gp_ht_map_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME gp_ht_map_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Hash_Fn, Eq_Fn, Allocator, \ + Store_Hash, Comb_Probe_Fn, Probe_Fn, Resize_Policy> + +#define PB_DS_HASH_EQ_FN_C_DEC \ + hash_eq_fn<Key, Eq_Fn, Allocator, Store_Hash> + +#define PB_DS_RANGED_PROBE_FN_C_DEC \ + ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, Probe_Fn, Store_Hash> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, Store_Hash> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, Eq_Fn, typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped() +#endif + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> \ + UNIQUE##static_assert_type + + template<typename Key, + typename Mapped, + typename Hash_Fn, + typename Eq_Fn, + typename Allocator, + bool Store_Hash, + typename Comb_Probe_Fn, + typename Probe_Fn, + typename Resize_Policy> + class PB_DS_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + protected PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif + public PB_DS_HASH_EQ_FN_C_DEC, + public Resize_Policy, + public PB_DS_RANGED_PROBE_FN_C_DEC, + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + typedef typename traits_base::value_type value_type_; + typedef typename traits_base::pointer pointer_; + typedef typename traits_base::const_pointer const_pointer_; + typedef typename traits_base::reference reference_; + typedef typename traits_base::const_reference const_reference_; + typedef typename traits_base::comp_hash comp_hash; + + enum entry_status + { + empty_entry_status, + valid_entry_status, + erased_entry_status + } __attribute__ ((packed)); + + struct entry : public traits_base::stored_value_type + { + entry_status m_stat; + }; + + typedef typename Allocator::template rebind<entry>::other entry_allocator; + typedef typename entry_allocator::pointer entry_pointer; + typedef typename entry_allocator::const_pointer const_entry_pointer; + typedef typename entry_allocator::reference entry_reference; + typedef typename entry_allocator::const_reference const_entry_reference; + typedef typename entry_allocator::pointer entry_array; + + typedef PB_DS_RANGED_PROBE_FN_C_DEC ranged_probe_fn_base; + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + + typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; + typedef Resize_Policy resize_base; + +#define PB_DS_GEN_POS typename Allocator::size_type + +#include <ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> + +#undef PB_DS_GEN_POS + + public: + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef Hash_Fn hash_fn; + typedef Eq_Fn eq_fn; + typedef Probe_Fn probe_fn; + typedef Comb_Probe_Fn comb_probe_fn; + typedef Resize_Policy resize_policy; + + enum + { + store_hash = Store_Hash + }; + + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef point_iterator_ point_iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_point_iterator_ point_iterator; +#endif + + typedef const_point_iterator_ const_point_iterator; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef iterator_ iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_iterator_ iterator; +#endif + + typedef const_iterator_ const_iterator; + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + PB_DS_CLASS_NAME(const Hash_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, + const Probe_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, + const Probe_Fn&, const Resize_Policy&); + + template<typename It> + void + copy_from_range(It first_it, It last_it); + + virtual + ~PB_DS_CLASS_NAME(); + + void + swap(PB_DS_CLASS_C_DEC& other); + + inline size_type + size() const; + + inline size_type + max_size() const; + + inline bool + empty() const; + + Hash_Fn& + get_hash_fn(); + + const Hash_Fn& + get_hash_fn() const; + + Eq_Fn& + get_eq_fn(); + + const Eq_Fn& + get_eq_fn() const; + + Probe_Fn& + get_probe_fn(); + + const Probe_Fn& + get_probe_fn() const; + + Comb_Probe_Fn& + get_comb_probe_fn(); + + const Comb_Probe_Fn& + get_comb_probe_fn() const; + + Resize_Policy& + get_resize_policy(); + + const Resize_Policy& + get_resize_policy() const; + + inline std::pair<point_iterator, bool> + insert(const_reference r_val) + { + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return insert_imp(r_val, traits_base::m_store_extra_indicator); + } + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + return subscript_imp(r_key, traits_base::m_store_extra_indicator); +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline point_iterator + find(const_key_reference r_key); + + inline const_point_iterator + find(const_key_reference r_key) const; + + inline point_iterator + find_end(); + + inline const_point_iterator + find_end() const; + + inline bool + erase(const_key_reference r_key); + + template<typename Pred> + inline size_type + erase_if(Pred prd); + + void + clear(); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_HT_MAP_TRACE_ + void + trace() const; +#endif + + private: +#ifdef PB_DS_DATA_TRUE_INDICATOR + friend class iterator_; +#endif + + friend class const_iterator_; + + void + deallocate_all(); + + void + initialize(); + + void + erase_all_valid_entries(entry_array, size_type); + + inline bool + do_resize_if_needed(); + + inline void + do_resize_if_needed_no_throw(); + + void + resize_imp(size_type); + + virtual void + do_resize(size_type); + + void + resize_imp(entry_array, size_type); + + inline void + resize_imp_reassign(entry_pointer, entry_array, false_type); + + inline void + resize_imp_reassign(entry_pointer, entry_array, true_type); + + inline size_type + find_ins_pos(const_key_reference, false_type); + + inline comp_hash + find_ins_pos(const_key_reference, true_type); + + inline std::pair<point_iterator, bool> + insert_imp(const_reference, false_type); + + inline std::pair<point_iterator, bool> + insert_imp(const_reference, true_type); + + inline pointer + insert_new_imp(const_reference r_val, size_type pos) + { + _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); + + if (do_resize_if_needed()) + pos = find_ins_pos(PB_DS_V2F(r_val), + traits_base::m_store_extra_indicator); + + _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); + + entry* const p_e = m_entries + pos; + new (&p_e->m_value) value_type(r_val); + p_e->m_stat = valid_entry_status; + resize_base::notify_inserted(++m_num_used_e); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(p_e->m_value));) + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return &p_e->m_value; + } + + inline pointer + insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) + { + _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != + valid_entry_status); + + if (do_resize_if_needed()) + r_pos_hash_pair = find_ins_pos(PB_DS_V2F(r_val), + traits_base::m_store_extra_indicator); + + _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != + valid_entry_status); + + entry* const p_e = m_entries + r_pos_hash_pair.first; + new (&p_e->m_value) value_type(r_val); + p_e->m_hash = r_pos_hash_pair.second; + p_e->m_stat = valid_entry_status; + + resize_base::notify_inserted(++m_num_used_e); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(p_e->m_value));) + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return &p_e->m_value; + } + +#ifdef PB_DS_DATA_TRUE_INDICATOR + inline mapped_reference + subscript_imp(const_key_reference key, false_type) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + const size_type pos = find_ins_pos(key, + traits_base::m_store_extra_indicator); + + entry_pointer p_e = &m_entries[pos]; + if (p_e->m_stat != valid_entry_status) + return insert_new_imp(value_type(key, mapped_type()), pos)->second; + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key);) + return p_e->m_value.second; + } + + inline mapped_reference + subscript_imp(const_key_reference key, true_type) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + comp_hash pos_hash_pair = + find_ins_pos(key, traits_base::m_store_extra_indicator); + + if (m_entries[pos_hash_pair.first].m_stat != valid_entry_status) + return insert_new_imp(value_type(key, mapped_type()), + pos_hash_pair)->second; + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key)); + return (m_entries + pos_hash_pair.first)->m_value.second; + } +#endif + + inline pointer + find_key_pointer(const_key_reference key, false_type) + { + const size_type hash = ranged_probe_fn_base::operator()(key); + size_type i; + resize_base::notify_find_search_start(); + + // Loop until entry is found or until all possible entries accessed. + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(key, hash, i); + + entry* const p_e = m_entries + pos; + switch (p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_find_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + + return NULL; + } + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), key)) + { + resize_base::notify_find_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key);) + + return pointer(&p_e->m_value); + } + break; + case erased_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + resize_base::notify_find_search_collision(); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + resize_base::notify_find_search_end(); + return NULL; + } + + inline pointer + find_key_pointer(const_key_reference key, true_type) + { + comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(key); + size_type i; + resize_base::notify_find_search_start(); + + // Loop until entry is found or until all possible entries accessed. + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = + ranged_probe_fn_base::operator()(key, pos_hash_pair.second, i); + + entry* const p_e = m_entries + pos; + + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_find_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + + return NULL; + } + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), + p_e->m_hash, + key, pos_hash_pair.second)) + { + resize_base::notify_find_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key);) + return pointer(&p_e->m_value); + } + break; + case erased_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + resize_base::notify_find_search_collision(); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + resize_base::notify_find_search_end(); + return NULL; + } + + inline bool + erase_imp(const_key_reference, true_type); + + inline bool + erase_imp(const_key_reference, false_type); + + inline void + erase_entry(entry_pointer p_e); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + void + inc_it_state(pointer& r_p_value, size_type& r_pos) const + { inc_it_state((const_mapped_pointer& )r_p_value, r_pos); } +#endif + + void + inc_it_state(const_pointer& r_p_value, size_type& r_pos) const + { + _GLIBCXX_DEBUG_ASSERT(r_p_value != NULL); + for (++r_pos; r_pos < m_num_e; ++r_pos) + { + const_entry_pointer p_e =& m_entries[r_pos]; + if (p_e->m_stat == valid_entry_status) + { + r_p_value =& p_e->m_value; + return; + } + } + r_p_value = NULL; + } + + void + get_start_it_state(const_pointer& r_p_value, size_type& r_pos) const + { + for (r_pos = 0; r_pos < m_num_e; ++r_pos) + { + const_entry_pointer p_e = &m_entries[r_pos]; + if (p_e->m_stat == valid_entry_status) + { + r_p_value = &p_e->m_value; + return; + } + } + r_p_value = NULL; + } + + void + get_start_it_state(pointer& r_p_value, size_type& r_pos) + { + for (r_pos = 0; r_pos < m_num_e; ++r_pos) + { + entry_pointer p_e = &m_entries[r_pos]; + if (p_e->m_stat == valid_entry_status) + { + r_p_value = &p_e->m_value; + return; + } + } + r_p_value = NULL; + } + +#ifdef _GLIBCXX_DEBUG + void + assert_entry_array_valid(const entry_array, false_type) const; + + void + assert_entry_array_valid(const entry_array, true_type) const; +#endif + + static entry_allocator s_entry_allocator; + static iterator s_end_it; + static const_iterator s_const_end_it; + + size_type m_num_e; + size_type m_num_used_e; + entry_pointer m_entries; + + enum + { + store_hash_ok = !Store_Hash + || !is_same<Hash_Fn, pb_ds::null_hash_fn>::value + }; + + PB_DS_STATIC_ASSERT(sth, store_hash_ok); + }; + +#include <ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_HASH_EQ_FN_C_DEC +#undef PB_DS_RANGED_PROBE_FN_C_DEC +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_V2F +#undef PB_DS_V2S +#undef PB_DS_STATIC_ASSERT + + } // namespace detail +} // namespace pb_ds + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp new file mode 100644 index 0000000..f24fa8e --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp @@ -0,0 +1,64 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains implementations of gp_ht_map_'s entire container info related + * functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return m_num_used_e; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_entry_allocator.max_size(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (size() == 0); } diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp new file mode 100644 index 0000000..de6e3c2 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp @@ -0,0 +1,49 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains implementations of gp_ht_map_'s insert related functions. + */ + +#include <ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp> + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..98d5970 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp @@ -0,0 +1,117 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s insert related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +find_ins_pos(const_key_reference r_key, false_type) +{ + size_type hash = ranged_probe_fn_base::operator()(r_key); + size_type i; + + /* The insertion position is initted to a non-legal value to indicate + * that it has not been initted yet. + */ + size_type ins_pos = m_num_e; + resize_base::notify_insert_search_start(); + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); + _GLIBCXX_DEBUG_ASSERT(pos < m_num_e); + entry* const p_e = m_entries + pos; + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_insert_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return (ins_pos == m_num_e) ? pos : ins_pos; + } + break; + case erased_entry_status: + if (ins_pos == m_num_e) + ins_pos = pos; + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) + { + resize_base::notify_insert_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return pos; + } + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + resize_base::notify_insert_search_collision(); + } + resize_base::notify_insert_search_end(); + if (ins_pos == m_num_e) + __throw_insert_error(); + return ins_pos; +} + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_imp(const_reference r_val, false_type) +{ + const_key_reference r_key = PB_DS_V2F(r_val); + const size_type pos = find_ins_pos(r_key, + traits_base::m_store_extra_indicator); + + if (m_entries[pos].m_stat == valid_entry_status) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return std::make_pair(&(m_entries + pos)->m_value, false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return std::make_pair(insert_new_imp(r_val, pos), true); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp new file mode 100644 index 0000000..b6445fa --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp @@ -0,0 +1,124 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s find related functions, + * when the hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::comp_hash +PB_DS_CLASS_C_DEC:: +find_ins_pos(const_key_reference r_key, true_type) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); + + size_type i; + + /* The insertion position is initted to a non-legal value to indicate + * that it has not been initted yet. + */ + size_type ins_pos = m_num_e; + resize_base::notify_insert_search_start(); + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); + + entry* const p_e = m_entries + pos; + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_insert_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + + return ((ins_pos == m_num_e) ? + std::make_pair(pos, pos_hash_pair.second) : + std::make_pair(ins_pos, pos_hash_pair.second)); + } + break; + case erased_entry_status: + if (ins_pos == m_num_e) + ins_pos = pos; + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, + r_key, pos_hash_pair.second)) + { + resize_base::notify_insert_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return std::make_pair(pos, pos_hash_pair.second); + } + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + resize_base::notify_insert_search_collision(); + } + resize_base::notify_insert_search_end(); + if (ins_pos == m_num_e) + __throw_insert_error(); + return std::make_pair(ins_pos, pos_hash_pair.second); +} + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_imp(const_reference r_val, true_type) +{ + const_key_reference r_key = PB_DS_V2F(r_val); + comp_hash pos_hash_pair = find_ins_pos(r_key, + traits_base::m_store_extra_indicator); + + _GLIBCXX_DEBUG_ASSERT(pos_hash_pair.first < m_num_e); + entry_pointer p_e =& m_entries[pos_hash_pair.first]; + if (p_e->m_stat == valid_entry_status) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return std::make_pair(&p_e->m_value, false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp new file mode 100644 index 0000000..0f5e835 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp @@ -0,0 +1,89 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterator_fn_imps.hpp + * Contains implementations of gp_ht_map_'s iterators related functions, e.g., + * begin(). + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC::s_end_it; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC::s_const_end_it; + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + pointer_ p_value; + size_type pos; + get_start_it_state(p_value, pos); + return iterator(p_value, pos, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ return s_end_it; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + const_pointer_ p_value; + size_type pos; + get_start_it_state(p_value, pos); + return const_iterator(p_value, pos, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ return s_const_end_it; } + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp new file mode 100644 index 0000000..903fc34 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp @@ -0,0 +1,106 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains implementations of gp_ht_map_'s policy agpess + * functions. + */ + +PB_DS_CLASS_T_DEC +Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_hash_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_hash_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Eq_Fn& +PB_DS_CLASS_C_DEC:: +get_eq_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Eq_Fn& +PB_DS_CLASS_C_DEC:: +get_eq_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Probe_Fn& +PB_DS_CLASS_C_DEC:: +get_probe_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Probe_Fn& +PB_DS_CLASS_C_DEC:: +get_probe_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Comb_Probe_Fn& +PB_DS_CLASS_C_DEC:: +get_comb_probe_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Comb_Probe_Fn& +PB_DS_CLASS_C_DEC:: +get_comb_probe_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Resize_Policy& +PB_DS_CLASS_C_DEC:: +get_resize_policy() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Resize_Policy& +PB_DS_CLASS_C_DEC:: +get_resize_policy() const +{ return *this; } diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp new file mode 100644 index 0000000..4368d12 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp @@ -0,0 +1,143 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_fn_imps.hpp + * Contains implementations of gp_ht_map_'s resize related functions. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +do_resize_if_needed() +{ + if (!resize_base::is_resize_needed()) + return false; + resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +do_resize(size_type n) +{ resize_imp(resize_base::get_nearest_larger_size(n)); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +do_resize_if_needed_no_throw() +{ + if (!resize_base::is_resize_needed()) + return; + + try + { + resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); + } + catch(...) + { } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize_imp(size_type new_size) +{ +#ifdef PB_DS_REGRESSION + typename Allocator::group_throw_prob_adjustor adjust(m_num_e); +#endif + + if (new_size == m_num_e) + return; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const size_type old_size = m_num_e; + entry_array a_entries_resized = NULL; + + // Following line might throw an exception. + a_entries_resized = s_entry_allocator.allocate(new_size); + + ranged_probe_fn_base::notify_resized(new_size); + m_num_e = new_size; + + for (size_type i = 0; i < m_num_e; ++i) + a_entries_resized[i].m_stat = empty_entry_status; + + try + { + resize_imp(a_entries_resized, old_size); + } + catch(...) + { + erase_all_valid_entries(a_entries_resized, new_size); + m_num_e = old_size; + s_entry_allocator.deallocate(a_entries_resized, new_size); + ranged_probe_fn_base::notify_resized(old_size); + __throw_exception_again; + } + + // At this point no exceptions can be thrown. + _GLIBCXX_DEBUG_ONLY(assert_entry_array_valid(a_entries_resized, traits_base::m_store_extra_indicator);) + + Resize_Policy::notify_resized(new_size); + erase_all_valid_entries(m_entries, old_size); + s_entry_allocator.deallocate(m_entries, old_size); + m_entries = a_entries_resized; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize_imp(entry_array a_entries_resized, size_type old_size) +{ + for (size_type pos = 0; pos < old_size; ++pos) + if (m_entries[pos].m_stat == valid_entry_status) + resize_imp_reassign(m_entries + pos, a_entries_resized, + traits_base::m_store_extra_indicator); +} + +#include <ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp> + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp new file mode 100644 index 0000000..2f4126a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s resize related functions, when the + * hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, + false_type) +{ + const_key_reference r_key = PB_DS_V2F(p_e->m_value); + size_type hash = ranged_probe_fn_base::operator()(r_key); + size_type i; + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); + entry_pointer p_new_e = a_entries_resized + pos; + switch(p_new_e->m_stat) + { + case empty_entry_status: + new (&p_new_e->m_value) value_type(p_e->m_value); + p_new_e->m_stat = valid_entry_status; + return; + case erased_entry_status: + _GLIBCXX_DEBUG_ASSERT(0); + break; + case valid_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + } + __throw_insert_error(); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp new file mode 100644 index 0000000..ac2ce14 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s resize related functions, when the + * hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, + true_type) +{ + const_key_reference r_key = PB_DS_V2F(p_e->m_value); + size_type hash = ranged_probe_fn_base::operator()(r_key, p_e->m_hash); + + size_type i; + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); + entry_pointer p_new_e = a_entries_resized + pos; + switch(p_new_e->m_stat) + { + case empty_entry_status: + new (&p_new_e->m_value) value_type(p_e->m_value); + p_new_e->m_hash = hash; + p_new_e->m_stat = valid_entry_status; + return; + case erased_entry_status: + _GLIBCXX_DEBUG_ASSERT(0); + break; + case valid_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + } + __throw_insert_error(); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/standard_policies.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/standard_policies.hpp new file mode 100644 index 0000000..f4bf7c6 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/standard_policies.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file standard_policies.hpp + * Contains standard policies for gp_ht_map types. + */ + +#ifndef PB_DS_GP_HT_MAP_STANDARD_POLICIES_HPP +#define PB_DS_GP_HT_MAP_STANDARD_POLICIES_HPP + +#include <ext/pb_ds/detail/standard_policies.hpp> +#include <ext/pb_ds/ht_load_check_resize_trigger.hpp> +#include <ext/pb_ds/linear_probe_fn.hpp> +#include <ext/pb_ds/quadratic_probe_fn.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Comb_Probe_Fn> + struct default_probe_fn + { + private: + typedef typename Comb_Probe_Fn::size_type size_type; + + public: + typedef + typename __conditional_type< + is_same< + pb_ds::direct_mask_range_hashing<size_t>, + Comb_Probe_Fn>::value, + pb_ds::linear_probe_fn<size_type>, + pb_ds::quadratic_probe_fn<size_type> >::__type + type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp new file mode 100644 index 0000000..78240c4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains implementations of gp_ht_map_'s trace-mode functions. + */ + +#ifdef PB_DS_HT_MAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << static_cast<unsigned long>(m_num_e) << " " << + static_cast<unsigned long>(m_num_used_e) << std::endl; + + for (size_type i = 0; i < m_num_e; ++i) + { + std::cerr << static_cast<unsigned long>(i) << " "; + + switch(m_entries[i].m_stat) + { + case empty_entry_status: + std::cerr << "<empty>"; + break; + case erased_entry_status: + std::cerr << "<erased>"; + break; + case valid_entry_status: + std::cerr << PB_DS_V2F(m_entries[i].m_value); + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + std::cerr << std::endl; + } +} + +#endif // #ifdef PB_DS_HT_MAP_TRACE_ diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp new file mode 100644 index 0000000..5295134 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp @@ -0,0 +1,64 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file direct_mask_range_hashing_imp.hpp + * Contains a range-hashing policy implementation + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ mask_based_base::swap(other); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type size) +{ mask_based_base::notify_resized(size); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +operator()(size_type hash) const +{ return mask_based_base::range_hash(hash); } + diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp new file mode 100644 index 0000000..5edff69 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp @@ -0,0 +1,64 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file direct_mod_range_hashing_imp.hpp + * Contains a range-hashing policy implementation + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ mod_based_base::swap(other); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type n) +{ mod_based_base::notify_resized(n); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +operator()(size_type hash) const +{ return mod_based_base::range_hash(hash); } + diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp new file mode 100644 index 0000000..c1e196c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file linear_probe_fn_imp.hpp + * Contains a probe policy implementation + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +operator()(size_type i) const +{ + return (i); +} diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp new file mode 100644 index 0000000..4aa1894 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp @@ -0,0 +1,113 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file mask_based_range_hashing.hpp + * Contains a range hashing policy base. + */ + +#ifndef PB_DS_MASK_BASED_RANGE_HASHING_HPP +#define PB_DS_MASK_BASED_RANGE_HASHING_HPP + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC mask_based_range_hashing<Size_Type> + + template<typename Size_Type> + class mask_based_range_hashing + { + protected: + typedef Size_Type size_type; + + void + swap(mask_based_range_hashing& other) + { std::swap(m_mask, other.m_mask); } + + void + notify_resized(size_type size); + + inline size_type + range_hash(size_type hash) const + { return size_type(hash & m_mask); } + + private: + size_type m_mask; + const static size_type s_num_bits_in_size_type; + const static size_type s_highest_bit_1; + }; + + PB_DS_CLASS_T_DEC + const typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC::s_num_bits_in_size_type = + sizeof(typename PB_DS_CLASS_C_DEC::size_type) << 3; + + PB_DS_CLASS_T_DEC + const typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC::s_highest_bit_1 = static_cast<typename PB_DS_CLASS_C_DEC::size_type>(1) << (s_num_bits_in_size_type - 1); + + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { + size_type i = 0; + while (size ^ s_highest_bit_1) + { + size <<= 1; + ++i; + } + + m_mask = 1; + i += 2; + while (i++ < s_num_bits_in_size_type) + m_mask = (m_mask << 1) ^ 1; + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp new file mode 100644 index 0000000..2d5e8d6 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp @@ -0,0 +1,114 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file mod_based_range_hashing.hpp + * Contains a range hashing policy base. + */ + +#ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP +#define PB_DS_MOD_BASED_RANGE_HASHING_HPP + +namespace pb_ds +{ + + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Size_Type> + +#define PB_DS_CLASS_C_DEC \ + mod_based_range_hashing< \ + Size_Type> + + template<typename Size_Type> + class mod_based_range_hashing + { + protected: + typedef Size_Type size_type; + + protected: + void + swap(PB_DS_CLASS_C_DEC& other); + + void + notify_resized(size_type size); + + inline size_type + range_hash(size_type hash) const; + + private: + size_type m_size; + }; + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + std::swap(m_size, other.m_size); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { + m_size = size; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + range_hash(size_type hash) const + { + return (hash % m_size); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail + +} // namespace pb_ds + +#endif // #ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/probe_fn_base.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/probe_fn_base.hpp new file mode 100644 index 0000000..e72a47e --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/probe_fn_base.hpp @@ -0,0 +1,65 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file probe_fn_base.hpp + * Contains a probe policy base. + */ + +#ifndef PB_DS_PROBE_FN_BASE_HPP +#define PB_DS_PROBE_FN_BASE_HPP + +#include <functional> + +namespace pb_ds +{ + namespace detail + { + template<typename Allocator> + class probe_fn_base + { + protected: + ~probe_fn_base() { } + }; +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp new file mode 100644 index 0000000..044b18b --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file quadratic_probe_fn_imp.hpp + * Contains a probe policy implementation + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +operator()(size_type i) const +{ + return (i* i); +} diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp new file mode 100644 index 0000000..179e593 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp @@ -0,0 +1,365 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file ranged_hash_fn.hpp + * Contains a unified ranged hash functor, allowing the hash tables + * to deal with a single class for ranged hashing. + */ + +#ifndef PB_DS_RANGED_HASH_FN_HPP +#define PB_DS_RANGED_HASH_FN_HPP + +#include <ext/pb_ds/detail/basic_types.hpp> +#include <utility> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Hash_Fn, bool Store_Hash> + class ranged_hash_fn; + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Hash_Fn, typename Allocator, \ + typename Comb_Hash_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_hash_fn<Key, Hash_Fn, Allocator, Comb_Hash_Fn, false> + + /** + * Specialization 1 + * The client supplies a hash function and a ranged hash function, + * and requests that hash values not be stored. + **/ + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Hash_Fn> + class ranged_hash_fn< Key, Hash_Fn, Allocator, Comb_Hash_Fn, false> + : public Hash_Fn, public Comb_Hash_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Hash_Fn hash_fn_base; + typedef Comb_Hash_Fn comb_hash_fn_base; + typedef typename Allocator::template rebind< Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_hash_fn(size_type); + + ranged_hash_fn(size_type, const Hash_Fn&); + + ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + + void + notify_resized(size_type); + + inline size_type + operator()(const_key_reference) const; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) + : Hash_Fn(r_hash_fn) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Hash_Fn& r_comb_hash_fn) + : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) + { comb_hash_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + comb_hash_fn_base::swap(other); + std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { comb_hash_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_key) const + { return (comb_hash_fn_base::operator()(hash_fn_base::operator()(r_key)));} + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Hash_Fn, typename Allocator, \ + typename Comb_Hash_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_hash_fn<Key,Hash_Fn, Allocator, Comb_Hash_Fn, true> + + /** + * Specialization 2 + * The client supplies a hash function and a ranged hash function, + * and requests that hash values be stored. + **/ + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Hash_Fn> + class ranged_hash_fn<Key, Hash_Fn, Allocator, Comb_Hash_Fn, true> + : public Hash_Fn, public Comb_Hash_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef std::pair<size_type, size_type> comp_hash; + typedef Hash_Fn hash_fn_base; + typedef Comb_Hash_Fn comb_hash_fn_base; + typedef typename Allocator::template rebind<Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_hash_fn(size_type); + + ranged_hash_fn(size_type, const Hash_Fn&); + + ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + + void + notify_resized(size_type); + + inline comp_hash + operator()(const_key_reference) const; + + inline comp_hash + operator()(const_key_reference, size_type) const; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) : + Hash_Fn(r_hash_fn) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Hash_Fn& r_comb_hash_fn) + : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) + { comb_hash_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + comb_hash_fn_base::swap(other); + std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { comb_hash_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::comp_hash + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_key) const + { + const size_type hash = hash_fn_base::operator()(r_key); + return std::make_pair(comb_hash_fn_base::operator()(hash), hash); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::comp_hash + PB_DS_CLASS_C_DEC:: + operator() +#ifdef _GLIBCXX_DEBUG + (const_key_reference r_key, size_type hash) const +#else + (const_key_reference /*r_key*/, size_type hash) const +#endif + { + _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); + return std::make_pair(comb_hash_fn_base::operator()(hash), hash); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Allocator, typename Comb_Hash_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_hash_fn<Key, null_hash_fn, Allocator, Comb_Hash_Fn, false> + + /** + * Specialization 3 + * The client does not supply a hash function (by specifying + * null_hash_fn as the Hash_Fn parameter), and requests that hash + * values not be stored. + **/ + template<typename Key, typename Allocator, typename Comb_Hash_Fn> + class ranged_hash_fn<Key, null_hash_fn, Allocator, Comb_Hash_Fn, false> + : public null_hash_fn, public Comb_Hash_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Comb_Hash_Fn comb_hash_fn_base; + + ranged_hash_fn(size_type); + + ranged_hash_fn(size_type, const Comb_Hash_Fn&); + + ranged_hash_fn(size_type, const null_hash_fn&, const Comb_Hash_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) : + Comb_Hash_Fn(r_comb_hash_fn) + { } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const null_hash_fn& r_null_hash_fn, + const Comb_Hash_Fn& r_comb_hash_fn) + : Comb_Hash_Fn(r_comb_hash_fn) + { } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { comb_hash_fn_base::swap(other); } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Allocator, typename Comb_Hash_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_hash_fn<Key, null_hash_fn, Allocator, Comb_Hash_Fn, true> + + /** + * Specialization 4 + * The client does not supply a hash function (by specifying + * null_hash_fn as the Hash_Fn parameter), and requests that hash + * values be stored. + **/ + template<typename Key, typename Allocator, typename Comb_Hash_Fn> + class ranged_hash_fn<Key, null_hash_fn, Allocator, Comb_Hash_Fn, true> + : public null_hash_fn, public Comb_Hash_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Comb_Hash_Fn comb_hash_fn_base; + + ranged_hash_fn(size_type); + + ranged_hash_fn(size_type, const Comb_Hash_Fn&); + + ranged_hash_fn(size_type, const null_hash_fn&, const Comb_Hash_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) + : Comb_Hash_Fn(r_comb_hash_fn) + { } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const null_hash_fn& r_null_hash_fn, + const Comb_Hash_Fn& r_comb_hash_fn) + : Comb_Hash_Fn(r_comb_hash_fn) + { } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { comb_hash_fn_base::swap(other); } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp new file mode 100644 index 0000000..b665dbf --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp @@ -0,0 +1,333 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file ranged_probe_fn.hpp + * Contains a unified ranged probe functor, allowing the probe tables to deal with + * a single class for ranged probeing. + */ + +#ifndef PB_DS_RANGED_PROBE_FN_HPP +#define PB_DS_RANGED_PROBE_FN_HPP + +#include <ext/pb_ds/detail/basic_types.hpp> +#include <utility> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Probe_Fn, typename Probe_Fn, bool Store_Hash> + class ranged_probe_fn; + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Hash_Fn, typename Allocator, \ + typename Comb_Probe_Fn, typename Probe_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, Probe_Fn, false> + + /** + * Specialization 1 + * The client supplies a probe function and a ranged probe + * function, and requests that hash values not be stored. + **/ + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Probe_Fn, typename Probe_Fn> + class ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, + Probe_Fn, false> + : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Comb_Probe_Fn comb_probe_fn_base; + typedef Hash_Fn hash_fn_base; + typedef Probe_Fn probe_fn_base; + typedef typename Allocator::template rebind<Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_probe_fn(size_type); + + ranged_probe_fn(size_type, const Hash_Fn&); + + ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&); + + ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, + const Probe_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + + void + notify_resized(size_type); + + inline size_type + operator()(const_key_reference) const; + + inline size_type + operator()(const_key_reference, size_type, size_type) const; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size) + { Comb_Probe_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) + : Hash_Fn(r_hash_fn) + { Comb_Probe_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Probe_Fn& r_comb_probe_fn) + : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Probe_Fn& r_comb_probe_fn, + const Probe_Fn& r_probe_fn) + : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + comb_probe_fn_base::swap(other); + std::swap((Hash_Fn& )(*this), (Hash_Fn&)other); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_key) const + { return comb_probe_fn_base::operator()(hash_fn_base::operator()(r_key)); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference, size_type hash, size_type i) const + { + return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Hash_Fn, typename Allocator, \ + typename Comb_Probe_Fn, typename Probe_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, Probe_Fn, true> + + /** + * Specialization 2- The client supplies a probe function and a ranged + * probe function, and requests that hash values not be stored. + **/ + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Probe_Fn, typename Probe_Fn> + class ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, + Probe_Fn, true> + : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef std::pair<size_type, size_type> comp_hash; + typedef Comb_Probe_Fn comb_probe_fn_base; + typedef Hash_Fn hash_fn_base; + typedef Probe_Fn probe_fn_base; + typedef typename Allocator::template rebind<Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_probe_fn(size_type); + + ranged_probe_fn(size_type, const Hash_Fn&); + + ranged_probe_fn(size_type, const Hash_Fn&, + const Comb_Probe_Fn&); + + ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, + const Probe_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + + void + notify_resized(size_type); + + inline comp_hash + operator()(const_key_reference) const; + + inline size_type + operator()(const_key_reference, size_type, size_type) const; + + inline size_type + operator()(const_key_reference, size_type) const; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size) + { Comb_Probe_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) + : Hash_Fn(r_hash_fn) + { Comb_Probe_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Probe_Fn& r_comb_probe_fn) + : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Probe_Fn& r_comb_probe_fn, + const Probe_Fn& r_probe_fn) + : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + comb_probe_fn_base::swap(other); + std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::comp_hash + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_key) const + { + const size_type hash = hash_fn_base::operator()(r_key); + return std::make_pair(comb_probe_fn_base::operator()(hash), hash); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference, size_type hash, size_type i) const + { + return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator() +#ifdef _GLIBCXX_DEBUG + (const_key_reference r_key, size_type hash) const +#else + (const_key_reference /*r_key*/, size_type hash) const +#endif + { + _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); + return hash; + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + /** + * Specialization 3 and 4 + * The client does not supply a hash function or probe function, + * and requests that hash values not be stored. + **/ + template<typename Key, typename Allocator, typename Comb_Probe_Fn> + class ranged_probe_fn<Key, null_hash_fn, Allocator, Comb_Probe_Fn, + null_probe_fn, false> + : public Comb_Probe_Fn, public null_hash_fn, public null_probe_fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Comb_Probe_Fn comb_probe_fn_base; + typedef typename Allocator::template rebind<Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_probe_fn(size_type size) + { Comb_Probe_Fn::notify_resized(size); } + + ranged_probe_fn(size_type, const Comb_Probe_Fn& r_comb_probe_fn) + : Comb_Probe_Fn(r_comb_probe_fn) + { } + + ranged_probe_fn(size_type, const null_hash_fn&, + const Comb_Probe_Fn& r_comb_probe_fn, + const null_probe_fn&) + : Comb_Probe_Fn(r_comb_probe_fn) + { } + + void + swap(ranged_probe_fn& other) + { comb_probe_fn_base::swap(other); } + }; + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_probe_fn.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_probe_fn.hpp new file mode 100644 index 0000000..908a719 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_probe_fn.hpp @@ -0,0 +1,79 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_probe_fn.hpp + * Contains a sample probe policy. + */ + +#ifndef PB_DS_SAMPLE_PROBE_FN_HPP +#define PB_DS_SAMPLE_PROBE_FN_HPP + +// A sample probe policy. +class sample_probe_fn +{ + +public: + + // Size type. + typedef size_t size_type; + +public: + + // Default constructor. + sample_probe_fn(); + + // Copy constructor. + sample_probe_fn(const sample_probe_fn& other); + + // Swaps content. + inline void + swap(sample_probe_fn& other); + +protected: + + // Returns the i-th offset from the hash value of some key r_key. + inline size_type + operator()(const_key_reference r_key, size_type i) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_PROBE_FN_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_range_hashing.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_range_hashing.hpp new file mode 100644 index 0000000..40ab29a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_range_hashing.hpp @@ -0,0 +1,83 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_range_hashing.hpp + * Contains a range hashing policy. + */ + +#ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP +#define PB_DS_SAMPLE_RANGE_HASHING_HPP + +// A sample range-hashing functor. +class sample_range_hashing +{ + +public: + + // Size type. + typedef size_t size_type; + +public: + + // Default constructor. + sample_range_hashing(); + + // Copy constructor. + sample_range_hashing(const sample_range_hashing& other); + + // Swaps content. + inline void + swap(sample_range_hashing& other); + +protected: + + // Notifies the policy object that the container's __size has changed to size. + void + notify_resized(size_type size); + + // Transforms the __hash value hash into a ranged-hash value. + inline size_type + operator()(size_type hash) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hpp new file mode 100644 index 0000000..55a115d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hpp @@ -0,0 +1,83 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_ranged_hash_fn.hpp + * Contains a ranged hash policy. + */ + +#ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP +#define PB_DS_SAMPLE_RANGED_HASH_FN_HPP + +// A sample ranged-hash functor. +class sample_ranged_hash_fn +{ + +public: + + // Size type. + typedef size_t size_type; + +public: + + // Default constructor. + sample_ranged_hash_fn(); + + // Copy constructor. + sample_ranged_hash_fn(const sample_ranged_hash_fn& other); + + // Swaps content. + inline void + swap(sample_ranged_hash_fn& other); + +protected: + + // Notifies the policy object that the container's __size has changed to size. + void + notify_resized(size_type size); + + // Transforms r_key into a position within the table. + inline size_type + operator()(const_key_reference r_key) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hpp b/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hpp new file mode 100644 index 0000000..01697bb --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hpp @@ -0,0 +1,83 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_ranged_probe_fn.hpp + * Contains a ranged probe policy. + */ + +#ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP +#define PB_DS_SAMPLE_RANGED_PROBE_FN_HPP + +// A sample ranged-probe functor. +class sample_ranged_probe_fn +{ + +public: + + // Size type. + typedef size_t size_type; + +public: + + // Default constructor. + sample_ranged_probe_fn(); + + // Copy constructor. + sample_ranged_probe_fn(const sample_ranged_probe_fn& other); + + // Swaps content. + inline void + swap(sample_ranged_probe_fn& other); + +protected: + + // Notifies the policy object that the container's __size has changed to size. + void + notify_resized(size_type size); + + // Transforms the const key reference r_key into the i-th position within the table. This method is called for each collision within the probe sequence. + inline size_type + operator()(const_key_reference r_key, size_t hash, size_type i) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp new file mode 100644 index 0000000..cff9bb8 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp @@ -0,0 +1,168 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_iterator.hpp + * Contains an iterator class returned by the table's const find and insert + * methods. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP + +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_C_DEC \ + left_child_next_sibling_heap_const_iterator_<Node, Allocator> + +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_node_const_point_iterator_<Node, Allocator> + + // Const point-type iterator. + template<typename Node, class Allocator> + class left_child_next_sibling_heap_const_iterator_ : public PB_DS_BASE_C_DEC + { + + private: + typedef typename PB_DS_BASE_C_DEC::node_pointer node_pointer; + + typedef PB_DS_BASE_C_DEC base_type; + + public: + + // Category. + typedef std::forward_iterator_tag iterator_category; + + // Difference type. + typedef typename Allocator::difference_type difference_type; + + // Iterator's value type. + typedef typename base_type::value_type value_type; + + // Iterator's pointer type. + typedef typename base_type::pointer pointer; + + // Iterator's const pointer type. + typedef typename base_type::const_pointer const_pointer; + + // Iterator's reference type. + typedef typename base_type::reference reference; + + // Iterator's const reference type. + typedef typename base_type::const_reference const_reference; + + public: + + inline + left_child_next_sibling_heap_const_iterator_(node_pointer p_nd) : base_type(p_nd) + { } + + // Default constructor. + inline + left_child_next_sibling_heap_const_iterator_() + { } + + // Copy constructor. + inline + left_child_next_sibling_heap_const_iterator_(const PB_DS_CLASS_C_DEC& other) : base_type(other) + { } + + // Compares content to a different iterator object. + inline bool + operator==(const PB_DS_CLASS_C_DEC& other) const + { return (base_type::m_p_nd == other.m_p_nd); } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_CLASS_C_DEC& other) const + { return (base_type::m_p_nd != other.m_p_nd); } + + inline PB_DS_CLASS_C_DEC& + operator++() + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd != NULL); + inc(); + return (*this); + } + + inline PB_DS_CLASS_C_DEC + operator++(int) + { + PB_DS_CLASS_C_DEC ret_it(base_type::m_p_nd); + operator++(); + return (ret_it); + } + + private: + void + inc() + { + if (base_type::m_p_nd->m_p_next_sibling != NULL) + { + base_type::m_p_nd = base_type::m_p_nd->m_p_next_sibling; + while (base_type::m_p_nd->m_p_l_child != NULL) + base_type::m_p_nd = base_type::m_p_nd->m_p_l_child; + return; + } + + while (true) + { + node_pointer p_next = base_type::m_p_nd; + base_type::m_p_nd = base_type::m_p_nd->m_p_prev_or_parent; + if (base_type::m_p_nd == NULL || base_type::m_p_nd->m_p_l_child == p_next) + return; + } + } + }; + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp new file mode 100644 index 0000000..ea45b62 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp @@ -0,0 +1,160 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_point_iterator.hpp + * Contains an iterator class returned by the table's const find and insert + * methods. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Node, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + left_child_next_sibling_heap_node_const_point_iterator_<Node, Allocator> + + // Const point-type iterator. + template<typename Node, class Allocator> + class left_child_next_sibling_heap_node_const_point_iterator_ + { + + protected: + typedef typename Allocator::template rebind<Node>::other::pointer node_pointer; + + public: + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // Iterator's value type. + typedef typename Node::value_type value_type; + + // Iterator's pointer type. + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + // Iterator's const pointer type. + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + // Iterator's reference type. + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + // Iterator's const reference type. + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + public: + + inline + left_child_next_sibling_heap_node_const_point_iterator_(node_pointer p_nd) : m_p_nd(p_nd) + { } + + // Default constructor. + inline + left_child_next_sibling_heap_node_const_point_iterator_() : m_p_nd(NULL) + { } + + // Copy constructor. + inline + left_child_next_sibling_heap_node_const_point_iterator_(const PB_DS_CLASS_C_DEC& other) : m_p_nd(other.m_p_nd) + { } + + // Access. + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + return &m_p_nd->m_value; + } + + // Access. + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + return m_p_nd->m_value; + } + + // Compares content to a different iterator object. + inline bool + operator==(const PB_DS_CLASS_C_DEC& other) const + { return m_p_nd == other.m_p_nd; } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_CLASS_C_DEC& other) const + { return m_p_nd != other.m_p_nd; } + + public: + node_pointer m_p_nd; + }; + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..85d2511 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,158 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_allocator +PB_DS_CLASS_C_DEC::s_node_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::no_throw_copies_t +PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +left_child_next_sibling_heap_() : + m_p_root(NULL), + m_size(0) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +left_child_next_sibling_heap_(const Cmp_Fn& r_cmp_fn) : + Cmp_Fn(r_cmp_fn), + m_p_root(NULL), + m_size(0) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +left_child_next_sibling_heap_(const PB_DS_CLASS_C_DEC& other) +: Cmp_Fn(other), m_p_root(NULL), m_size(0) +{ + m_size = other.m_size; + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + m_p_root = recursive_copy_node(other.m_p_root); + m_size = other.m_size; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + value_swap(other); + std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_p_root, other.m_p_root); + std::swap(m_size, other.m_size); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~left_child_next_sibling_heap_() +{ + clear(); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +recursive_copy_node(const_node_pointer p_nd) +{ + if (p_nd == NULL) + return (NULL); + + node_pointer p_ret = s_node_allocator.allocate(1); + + try + { + new (p_ret) node(*p_nd); + } + catch(...) + { + s_node_allocator.deallocate(p_ret, 1); + __throw_exception_again; + } + + p_ret->m_p_l_child = p_ret->m_p_next_sibling = + p_ret->m_p_prev_or_parent = NULL; + + try + { + p_ret->m_p_l_child = recursive_copy_node(p_nd->m_p_l_child); + p_ret->m_p_next_sibling = recursive_copy_node(p_nd->m_p_next_sibling); + } + catch(...) + { + clear_imp(p_ret); + __throw_exception_again; + } + + if (p_ret->m_p_l_child != NULL) + p_ret->m_p_l_child->m_p_prev_or_parent = p_ret; + + if (p_ret->m_p_next_sibling != NULL) + p_ret->m_p_next_sibling->m_p_prev_or_parent = + p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd ? p_ret : NULL; + + return p_ret; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp new file mode 100644 index 0000000..f16e912 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp @@ -0,0 +1,147 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + _GLIBCXX_DEBUG_ASSERT(m_p_root == NULL || m_p_root->m_p_prev_or_parent == NULL); + + if (m_p_root != NULL) + assert_node_consistent(m_p_root, Single_Link_Roots); + assert_size(); + assert_iterators(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const_node_pointer p_nd, bool single_link) const +{ + if (p_nd == NULL) + return; + + assert_node_consistent(p_nd->m_p_l_child, false); + assert_node_consistent(p_nd->m_p_next_sibling, single_link); + + if (single_link) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_prev_or_parent == NULL); + else if (p_nd->m_p_next_sibling != NULL) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd); + + if (p_nd->m_p_l_child == NULL) + return; + + const_node_pointer p_child = p_nd->m_p_l_child; + while (p_child != NULL) + { + const_node_pointer p_next_child = p_child->m_p_next_sibling; + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(p_nd->m_value, p_child->m_value)); + p_child = p_next_child; + } + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child->m_p_prev_or_parent == p_nd); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_iterators() const +{ + const size_type calc_size = std::distance(begin(), end()); + if (calc_size == size()) + return; + _GLIBCXX_DEBUG_ASSERT(0); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_size() const +{ + if (size_from_node(m_p_root) == m_size) + return; + _GLIBCXX_DEBUG_ASSERT(0); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size_under_node(const_node_pointer p_nd) +{ return 1 + size_from_node(p_nd->m_p_l_child); } + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size_from_node(const_node_pointer p_nd) +{ + size_type ret = 0; + while (p_nd != NULL) + { + ret += 1 + size_from_node(p_nd->m_p_l_child); + p_nd = p_nd->m_p_next_sibling; + } + return ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +degree(const_node_pointer p_nd) +{ + size_type ret = 0; + const_node_pointer p_child = p_nd->m_p_l_child; + while (p_child != NULL) + { + ++ret; + p_child = p_child->m_p_next_sibling; + } + return ret; +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp new file mode 100644 index 0000000..5281763 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp @@ -0,0 +1,156 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + clear_imp(m_p_root); + _GLIBCXX_DEBUG_ASSERT(m_size == 0); + m_p_root = NULL; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_node(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + p_nd->~node(); + s_node_allocator.deallocate(p_nd, 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + while (p_nd != NULL) + { + clear_imp(p_nd->m_p_l_child); + node_pointer p_next = p_nd->m_p_next_sibling; + actual_erase_node(p_nd); + p_nd = p_next; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +to_linked_list() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + node_pointer p_cur = m_p_root; + while (p_cur != NULL) + if (p_cur->m_p_l_child != NULL) + { + node_pointer p_child_next = p_cur->m_p_l_child->m_p_next_sibling; + p_cur->m_p_l_child->m_p_next_sibling = p_cur->m_p_next_sibling; + p_cur->m_p_next_sibling = p_cur->m_p_l_child; + p_cur->m_p_l_child = p_child_next; + } + else + p_cur = p_cur->m_p_next_sibling; + +#ifdef _GLIBCXX_DEBUG + const_node_pointer p_counter = m_p_root; + size_type count = 0; + while (p_counter != NULL) + { + ++count; + _GLIBCXX_DEBUG_ASSERT(p_counter->m_p_l_child == NULL); + p_counter = p_counter->m_p_next_sibling; + } + _GLIBCXX_DEBUG_ASSERT(count == m_size); +#endif +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +prune(Pred pred) +{ + node_pointer p_cur = m_p_root; + m_p_root = NULL; + node_pointer p_out = NULL; + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + if (pred(p_cur->m_value)) + { + p_cur->m_p_next_sibling = p_out; + if (p_out != NULL) + p_out->m_p_prev_or_parent = p_cur; + p_out = p_cur; + } + else + { + p_cur->m_p_next_sibling = m_p_root; + if (m_p_root != NULL) + m_p_root->m_p_prev_or_parent = p_cur; + m_p_root = p_cur; + } + p_cur = p_next; + } + return p_out; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +bubble_to_top(node_pointer p_nd) +{ + node_pointer p_parent = parent(p_nd); + while (p_parent != NULL) + { + swap_with_parent(p_nd, p_parent); + p_parent = parent(p_nd); + } +} + diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp new file mode 100644 index 0000000..3c0dde8 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp @@ -0,0 +1,70 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ + return (m_size == 0); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ + return (m_size); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ + return (s_node_allocator.max_size()); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp new file mode 100644 index 0000000..479690d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp @@ -0,0 +1,181 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_insert(const_reference r_val) +{ + return get_new_node_for_insert(r_val, s_no_throw_copies_ind); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_insert(const_reference r_val, false_type) +{ + node_pointer p_new_nd = s_node_allocator.allocate(1); + + cond_dealtor_t cond(p_new_nd); + + new (const_cast<void* >( + static_cast<const void* >(&p_new_nd->m_value))) + typename node::value_type(r_val); + + cond.set_no_action(); + + ++m_size; + + return (p_new_nd); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_insert(const_reference r_val, true_type) +{ + node_pointer p_new_nd = s_node_allocator.allocate(1); + + new (const_cast<void* >( + static_cast<const void* >(&p_new_nd->m_value))) + typename node::value_type(r_val); + + ++m_size; + + return (p_new_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_child_of(node_pointer p_nd, node_pointer p_new_parent) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_new_parent != NULL); + + p_nd->m_p_next_sibling = p_new_parent->m_p_l_child; + + if (p_new_parent->m_p_l_child != NULL) + p_new_parent->m_p_l_child->m_p_prev_or_parent = p_nd; + + p_nd->m_p_prev_or_parent = p_new_parent; + + p_new_parent->m_p_l_child = p_nd; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +parent(node_pointer p_nd) +{ + while (true) + { + node_pointer p_pot = p_nd->m_p_prev_or_parent; + + if (p_pot == NULL || p_pot->m_p_l_child == p_nd) + return p_pot; + + p_nd = p_pot; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap_with_parent(node_pointer p_nd, node_pointer p_parent) +{ + if (p_parent == m_p_root) + m_p_root = p_nd; + + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_parent != NULL); + _GLIBCXX_DEBUG_ASSERT(parent(p_nd) == p_parent); + + const bool nd_direct_child = p_parent->m_p_l_child == p_nd; + const bool parent_root = p_parent->m_p_prev_or_parent == NULL; + const bool parent_direct_child = + !parent_root&& p_parent->m_p_prev_or_parent->m_p_l_child == p_parent; + + std::swap(p_parent->m_p_prev_or_parent, p_nd->m_p_prev_or_parent); + std::swap(p_parent->m_p_next_sibling, p_nd->m_p_next_sibling); + std::swap(p_parent->m_p_l_child, p_nd->m_p_l_child); + std::swap(p_parent->m_metadata, p_nd->m_metadata); + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child != NULL); + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent != NULL); + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; + + if (p_parent->m_p_next_sibling != NULL) + p_parent->m_p_next_sibling->m_p_prev_or_parent = p_parent; + + if (p_parent->m_p_l_child != NULL) + p_parent->m_p_l_child->m_p_prev_or_parent = p_parent; + + if (parent_direct_child) + p_nd->m_p_prev_or_parent->m_p_l_child = p_nd; + else if (!parent_root) + p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd; + + if (!nd_direct_child) + { + p_nd->m_p_l_child->m_p_prev_or_parent = p_nd; + + p_parent->m_p_prev_or_parent->m_p_next_sibling = p_parent; + } + else + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child == p_nd); + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent == p_parent); + + p_nd->m_p_l_child = p_parent; + p_parent->m_p_prev_or_parent = p_nd; + } + + _GLIBCXX_DEBUG_ASSERT(parent(p_parent) == p_nd); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp new file mode 100644 index 0000000..02e9982 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp @@ -0,0 +1,94 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + node_pointer p_nd = m_p_root; + + if (p_nd == NULL) + return (iterator(NULL)); + + while (p_nd->m_p_l_child != NULL) + p_nd = p_nd->m_p_l_child; + + return (iterator(p_nd)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + node_pointer p_nd = m_p_root; + + if (p_nd == NULL) + return (const_iterator(NULL)); + + while (p_nd->m_p_l_child != NULL) + p_nd = p_nd->m_p_l_child; + + return (const_iterator(p_nd)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ + return (iterator(NULL)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ + return (const_iterator(NULL)); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp new file mode 100644 index 0000000..e06358d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp @@ -0,0 +1,355 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file left_child_next_sibling_heap_.hpp + * Contains an implementation class for a basic heap. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP + +/* + * Based on CLRS. + */ + +#include <iterator> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp> +#ifdef PB_DS_LC_NS_HEAP_TRACE_ +#include <iostream> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_CLASS_T_DEC \ + template< \ + typename Value_Type, \ + class Cmp_Fn, \ + typename Node_Metadata, \ + class Allocator, \ + bool Single_Link_Roots> +#else +#define PB_DS_CLASS_T_DEC \ + template< \ + typename Value_Type, \ + class Cmp_Fn, \ + typename Node_Metadata, \ + class Allocator> +#endif + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_CLASS_C_DEC \ + left_child_next_sibling_heap_< \ + Value_Type, \ + Cmp_Fn, \ + Node_Metadata, \ + Allocator, \ + Single_Link_Roots> +#else +#define PB_DS_CLASS_C_DEC \ + left_child_next_sibling_heap_< \ + Value_Type, \ + Cmp_Fn, \ + Node_Metadata, \ + Allocator> +#endif + + /** + * class description = "Base class for some types of h3ap$"> + **/ +#ifdef _GLIBCXX_DEBUG + template<typename Value_Type, + class Cmp_Fn, + typename Node_Metadata, + class Allocator, + bool Single_Link_Roots> +#else + template<typename Value_Type, + class Cmp_Fn, + typename Node_Metadata, + class Allocator> +#endif + class left_child_next_sibling_heap_ : public Cmp_Fn + { + + protected: + typedef + typename Allocator::template rebind< + left_child_next_sibling_heap_node_< + Value_Type, + Node_Metadata, + Allocator> >::other + node_allocator; + + typedef typename node_allocator::value_type node; + + typedef typename node_allocator::pointer node_pointer; + + typedef typename node_allocator::const_pointer const_node_pointer; + + typedef Node_Metadata node_metadata; + + typedef std::pair< node_pointer, node_pointer> node_pointer_pair; + + private: + typedef cond_dealtor< node, Allocator> cond_dealtor_t; + + enum + { + simple_value = is_simple<Value_Type>::value + }; + + typedef integral_constant<int, simple_value> no_throw_copies_t; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + left_child_next_sibling_heap_node_const_point_iterator_< + node, + Allocator> + const_point_iterator; + + typedef const_point_iterator point_iterator; + + typedef + left_child_next_sibling_heap_const_iterator_< + node, + Allocator> + const_iterator; + + typedef const_iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + public: + + left_child_next_sibling_heap_(); + + left_child_next_sibling_heap_(const Cmp_Fn& r_cmp_fn); + + left_child_next_sibling_heap_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~left_child_next_sibling_heap_(); + + inline bool + empty() const; + + inline size_type + size() const; + + inline size_type + max_size() const; + + Cmp_Fn& + get_cmp_fn(); + + const Cmp_Fn& + get_cmp_fn() const; + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + + void + clear(); + +#ifdef PB_DS_LC_NS_HEAP_TRACE_ + void + trace() const; +#endif + + protected: + + inline node_pointer + get_new_node_for_insert(const_reference r_val); + + inline static void + make_child_of(node_pointer p_nd, node_pointer p_new_parent); + + void + value_swap(PB_DS_CLASS_C_DEC& other); + + inline static node_pointer + parent(node_pointer p_nd); + + inline void + swap_with_parent(node_pointer p_nd, node_pointer p_parent); + + void + bubble_to_top(node_pointer p_nd); + + inline void + actual_erase_node(node_pointer p_nd); + + void + clear_imp(node_pointer p_nd); + + void + to_linked_list(); + + template<typename Pred> + node_pointer + prune(Pred pred); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_node_consistent(const_node_pointer p_nd, bool single_link) const; + + static size_type + size_under_node(const_node_pointer p_nd); + + static size_type + degree(const_node_pointer p_nd); +#endif + +#ifdef PB_DS_LC_NS_HEAP_TRACE_ + static void + trace_node(const_node_pointer, size_type level); +#endif + + protected: + node_pointer m_p_root; + + size_type m_size; + + private: +#ifdef _GLIBCXX_DEBUG + void + assert_iterators() const; + + void + assert_size() const; + + static size_type + size_from_node(const_node_pointer p_nd); +#endif + + node_pointer + recursive_copy_node(const_node_pointer p_nd); + + inline node_pointer + get_new_node_for_insert(const_reference r_val, false_type); + + inline node_pointer + get_new_node_for_insert(const_reference r_val, true_type); + +#ifdef PB_DS_LC_NS_HEAP_TRACE_ + template<typename Metadata_> + static void + trace_node_metadata(const_node_pointer p_nd, type_to_type<Metadata_>); + + static void + trace_node_metadata(const_node_pointer, type_to_type<null_left_child_next_sibling_heap_node_metadata>); +#endif + + private: + static node_allocator s_node_allocator; + + static no_throw_copies_t s_no_throw_copies_ind; + }; + +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp new file mode 100644 index 0000000..e3460ad --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp @@ -0,0 +1,129 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node.hpp + * Contains an implementation struct for this type of heap's node. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP + +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Value_Type, typename Metadata_Type, class Allocator> + struct left_child_next_sibling_heap_node_ + { + private: + typedef + left_child_next_sibling_heap_node_< + Value_Type, + Metadata_Type, + Allocator> + this_type; + + public: + typedef typename Allocator::size_type size_type; + + typedef + typename Allocator::template rebind< + this_type>::other::pointer + node_pointer; + + typedef Value_Type value_type; + + typedef Metadata_Type metadata_type; + + public: + value_type m_value; + + metadata_type m_metadata; + + node_pointer m_p_l_child; + + node_pointer m_p_next_sibling; + + node_pointer m_p_prev_or_parent; + }; + + template<typename Value_Type, class Allocator> + struct left_child_next_sibling_heap_node_< + Value_Type, + null_left_child_next_sibling_heap_node_metadata, + Allocator> + { + private: + typedef + left_child_next_sibling_heap_node_< + Value_Type, + null_left_child_next_sibling_heap_node_metadata, + Allocator> + this_type; + + public: + typedef typename Allocator::size_type size_type; + + typedef + typename Allocator::template rebind< + this_type>::other::pointer + node_pointer; + + typedef Value_Type value_type; + + public: + value_type m_value; + + node_pointer m_p_l_child; + + node_pointer m_p_next_sibling; + + node_pointer m_p_prev_or_parent; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp new file mode 100644 index 0000000..1716fd1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp @@ -0,0 +1,63 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file null_metadata.hpp + * Contains an implementation struct for this type of heap's node. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NULL_METADATA_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NULL_METADATA_HPP + +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + + struct null_left_child_next_sibling_heap_node_metadata + { }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NULL_METADATA_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp new file mode 100644 index 0000000..b7503c2 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp @@ -0,0 +1,62 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() +{ + return (*this); +} + +PB_DS_CLASS_T_DEC +const Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() const +{ + return (*this); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp new file mode 100644 index 0000000..5c0d9ac --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp @@ -0,0 +1,101 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +#ifdef PB_DS_LC_NS_HEAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << std::endl; + + trace_node(m_p_root, 0); + + std::cerr << std::endl; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_node(const_node_pointer p_nd, size_type level) +{ + while (p_nd != NULL) + { + for (size_type i = 0; i < level; ++i) + std::cerr << ' '; + + std::cerr << p_nd << + " prev = " << p_nd->m_p_prev_or_parent << + " next " << p_nd->m_p_next_sibling << + " left = " << p_nd->m_p_l_child << " "; + + trace_node_metadata(p_nd, type_to_type<node_metadata>()); + + std::cerr << p_nd->m_value << std::endl; + + trace_node(p_nd->m_p_l_child, level + 1); + + p_nd = p_nd->m_p_next_sibling; + } +} + +PB_DS_CLASS_T_DEC +template<typename Metadata_> +void +PB_DS_CLASS_C_DEC:: +trace_node_metadata(const_node_pointer p_nd, type_to_type<Metadata_>) +{ + std::cerr << "(" << p_nd->m_metadata << ") "; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_node_metadata(const_node_pointer, type_to_type<null_left_child_next_sibling_heap_node_metadata>) +{ } + +#endif // #ifdef PB_DS_LC_NS_HEAP_TRACE_ diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp new file mode 100644 index 0000000..a311a79 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp @@ -0,0 +1,147 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_fn_imps.hpp + * Contains implementations of PB_DS_CLASS_NAME. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_allocator +PB_DS_CLASS_C_DEC::s_entry_allocator; + +PB_DS_CLASS_T_DEC +Eq_Fn PB_DS_CLASS_C_DEC::s_eq_fn; + +PB_DS_CLASS_T_DEC +null_lu_metadata PB_DS_CLASS_C_DEC::s_null_lu_metadata; + +PB_DS_CLASS_T_DEC +Update_Policy PB_DS_CLASS_C_DEC::s_update_policy; + +PB_DS_CLASS_T_DEC +type_to_type< + typename PB_DS_CLASS_C_DEC::update_metadata> PB_DS_CLASS_C_DEC::s_metadata_type_indicator; + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() : m_p_l(NULL) +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +template<typename It> +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(It first_it, It last_it) : m_p_l(NULL) +{ + copy_from_range(first_it, last_it); + _GLIBCXX_DEBUG_ONLY(assert_valid();); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(), +#endif +m_p_l(NULL) +{ + try + { + for (const_iterator it = other.begin(); it != other.end(); ++it) + { + entry_pointer p_l = allocate_new_entry(*it, + PB_DS_TYPES_TRAITS_C_DEC::m_no_throw_copies_indicator); + + p_l->m_p_next = m_p_l; + m_p_l = p_l; + } + } + catch(...) + { + deallocate_all(); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other);) + std::swap(m_p_l, other.m_p_l); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +deallocate_all() +{ + entry_pointer p_l = m_p_l; + while (p_l != NULL) + { + entry_pointer p_next_l = p_l->m_p_next; + actual_erase_entry(p_l); + p_l = p_next_l; + } + m_p_l = NULL; +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ deallocate_all(); } + diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp new file mode 100644 index 0000000..1427f83 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp @@ -0,0 +1,63 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains implementations of cc_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + size_type calc_size = 0; + for (const_iterator it = begin(); it != end(); ++it) + { + map_debug_base::check_key_exists(PB_DS_V2F(*it)); + ++calc_size; + } + map_debug_base::check_size(calc_size); +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp new file mode 100644 index 0000000..7d711a2 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp @@ -0,0 +1,66 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file entry_metadata_base.hpp + * Contains an implementation for a list update map. + */ + +#ifndef PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP +#define PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP + +namespace pb_ds +{ + namespace detail + { + template<typename Metadata> + struct lu_map_entry_metadata_base + { + Metadata m_update_metadata; + }; + + template<> + struct lu_map_entry_metadata_base<null_lu_metadata> + { }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp new file mode 100644 index 0000000..85ac02d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp @@ -0,0 +1,141 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + if (m_p_l == NULL) + return false; + + if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) + { + entry_pointer p_next = m_p_l->m_p_next; + actual_erase_entry(m_p_l); + m_p_l = p_next; + return true; + } + + entry_pointer p_l = m_p_l; + while (p_l->m_p_next != NULL) + if (s_eq_fn(r_key, PB_DS_V2F(p_l->m_p_next->m_value))) + { + erase_next(p_l); + return true; + } + else + p_l = p_l->m_p_next; + return false; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + deallocate_all(); +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + size_type num_ersd = 0; + while (m_p_l != NULL && pred(m_p_l->m_value)) + { + entry_pointer p_next = m_p_l->m_p_next; + ++num_ersd; + actual_erase_entry(m_p_l); + m_p_l = p_next; + } + + if (m_p_l == NULL) + return num_ersd; + + entry_pointer p_l = m_p_l; + while (p_l->m_p_next != NULL) + { + if (pred(p_l->m_p_next->m_value)) + { + ++num_ersd; + erase_next(p_l); + } + else + p_l = p_l->m_p_next; + } + + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_next(entry_pointer p_l) +{ + _GLIBCXX_DEBUG_ASSERT(p_l != NULL); + _GLIBCXX_DEBUG_ASSERT(p_l != m_p_l); + _GLIBCXX_DEBUG_ASSERT(p_l->m_p_next != NULL); + entry_pointer p_next_l = p_l->m_p_next->m_p_next; + actual_erase_entry(p_l->m_p_next); + p_l->m_p_next = p_next_l; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +actual_erase_entry(entry_pointer p_l) +{ + _GLIBCXX_DEBUG_ONLY(map_debug_base::erase_existing(PB_DS_V2F(p_l->m_value));) + p_l->~entry(); + s_entry_allocator.deallocate(p_l, 1); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp new file mode 100644 index 0000000..37c173d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp @@ -0,0 +1,96 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +find_imp(const_key_reference r_key) const +{ + if (m_p_l == NULL) + return NULL; + if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) + { + apply_update(m_p_l, s_metadata_type_indicator); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return m_p_l; + } + + entry_pointer p_l = m_p_l; + while (p_l->m_p_next != NULL) + { + entry_pointer p_next = p_l->m_p_next; + if (s_eq_fn(r_key, PB_DS_V2F(p_next->m_value))) + { + if (apply_update(p_next, s_metadata_type_indicator)) + { + p_l->m_p_next = p_next->m_p_next; + p_next->m_p_next = m_p_l; + m_p_l = p_next; + return m_p_l; + } + return p_next; + } + else + p_l = p_next; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return NULL; +} + +PB_DS_CLASS_T_DEC +template<typename Metadata> +inline bool +PB_DS_CLASS_C_DEC:: +apply_update(entry_pointer p_l, type_to_type<Metadata>) +{ return s_update_policy(p_l->m_update_metadata); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +apply_update(entry_pointer, type_to_type<null_lu_metadata>) +{ return s_update_policy(s_null_lu_metadata); } + diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp new file mode 100644 index 0000000..a7fe8c4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp @@ -0,0 +1,63 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return std::distance(begin(), end()); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_entry_allocator.max_size(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (m_p_l == NULL); } diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp new file mode 100644 index 0000000..af60c07 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp @@ -0,0 +1,112 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline std::pair< + typename PB_DS_CLASS_C_DEC::point_iterator, + bool> +PB_DS_CLASS_C_DEC:: +insert(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_l = find_imp(PB_DS_V2F(r_val)); + + if (p_l != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(PB_DS_V2F(r_val));) + return std::make_pair(point_iterator(&p_l->m_value), false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(PB_DS_V2F(r_val));) + + p_l = allocate_new_entry(r_val, traits_base::m_no_throw_copies_indicator); + p_l->m_p_next = m_p_l; + m_p_l = p_l; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return std::make_pair(point_iterator(&p_l->m_value), true); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +allocate_new_entry(const_reference r_val, false_type) +{ + entry_pointer p_l = s_entry_allocator.allocate(1); + cond_dealtor_t cond(p_l); + new (const_cast<void* >(static_cast<const void* >(&p_l->m_value))) + value_type(r_val); + + cond.set_no_action(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + init_entry_metadata(p_l, s_metadata_type_indicator); + return p_l; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +allocate_new_entry(const_reference r_val, true_type) +{ + entry_pointer p_l = s_entry_allocator.allocate(1); + new (&p_l->m_value) value_type(r_val); + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + init_entry_metadata(p_l, s_metadata_type_indicator); + return p_l; +} + +PB_DS_CLASS_T_DEC +template<typename Metadata> +inline void +PB_DS_CLASS_C_DEC:: +init_entry_metadata(entry_pointer p_l, type_to_type<Metadata>) +{ new (&p_l->m_update_metadata) Metadata(s_update_policy()); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +init_entry_metadata(entry_pointer, type_to_type<null_lu_metadata>) +{ } + diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp new file mode 100644 index 0000000..e962032 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp @@ -0,0 +1,86 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + if (m_p_l == NULL) + { + _GLIBCXX_DEBUG_ASSERT(empty()); + return end(); + } + return iterator(&m_p_l->m_value, m_p_l, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + if (m_p_l == NULL) + { + _GLIBCXX_DEBUG_ASSERT(empty()); + return end(); + } + return iterator(&m_p_l->m_value, m_p_l, const_cast<PB_DS_CLASS_C_DEC* >(this)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ return iterator(NULL, NULL, this); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ + return const_iterator(NULL, NULL, const_cast<PB_DS_CLASS_C_DEC* const>(this)); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp new file mode 100644 index 0000000..e99dc73 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp @@ -0,0 +1,365 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file lu_map_.hpp + * Contains a list update map. + */ + +#include <utility> +#include <iterator> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp> +#include <ext/pb_ds/exception.hpp> +#ifdef _GLIBCXX_DEBUG +#include <ext/pb_ds/detail/map_debug_base.hpp> +#endif +#ifdef PB_DS_LU_MAP_TRACE_ +#include <iostream> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, class Eq_Fn, \ + class Allocator, class Update_Policy> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME lu_map_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME lu_map_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Eq_Fn, Allocator, Update_Policy> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, false> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, Eq_Fn, \ + typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + + /* Skip to the lu, my darling. */ + // list-based (with updates) associative container. + template<typename Key, + typename Mapped, + class Eq_Fn, + class Allocator, + class Update_Policy> + class PB_DS_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + protected PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + + struct entry + : public lu_map_entry_metadata_base<typename Update_Policy::metadata_type> + { + typename traits_base::value_type m_value; + typename Allocator::template rebind<entry>::other::pointer m_p_next; + }; + + typedef typename Allocator::template rebind<entry>::other entry_allocator; + typedef typename entry_allocator::pointer entry_pointer; + typedef typename entry_allocator::const_pointer const_entry_pointer; + typedef typename entry_allocator::reference entry_reference; + typedef typename entry_allocator::const_reference const_entry_reference; + + typedef typename Allocator::template rebind<entry_pointer>::other entry_pointer_allocator; + typedef typename entry_pointer_allocator::pointer entry_pointer_array; + + typedef typename traits_base::value_type value_type_; + typedef typename traits_base::pointer pointer_; + typedef typename traits_base::const_pointer const_pointer_; + typedef typename traits_base::reference reference_; + typedef typename traits_base::const_reference const_reference_; + +#define PB_DS_GEN_POS entry_pointer + +#include <ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> + +#undef PB_DS_GEN_POS + + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + + typedef cond_dealtor<entry, Allocator> cond_dealtor_t; + + public: + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef Eq_Fn eq_fn; + typedef Update_Policy update_policy; + typedef typename Update_Policy::metadata_type update_metadata; + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef point_iterator_ point_iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_point_iterator_ point_iterator; +#endif + + typedef const_point_iterator_ const_point_iterator; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef iterator_ iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_iterator_ iterator; +#endif + + typedef const_iterator_ const_iterator; + + public: + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + virtual + ~PB_DS_CLASS_NAME(); + + template<typename It> + PB_DS_CLASS_NAME(It first_it, It last_it); + + void + swap(PB_DS_CLASS_C_DEC&); + + inline size_type + size() const; + + inline size_type + max_size() const; + + inline bool + empty() const; + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return insert(std::make_pair(r_key, mapped_type())).first->second; +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline std::pair<point_iterator, bool> + insert(const_reference); + + inline point_iterator + find(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_e = find_imp(r_key); + return point_iterator(p_e == NULL ? NULL: &p_e->m_value); + } + + inline const_point_iterator + find(const_key_reference r_key) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_e = find_imp(r_key); + return const_point_iterator(p_e == NULL ? NULL: &p_e->m_value); + } + + inline bool + erase(const_key_reference); + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + clear(); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_LU_MAP_TRACE_ + void + trace() const; +#endif + + protected: + + template<typename It> + void + copy_from_range(It, It); + + private: +#ifdef PB_DS_DATA_TRUE_INDICATOR + friend class iterator_; +#endif + + friend class const_iterator_; + + inline entry_pointer + allocate_new_entry(const_reference, false_type); + + inline entry_pointer + allocate_new_entry(const_reference, true_type); + + template<typename Metadata> + inline static void + init_entry_metadata(entry_pointer, type_to_type<Metadata>); + + inline static void + init_entry_metadata(entry_pointer, type_to_type<null_lu_metadata>); + + void + deallocate_all(); + + void + erase_next(entry_pointer); + + void + actual_erase_entry(entry_pointer); + + void + inc_it_state(const_pointer& r_p_value, entry_pointer& r_pos) const + { + r_pos = r_pos->m_p_next; + r_p_value = (r_pos == NULL) ? NULL : &r_pos->m_value; + } + + template<typename Metadata> + inline static bool + apply_update(entry_pointer, type_to_type<Metadata>); + + inline static bool + apply_update(entry_pointer, type_to_type<null_lu_metadata>); + + inline entry_pointer + find_imp(const_key_reference) const; + + static entry_allocator s_entry_allocator; + static Eq_Fn s_eq_fn; + static Update_Policy s_update_policy; + static type_to_type<update_metadata> s_metadata_type_indicator; + static null_lu_metadata s_null_lu_metadata; + + mutable entry_pointer m_p_l; + }; + +#include <ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S + + } // namespace detail +} // namespace pb_ds diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp new file mode 100644 index 0000000..28bd7c4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp @@ -0,0 +1,65 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +#ifdef PB_DS_LU_MAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << m_p_l << std::endl << std::endl; + const_entry_pointer p_l = m_p_l; + while (p_l != NULL) + { + std::cerr << PB_DS_V2F(p_l->m_value) << std::endl; + p_l = p_l->m_p_next; + } + std::cerr << std::endl; +} + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_metadata.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_metadata.hpp new file mode 100644 index 0000000..d8cd289 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_metadata.hpp @@ -0,0 +1,92 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file counter_lu_metadata.hpp + * Contains implementation of a lu counter policy's metadata. + */ + +namespace pb_ds +{ + namespace detail + { + template<typename Size_Type> + class counter_lu_policy_base; + + // A list-update metadata type that moves elements to the front of + // the list based on the counter algorithm. + template<typename Size_Type = size_t> + class counter_lu_metadata + { + public: + typedef Size_Type size_type; + + private: + counter_lu_metadata(size_type init_count) : m_count(init_count) + { } + + friend class counter_lu_policy_base<size_type>; + + mutable size_type m_count; + }; + + template<typename Size_Type> + class counter_lu_policy_base + { + protected: + typedef Size_Type size_type; + + counter_lu_metadata<size_type> + operator()(size_type max_size) const + { return counter_lu_metadata<Size_Type>(rand() % max_size); } + + template<typename Metadata_Reference> + bool + operator()(Metadata_Reference r_data, size_type m_max_count) const + { + if (++r_data.m_count != m_max_count) + return false; + r_data.m_count = 0; + return true; + } + }; + } // namespace detail +} // namespace pb_ds diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_policy_imp.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_policy_imp.hpp new file mode 100644 index 0000000..42e1bdf --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_policy_imp.hpp @@ -0,0 +1,57 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file counter_lu_policy_imp.hpp + * Contains a lu counter policy implementation. + */ + +PB_DS_CLASS_T_DEC +detail::counter_lu_metadata<typename Allocator::size_type> +PB_DS_CLASS_C_DEC:: +operator()() const +{ return (base_type::operator()(max_count)); } + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +operator()(metadata_reference r_data) const +{ return (base_type::operator()(r_data, max_count)); } diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_policy/mtf_lu_policy_imp.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_policy/mtf_lu_policy_imp.hpp new file mode 100644 index 0000000..8f9d946 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_policy/mtf_lu_policy_imp.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file mtf_lu_policy_imp.hpp + * Contains a move-to-front policy implementation. + */ + +PB_DS_CLASS_T_DEC +null_lu_metadata PB_DS_CLASS_C_DEC::s_metadata; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::metadata_type +PB_DS_CLASS_C_DEC:: +operator()() const +{ return s_metadata; } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +operator()(metadata_reference /*r_data*/) const +{ return true; } + diff --git a/libstdc++/include/ext/pb_ds/detail/list_update_policy/sample_update_policy.hpp b/libstdc++/include/ext/pb_ds/detail/list_update_policy/sample_update_policy.hpp new file mode 100644 index 0000000..8cfc1f2 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/list_update_policy/sample_update_policy.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_update_policy.hpp + * Contains a sample policy for list update containers. + */ + +#ifndef PB_DS_SAMPLE_UPDATE_POLICY_HPP +#define PB_DS_SAMPLE_UPDATE_POLICY_HPP + +// A sample list-update policy. +struct sample_update_policy +{ + // Default constructor. + sample_update_policy(); + + // Copy constructor. + sample_update_policy(const sample_update_policy&); + + // Swaps content. + inline void + swap(sample_update_policy& other); + +protected: + // Metadata on which this functor operates. + typedef some_metadata_type metadata_type; + + // Creates a metadata object. + metadata_type + operator()() const; + + // Decides whether a metadata object should be moved to the front of + // the list. A list-update based containers object will call this + // method to decide whether to move a node to the front of the + // list. The method shoule return true if the node should be moved + // to the front of the list. + bool + operator()(metadata_reference) const; +}; + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/map_debug_base.hpp b/libstdc++/include/ext/pb_ds/detail/map_debug_base.hpp new file mode 100644 index 0000000..d31a0c2 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/map_debug_base.hpp @@ -0,0 +1,356 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file map_debug_base.hpp + * Contains a debug-mode base for all maps. + */ + +#ifndef PB_DS_MAP_DEBUG_BASE_HPP +#define PB_DS_MAP_DEBUG_BASE_HPP + +#ifdef _GLIBCXX_DEBUG + +#include <list> +#include <utility> +#include <ext/throw_allocator.h> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, class Eq_Fn, typename Const_Key_Reference> + +#define PB_DS_CLASS_C_DEC \ + map_debug_base<Key, Eq_Fn, Const_Key_Reference> + + template<typename Key, class Eq_Fn, typename Const_Key_Reference> + class map_debug_base + { + private: + typedef typename std::allocator< Key> key_allocator; + + typedef typename key_allocator::size_type size_type; + + typedef Const_Key_Reference const_key_reference; + + protected: + map_debug_base(); + + map_debug_base(const PB_DS_CLASS_C_DEC& other); + + ~map_debug_base(); + + inline void + insert_new(const_key_reference r_key); + + inline void + erase_existing(const_key_reference r_key); + + void + clear(); + + inline void + check_key_exists(const_key_reference r_key) const; + + inline void + check_key_does_not_exist(const_key_reference r_key) const; + + inline void + check_size(size_type size) const; + + void + swap(PB_DS_CLASS_C_DEC& other); + + template<typename Cmp_Fn> + void + split(const_key_reference, Cmp_Fn, PB_DS_CLASS_C_DEC&); + + void + join(PB_DS_CLASS_C_DEC& other); + + private: + typedef std::list< Key> key_set; + typedef typename key_set::iterator key_set_iterator; + typedef typename key_set::const_iterator const_key_set_iterator; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + + const_key_set_iterator + find(const_key_reference r_key) const; + + key_set_iterator + find(const_key_reference r_key); + + key_set m_key_set; + Eq_Fn m_eq; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + map_debug_base() + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + map_debug_base(const PB_DS_CLASS_C_DEC& other) : m_key_set(other.m_key_set) + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ~map_debug_base() + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + insert_new(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + __gnu_cxx::throw_allocator<char> alloc; + const double orig_throw_prob = alloc.get_throw_prob(); + alloc.set_throw_prob(0); + if (find(r_key) != m_key_set.end()) + { + std::cerr << "insert_new " << r_key << std::endl; + abort(); + } + + try + { + m_key_set.push_back(r_key); + } + catch(...) + { + std::cerr << "insert_new 1" << r_key << std::endl; + abort(); + } + alloc.set_throw_prob(orig_throw_prob); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + erase_existing(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + key_set_iterator it = find(r_key); + if (it == m_key_set.end()) + { + std::cerr << "erase_existing " << r_key << std::endl; + abort(); + } + m_key_set.erase(it); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + clear() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + m_key_set.clear(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + check_key_exists(const_key_reference r_key) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (find(r_key) == m_key_set.end()) + { + std::cerr << "check_key_exists " << r_key << std::endl; + abort(); + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + check_key_does_not_exist(const_key_reference r_key) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (find(r_key) != m_key_set.end()) + { + std::cerr << "check_key_does_not_exist " << r_key << std::endl; + abort(); + } + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + check_size(size_type size) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const size_type key_set_size = m_key_set.size(); + if (size != key_set_size) + { + std::cerr << "check_size " << size + << " " << key_set_size << std::endl; + abort(); + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + m_key_set.swap(other.m_key_set); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_key_set_iterator + PB_DS_CLASS_C_DEC:: + find(const_key_reference r_key) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + typedef const_key_set_iterator iterator_type; + for (iterator_type it = m_key_set.begin(); it != m_key_set.end(); ++it) + if (m_eq(*it, r_key)) + return it; + return m_key_set.end(); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::key_set_iterator + PB_DS_CLASS_C_DEC:: + find(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + key_set_iterator it = m_key_set.begin(); + while (it != m_key_set.end()) + { + if (m_eq(*it, r_key)) + return it; + ++it; + } + return it; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + assert_valid() const + { + const_key_set_iterator prime_it = m_key_set.begin(); + while (prime_it != m_key_set.end()) + { + const_key_set_iterator sec_it = prime_it; + ++sec_it; + while (sec_it != m_key_set.end()) + { + _GLIBCXX_DEBUG_ASSERT(!m_eq(*sec_it, *prime_it)); + _GLIBCXX_DEBUG_ASSERT(!m_eq(*prime_it, *sec_it)); + ++sec_it; + } + ++prime_it; + } + } +#endif + + PB_DS_CLASS_T_DEC + template<typename Cmp_Fn> + void + PB_DS_CLASS_C_DEC:: + split(const_key_reference r_key, Cmp_Fn cmp_fn, PB_DS_CLASS_C_DEC& other) + { + __gnu_cxx::throw_allocator<char> alloc; + const double orig_throw_prob = alloc.get_throw_prob(); + alloc.set_throw_prob(0); + other.clear(); + key_set_iterator it = m_key_set.begin(); + while (it != m_key_set.end()) + if (cmp_fn(r_key, * it)) + { + other.insert_new(*it); + it = m_key_set.erase(it); + } + else + ++it; + alloc.set_throw_prob(orig_throw_prob); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + join(PB_DS_CLASS_C_DEC& other) + { + __gnu_cxx::throw_allocator<char> alloc; + const double orig_throw_prob = alloc.get_throw_prob(); + alloc.set_throw_prob(0); + key_set_iterator it = other.m_key_set.begin(); + while (it != other.m_key_set.end()) + { + insert_new(*it); + it = other.m_key_set.erase(it); + } + _GLIBCXX_DEBUG_ASSERT(other.m_key_set.empty()); + alloc.set_throw_prob(orig_throw_prob); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace detail +} // namespace pb_ds + +#endif + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp new file mode 100644 index 0000000..072fce4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_dtor.hpp + * Contains a conditional destructor + */ + +template<typename Size_Type> +class cond_dtor +{ +public: + cond_dtor(value_vector a_vec, iterator& r_last_it, Size_Type total_size) + : m_a_vec(a_vec), m_r_last_it(r_last_it), m_max_size(total_size), + m_no_action(false) + { } + + ~cond_dtor() + { + if (m_no_action) + return; + iterator it = m_a_vec; + while (it != m_r_last_it) + { + it->~value_type(); + ++it; + } + + if (m_max_size > 0) + value_allocator().deallocate(m_a_vec, m_max_size); + } + + inline void + set_no_action() + { m_no_action = true; } + +protected: + value_vector m_a_vec; + iterator& m_r_last_it; + const Size_Type m_max_size; + bool m_no_action; +}; diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..83a4725 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,279 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::value_allocator +PB_DS_CLASS_C_DEC::s_value_alloc; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::metadata_allocator +PB_DS_CLASS_C_DEC::s_metadata_alloc; + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_OV_TREE_CLASS_NAME() : + m_a_values(NULL), + m_a_metadata(NULL), + m_end_it(NULL), + m_size(0) +{ _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn& r_cmp_fn) : + cmp_fn_base(r_cmp_fn), + m_a_values(NULL), + m_a_metadata(NULL), + m_end_it(NULL), + m_size(0) +{ _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : + cmp_fn_base(r_cmp_fn), + node_update(r_node_update), + m_a_values(NULL), + m_a_metadata(NULL), + m_end_it(NULL), + m_size(0) +{ _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_OV_TREE_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif +#ifdef PB_DS_TREE_TRACE + PB_DS_TREE_TRACE_BASE_C_DEC(other), +#endif + cmp_fn_base(other), + node_update(other), + m_a_values(NULL), + m_a_metadata(NULL), + m_end_it(NULL), + m_size(0) +{ + copy_from_ordered_range(other.begin(), other.end()); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +template<typename It> +inline void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef + std::map< + key_type, + mapped_type, + Cmp_Fn, + typename Allocator::template rebind< + value_type>::other> + map_type; +#else + typedef + std::set< + key_type, + Cmp_Fn, + typename Allocator::template rebind< + Key>::other> + map_type; +#endif + + map_type m(first_it, last_it); + copy_from_ordered_range(m.begin(), m.end()); +} + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_ordered_range(It first_it, It last_it) +{ + const size_type len = std::distance(first_it, last_it); + if (len == 0) + return; + + value_vector a_values = s_value_alloc.allocate(len); + iterator target_it = a_values; + It source_it = first_it; + It source_end_it = last_it; + + cond_dtor<size_type> cd(a_values, target_it, len); + while (source_it != source_end_it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + + ++target_it; + } + + reallocate_metadata((node_update* )this, len); + cd.set_no_action(); + m_a_values = a_values; + m_size = len; + m_end_it = m_a_values + m_size; + update(PB_DS_node_begin_imp(), (node_update* )this); + +#ifdef _GLIBCXX_DEBUG + const_iterator dbg_it = m_a_values; + while (dbg_it != m_end_it) + { + map_debug_base::insert_new(PB_DS_V2F(*dbg_it)); + dbg_it++; + } + PB_DS_CLASS_C_DEC::assert_valid(); +#endif +} + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_ordered_range(It first_it, It last_it, It other_first_it, + It other_last_it) +{ + clear(); + const size_type len = std::distance(first_it, last_it) + + std::distance(other_first_it, other_last_it); + + value_vector a_values = s_value_alloc.allocate(len); + + iterator target_it = a_values; + It source_it = first_it; + It source_end_it = last_it; + + cond_dtor<size_type> cd(a_values, target_it, len); + while (source_it != source_end_it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + ++target_it; + } + + source_it = other_first_it; + source_end_it = other_last_it; + + while (source_it != source_end_it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + ++target_it; + } + + reallocate_metadata((node_update* )this, len); + cd.set_no_action(); + m_a_values = a_values; + m_size = len; + m_end_it = m_a_values + m_size; + update(PB_DS_node_begin_imp(), (node_update* )this); + +#ifdef _GLIBCXX_DEBUG + const_iterator dbg_it = m_a_values; + while (dbg_it != m_end_it) + { + map_debug_base::insert_new(PB_DS_V2F(*dbg_it)); + dbg_it++; + } + PB_DS_CLASS_C_DEC::assert_valid(); +#endif +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + value_swap(other); + std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_a_values, other.m_a_values); + std::swap(m_a_metadata, other.m_a_metadata); + std::swap(m_size, other.m_size); + std::swap(m_end_it, other.m_end_it); + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other);) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_OV_TREE_CLASS_NAME() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + cond_dtor<size_type> cd(m_a_values, m_end_it, m_size); + reallocate_metadata((node_update* )this, 0); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update(node_iterator /*it*/, null_node_update_pointer) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update> +void +PB_DS_CLASS_C_DEC:: +update(node_iterator nd_it, Node_Update* p_update) +{ + const_node_iterator end_it = PB_DS_node_end_imp(); + if (nd_it == end_it) + return; + update(nd_it.get_l_child(), p_update); + update(nd_it.get_r_child(), p_update); + node_update::operator()(nd_it, end_it); +} diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp new file mode 100644 index 0000000..b1a3655 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp @@ -0,0 +1,90 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + std::cout << "av1" << std::endl; + + if (m_a_values == NULL || m_end_it == NULL || m_size == 0) + _GLIBCXX_DEBUG_ASSERT(m_a_values == NULL && m_end_it == NULL && m_size == 0); + + std::cout << "av2" << std::endl; + assert_iterators(); + std::cout << "av3" << std::endl; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_iterators() const +{ + map_debug_base::check_size(m_size); + size_type iterated_num = 0; + const_iterator prev_it = end(); + _GLIBCXX_DEBUG_ASSERT( m_end_it == m_a_values + m_size); + for (const_iterator it = begin(); it != end(); ++it) + { + ++iterated_num; + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(PB_DS_V2F(*it));) + _GLIBCXX_DEBUG_ASSERT(lower_bound(PB_DS_V2F(*it)) == it); + const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); + --upper_bound_it; + _GLIBCXX_DEBUG_ASSERT(upper_bound_it == it); + if (prev_it != end()) + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), + PB_DS_V2F(*it))); + prev_it = it; + } + _GLIBCXX_DEBUG_ASSERT(iterated_num == m_size); +} + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp new file mode 100644 index 0000000..936d549 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp @@ -0,0 +1,199 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (m_size == 0) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return; + } + else + { + reallocate_metadata((node_update* )this, 0); + cond_dtor<size_type> cd(m_a_values, m_end_it, m_size); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + m_a_values = NULL; + m_size = 0; + m_end_it = m_a_values; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + +#ifdef PB_DS_REGRESSION + typename Allocator::group_throw_prob_adjustor adjust(m_size); +#endif + + size_type new_size = 0; + size_type num_val_ersd = 0; + iterator source_it = m_a_values; + for (source_it = begin(); source_it != m_end_it; ++source_it) + if (!pred(*source_it)) + ++new_size; + else + ++num_val_ersd; + + if (new_size == 0) + { + clear(); + return num_val_ersd; + } + + value_vector a_new_values = s_value_alloc.allocate(new_size); + iterator target_it = a_new_values; + cond_dtor<size_type> cd(a_new_values, target_it, new_size); + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear()); + for (source_it = begin(); source_it != m_end_it; ++source_it) + { + if (!pred(*source_it)) + { + new (const_cast<void*>(static_cast<const void* >(target_it))) + value_type(*source_it); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(*source_it))); + ++target_it; + } + } + + reallocate_metadata((node_update* )this, new_size); + cd.set_no_action(); + + { + cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); + } + + m_a_values = a_new_values; + m_size = new_size; + m_end_it = target_it; + update(node_begin(), (node_update* )this); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return num_val_ersd; +} + +PB_DS_CLASS_T_DEC +template<typename It> +It +PB_DS_CLASS_C_DEC:: +erase_imp(It it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (it == end()) + return end(); + + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::check_key_exists(PB_DS_V2F(*it));) + +#ifdef PB_DS_REGRESSION + typename Allocator::group_throw_prob_adjustor adjust(m_size); +#endif + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + value_vector a_values = s_value_alloc.allocate(m_size - 1); + iterator source_it = begin(); + iterator source_end_it = end(); + iterator target_it = a_values; + iterator ret_it = end(); + + cond_dtor<size_type> cd(a_values, target_it, m_size - 1); + + _GLIBCXX_DEBUG_ONLY(size_type cnt = 0;) + + while (source_it != source_end_it) + { + if (source_it != it) + { + _GLIBCXX_DEBUG_ONLY(++cnt;) + _GLIBCXX_DEBUG_ASSERT(cnt != m_size); + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it); + + ++target_it; + } + else + ret_it = target_it; + ++source_it; + } + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + reallocate_metadata((node_update* )this, m_size - 1); + cd.set_no_action(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::erase_existing(PB_DS_V2F(*it));) + { + cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); + } + + m_a_values = a_values; + --m_size; + m_end_it = m_a_values + m_size; + update(node_begin(), (node_update* )this); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return It(ret_it); +} + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + point_iterator it = find(r_key); + if (it == end()) + return false; + erase(it); + return true; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp new file mode 100644 index 0000000..05161cb --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp @@ -0,0 +1,66 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return m_size; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_value_alloc.max_size(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return size() == 0; } diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp new file mode 100644 index 0000000..16d6f04 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp @@ -0,0 +1,69 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +reallocate_metadata(null_node_update_pointer, size_type) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +void +PB_DS_CLASS_C_DEC:: +reallocate_metadata(Node_Update_* , size_type new_size) +{ + metadata_pointer a_new_metadata_vec =(new_size == 0) ? NULL : s_metadata_alloc.allocate(new_size); + + if (m_a_metadata != NULL) + { + for (size_type i = 0; i < m_size; ++i) + m_a_metadata[i].~metadata_type(); + s_metadata_alloc.deallocate(m_a_metadata, m_size); + } + std::swap(m_a_metadata, a_new_metadata_vec); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp new file mode 100644 index 0000000..38d4cee --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp @@ -0,0 +1,109 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() const +{ return PB_DS_node_begin_imp(); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_end() const +{ return PB_DS_node_end_imp(); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() +{ return PB_DS_node_begin_imp(); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_end() +{ return PB_DS_node_end_imp(); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +PB_DS_node_begin_imp() const +{ + return const_node_iterator(const_cast<pointer>(mid_pointer(begin(), end())), + const_cast<pointer>(begin()), + const_cast<pointer>(end()),(m_a_metadata == NULL)? + NULL : + mid_pointer(m_a_metadata, m_a_metadata + m_size)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +PB_DS_node_end_imp() const +{ + return const_node_iterator(end(), end(), end(), + (m_a_metadata == NULL) ? NULL : m_a_metadata + m_size); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +PB_DS_node_begin_imp() +{ + return node_iterator(mid_pointer(begin(), end()), begin(), end(), + (m_a_metadata == NULL) ? NULL : mid_pointer(m_a_metadata, m_a_metadata + m_size)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +PB_DS_node_end_imp() +{ + return node_iterator(end(), end(), + end(),(m_a_metadata == NULL) ? NULL : m_a_metadata + m_size); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp new file mode 100644 index 0000000..d64ad20 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp @@ -0,0 +1,303 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_iterators.hpp + * Contains an implementation class for ov_tree_. + */ + +#ifndef PB_DS_OV_TREE_NODE_ITERATORS_HPP +#define PB_DS_OV_TREE_NODE_ITERATORS_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef \ + static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> \ + UNIQUE##static_assert_type + +#define PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC \ + ov_tree_node_const_it_<Value_Type, Metadata_Type, Allocator> + + // Const node reference. + template<typename Value_Type, typename Metadata_Type, class Allocator> + class ov_tree_node_const_it_ + { + + protected: + typedef + typename Allocator::template rebind< + Value_Type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + Value_Type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + Metadata_Type>::other::const_pointer + const_metadata_pointer; + + typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC this_type; + + protected: + + template<typename Ptr> + inline static Ptr + mid_pointer(Ptr p_begin, Ptr p_end) + { + _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); + return (p_begin + (p_end - p_begin) / 2); + } + + public: + + typedef trivial_iterator_tag iterator_category; + + typedef trivial_iterator_difference_type difference_type; + + typedef + typename Allocator::template rebind< + Value_Type>::other::const_pointer + value_type; + + typedef + typename Allocator::template rebind< + typename remove_const< + Value_Type>::type>::other::const_pointer + reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + Value_Type>::type>::other::const_pointer + const_reference; + + typedef Metadata_Type metadata_type; + + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + public: + inline + ov_tree_node_const_it_(const_pointer p_nd = NULL, const_pointer p_begin_nd = NULL, const_pointer p_end_nd = NULL, const_metadata_pointer p_metadata = NULL) : m_p_value(const_cast<pointer>(p_nd)), m_p_begin_value(const_cast<pointer>(p_begin_nd)), m_p_end_value(const_cast<pointer>(p_end_nd)), m_p_metadata(p_metadata) + { } + + inline const_reference + operator*() const + { return m_p_value; } + + inline const_metadata_reference + get_metadata() const + { + enum + { + has_metadata = !is_same<Metadata_Type, null_node_metadata>::value + }; + + PB_DS_STATIC_ASSERT(should_have_metadata, has_metadata); + _GLIBCXX_DEBUG_ASSERT(m_p_metadata != NULL); + return *m_p_metadata; + } + + inline this_type + get_l_child() const + { + if (m_p_begin_value == m_p_value) + return (this_type(m_p_begin_value, m_p_begin_value, m_p_begin_value)); + + const_metadata_pointer p_begin_metadata = + m_p_metadata - (m_p_value - m_p_begin_value); + + return (this_type(mid_pointer(m_p_begin_value, m_p_value), + m_p_begin_value, + m_p_value, + mid_pointer(p_begin_metadata, m_p_metadata))); + } + + inline this_type + get_r_child() const + { + if (m_p_value == m_p_end_value) + return (this_type(m_p_end_value, m_p_end_value, m_p_end_value)); + + const_metadata_pointer p_end_metadata = + m_p_metadata + (m_p_end_value - m_p_value); + + return (this_type(mid_pointer(m_p_value + 1, m_p_end_value), + m_p_value + 1, + m_p_end_value,(m_p_metadata == NULL) ? + NULL : mid_pointer(m_p_metadata + 1, p_end_metadata))); + } + + inline bool + operator==(const this_type& other) const + { + const bool is_end = m_p_begin_value == m_p_end_value; + const bool is_other_end = other.m_p_begin_value == other.m_p_end_value; + + if (is_end) + return (is_other_end); + + if (is_other_end) + return (is_end); + + return m_p_value == other.m_p_value; + } + + inline bool + operator!=(const this_type& other) const + { return !operator==(other); } + + public: + pointer m_p_value; + pointer m_p_begin_value; + pointer m_p_end_value; + + const_metadata_pointer m_p_metadata; + }; + +#define PB_DS_OV_TREE_NODE_ITERATOR_C_DEC \ + ov_tree_node_it_<Value_Type, Metadata_Type, Allocator> + + // Node reference. + template<typename Value_Type, typename Metadata_Type, class Allocator> + class ov_tree_node_it_ : public PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC + { + + private: + typedef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC this_type; + + typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC base_type; + + typedef typename base_type::pointer pointer; + + typedef typename base_type::const_pointer const_pointer; + + typedef + typename base_type::const_metadata_pointer + const_metadata_pointer; + + public: + + typedef trivial_iterator_tag iterator_category; + + typedef trivial_iterator_difference_type difference_type; + + typedef + typename Allocator::template rebind< + Value_Type>::other::pointer + value_type; + + typedef + typename Allocator::template rebind< + typename remove_const< + Value_Type>::type>::other::pointer + reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + Value_Type>::type>::other::pointer + const_reference; + + public: + inline + ov_tree_node_it_(const_pointer p_nd = NULL, const_pointer p_begin_nd = NULL, const_pointer p_end_nd = NULL, const_metadata_pointer p_metadata = NULL) : base_type( p_nd, p_begin_nd, p_end_nd, p_metadata) + { } + + // Access. + inline reference + operator*() const + { return reference(base_type::m_p_value); } + + // Returns the node reference associated with the left node. + inline ov_tree_node_it_ + get_l_child() const + { + if (base_type::m_p_begin_value == base_type::m_p_value) + return (this_type(base_type::m_p_begin_value, base_type::m_p_begin_value, base_type::m_p_begin_value)); + + const_metadata_pointer p_begin_metadata = + base_type::m_p_metadata - (base_type::m_p_value - base_type::m_p_begin_value); + + return (this_type(base_type::mid_pointer(base_type::m_p_begin_value, base_type::m_p_value), + base_type::m_p_begin_value, + base_type::m_p_value, + base_type::mid_pointer(p_begin_metadata, base_type::m_p_metadata))); + } + + // Returns the node reference associated with the right node. + inline ov_tree_node_it_ + get_r_child() const + { + if (base_type::m_p_value == base_type::m_p_end_value) + return (this_type(base_type::m_p_end_value, base_type::m_p_end_value, base_type::m_p_end_value)); + + const_metadata_pointer p_end_metadata = + base_type::m_p_metadata + (base_type::m_p_end_value - base_type::m_p_value); + + return (this_type(base_type::mid_pointer(base_type::m_p_value + 1, base_type::m_p_end_value), + base_type::m_p_value + 1, + base_type::m_p_end_value,(base_type::m_p_metadata == NULL)? + NULL : base_type::mid_pointer(base_type::m_p_metadata + 1, p_end_metadata))); + } + + }; + +#undef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC +#undef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC +#undef PB_DS_STATIC_ASSERT + +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp new file mode 100644 index 0000000..f9e2714 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp @@ -0,0 +1,528 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file ov_tree_map_.hpp + * Contains an implementation class for ov_tree_. + */ + +#include <map> +#include <set> +#include <ext/pb_ds/tree_policy.hpp> +#include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/detail/map_debug_base.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/tree_trace_base.hpp> +#include <utility> +#include <functional> +#include <algorithm> +#include <vector> +#include <assert.h> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, class Cmp_Fn, \ + class Node_And_It_Traits, class Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_OV_TREE_CLASS_NAME ov_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_OV_TREE_CLASS_NAME ov_tree_no_data_ +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_data_ +#else +#define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_OV_TREE_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, false> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, eq_by_less<Key, Cmp_Fn>, \ + typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + +#ifdef PB_DS_TREE_TRACE +#define PB_DS_TREE_TRACE_BASE_C_DEC \ + tree_trace_base<typename Node_And_It_Traits::const_node_iterator, \ + typename Node_And_It_Traits::node_iterator, \ + Cmp_Fn, false, Allocator> +#endif + + // Ordered-vector tree associative-container. + template<typename Key, typename Mapped, class Cmp_Fn, + class Node_And_It_Traits, class Allocator> + class PB_DS_OV_TREE_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + protected PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif +#ifdef PB_DS_TREE_TRACE + public PB_DS_TREE_TRACE_BASE_C_DEC, +#endif + public Cmp_Fn, + public Node_And_It_Traits::node_update, + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + + typedef typename remove_const<typename traits_base::value_type>::type non_const_value_type; + + typedef typename Allocator::template rebind<non_const_value_type>::other value_allocator; + typedef typename value_allocator::pointer value_vector; + + + typedef Cmp_Fn cmp_fn_base; + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + + typedef typename traits_base::pointer mapped_pointer_; + typedef typename traits_base::const_pointer const_mapped_pointer_; + + typedef typename Node_And_It_Traits::metadata_type metadata_type; + + typedef typename Allocator::template rebind<metadata_type>::other metadata_allocator; + typedef typename metadata_allocator::pointer metadata_pointer; + typedef typename metadata_allocator::const_reference const_metadata_reference; + typedef typename metadata_allocator::reference metadata_reference; + + typedef + typename Node_And_It_Traits::null_node_update_pointer + null_node_update_pointer; + + public: + + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + + typedef Cmp_Fn cmp_fn; + + typedef typename Node_And_It_Traits::node_update node_update; + + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + + typedef const_pointer const_point_iterator; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef pointer point_iterator; +#else + typedef const_point_iterator point_iterator; +#endif + + typedef const_point_iterator const_iterator; + + typedef point_iterator iterator; + +#include <ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp> + + typedef + typename Node_And_It_Traits::const_node_iterator + const_node_iterator; + + typedef typename Node_And_It_Traits::node_iterator node_iterator; + + public: + + PB_DS_OV_TREE_CLASS_NAME(); + + PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&); + + PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&, const node_update&); + + PB_DS_OV_TREE_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + ~PB_DS_OV_TREE_CLASS_NAME(); + + void + swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_range(It, It); + + inline size_type + max_size() const; + + inline bool + empty() const; + + inline size_type + size() const; + + Cmp_Fn& + get_cmp_fn(); + + const Cmp_Fn& + get_cmp_fn() const; + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + _GLIBCXX_DEBUG_ONLY(assert_valid();) + point_iterator it = lower_bound(r_key); + if (it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return it->second; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return (insert_new_val(it, std::make_pair(r_key, mapped_type()))->second); +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline std::pair<point_iterator, bool> + insert(const_reference r_value) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const_key_reference r_key = PB_DS_V2F(r_value); + point_iterator it = lower_bound(r_key); + + if (it != end()&& !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return std::make_pair(it, false); + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return std::make_pair(insert_new_val(it, r_value), true); + } + + inline point_iterator + lower_bound(const_key_reference r_key) + { + pointer it = m_a_values; + pointer e_it = m_a_values + m_size; + while (it != e_it) + { + pointer mid_it = it + ((e_it - it) >> 1); + if (cmp_fn_base::operator()(PB_DS_V2F(*mid_it), r_key)) + it = ++mid_it; + else + e_it = mid_it; + } + return it; + } + + inline const_point_iterator + lower_bound(const_key_reference r_key) const + { return const_cast<PB_DS_CLASS_C_DEC& >(*this).lower_bound(r_key); } + + inline point_iterator + upper_bound(const_key_reference r_key) + { + iterator pot_it = lower_bound(r_key); + if (pot_it != end()&& !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return ++pot_it; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return pot_it; + } + + inline const_point_iterator + upper_bound(const_key_reference r_key) const + { return const_cast<PB_DS_CLASS_C_DEC&>(*this).upper_bound(r_key); } + + inline point_iterator + find(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + iterator pot_it = lower_bound(r_key); + if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return pot_it; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return end(); + } + + inline const_point_iterator + find(const_key_reference r_key) const + { return (const_cast<PB_DS_CLASS_C_DEC& >(*this).find(r_key)); } + + bool + erase(const_key_reference); + + template<typename Pred> + inline size_type + erase_if(Pred); + + inline iterator + erase(iterator it) + { return erase_imp<iterator>(it); } + + void + clear(); + + void + join(PB_DS_CLASS_C_DEC&); + + void + split(const_key_reference, PB_DS_CLASS_C_DEC&); + + inline iterator + begin() + { return m_a_values; } + + inline const_iterator + begin() const + { return m_a_values; } + + inline iterator + end() + { return m_end_it; } + + inline const_iterator + end() const + { return m_end_it; } + + inline const_node_iterator + node_begin() const; + + inline const_node_iterator + node_end() const; + + inline node_iterator + node_begin(); + + inline node_iterator + node_end(); + + private: + + inline void + update(node_iterator /*it*/, null_node_update_pointer); + + template<typename Node_Update> + void + update(node_iterator, Node_Update*); + + void + reallocate_metadata(null_node_update_pointer, size_type); + + template<typename Node_Update_> + void + reallocate_metadata(Node_Update_*, size_type); + + template<typename It> + void + copy_from_ordered_range(It, It); + + void + value_swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_ordered_range(It, It, It, It); + + template<typename Ptr> + inline static Ptr + mid_pointer(Ptr p_begin, Ptr p_end) + { + _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); + return (p_begin + (p_end - p_begin) / 2); + } + + inline iterator + insert_new_val(iterator it, const_reference r_value) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) +#ifdef PB_DS_REGRESSION + typename Allocator::group_throw_prob_adjustor adjust(m_size); +#endif + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(PB_DS_V2F(r_value))); + + value_vector a_values = s_value_alloc.allocate(m_size + 1); + + iterator source_it = begin(); + iterator source_end_it = end(); + iterator target_it = a_values; + iterator ret_it; + + cond_dtor<size_type> cd(a_values, target_it, m_size + 1); + while (source_it != it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + ++target_it; + } + + new (const_cast<void* >(static_cast<const void* >(ret_it = target_it))) + value_type(r_value); + ++target_it; + + while (source_it != source_end_it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + ++target_it; + } + + reallocate_metadata((node_update* )this, m_size + 1); + cd.set_no_action(); + if (m_size != 0) + { + cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); + } + + ++m_size; + m_a_values = a_values; + m_end_it = m_a_values + m_size; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_value))); + update(node_begin(), (node_update* )this); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return ret_it; + } + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_iterators() const; +#endif + + template<typename It> + It + erase_imp(It it); + + inline const_node_iterator + PB_DS_node_begin_imp() const; + + inline const_node_iterator + PB_DS_node_end_imp() const; + + inline node_iterator + PB_DS_node_begin_imp(); + + inline node_iterator + PB_DS_node_end_imp(); + + private: + static value_allocator s_value_alloc; + static metadata_allocator s_metadata_alloc; + + value_vector m_a_values; + metadata_pointer m_a_metadata; + iterator m_end_it; + size_type m_size; + }; + +#include <ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_OV_TREE_CLASS_NAME +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#ifdef PB_DS_TREE_TRACE +#undef PB_DS_TREE_TRACE_BASE_C_DEC +#endif + +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S +#undef PB_DS_CONST_NODE_ITERATOR_NAME + + } // namespace detail +} // namespace pb_ds diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hpp new file mode 100644 index 0000000..8ed19f1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hpp @@ -0,0 +1,57 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() const +{ return *this; } diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp new file mode 100644 index 0000000..3b6abcd --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp @@ -0,0 +1,143 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + if (m_size == 0) + { + other.clear(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + if (Cmp_Fn::operator()(r_key, PB_DS_V2F(*begin()))) + { + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(*(end() - 1)))) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + if (m_size == 1) + { + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::join(other);) + iterator it = upper_bound(r_key); + PB_DS_CLASS_C_DEC new_other(other, other); + new_other.copy_from_ordered_range(it, end()); + PB_DS_CLASS_C_DEC new_this(*this, * this); + new_this.copy_from_ordered_range(begin(), it); + + // No exceptions from this point. + _GLIBCXX_DEBUG_ONLY(map_debug_base::split(r_key,(Cmp_Fn& )(*this), other);) + other.update(other.node_begin(), (node_update* )(&other)); + update(node_begin(), (node_update* )this); + other.value_swap(new_other); + value_swap(new_this); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (other.m_size == 0) + return; + + if (m_size == 0) + { + value_swap(other); + return; + } + + const bool greater = Cmp_Fn::operator()(PB_DS_V2F(*(end() - 1)), + PB_DS_V2F(*other.begin())); + + const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(*(other.end() - 1)), + PB_DS_V2F(*begin())); + + if (!greater && !lesser) + __throw_join_error(); + + PB_DS_CLASS_C_DEC new_this(*this, *this); + + if (greater) + new_this.copy_from_ordered_range(begin(), end(), + other.begin(), other.end()); + else + new_this.copy_from_ordered_range(other.begin(), other.end(), + begin(), end()); + + // No exceptions from this point. + _GLIBCXX_DEBUG_ONLY(map_debug_base::join(other);) + value_swap(new_this); + other.clear(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} diff --git a/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/traits.hpp b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/traits.hpp new file mode 100644 index 0000000..182c0c8 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/traits.hpp @@ -0,0 +1,189 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation class for ov_tree_. + */ + +#ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Key, + typename Mapped, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + ov_tree_tag, + Allocator> + { + private: + typedef + typename types_traits< + Key, + Mapped, + Allocator, + false>::value_type + value_type; + + public: + typedef + typename tree_node_metadata_selector< + Key, + Mapped, + Cmp_Fn, + Node_Update, + Allocator>::type + metadata_type; + + typedef + ov_tree_node_const_it_< + value_type, + metadata_type, + Allocator> + const_node_iterator; + + typedef + ov_tree_node_it_< + value_type, + metadata_type, + Allocator> + node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator> + node_update; + + typedef + pb_ds::null_tree_node_update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator>* + null_node_update_pointer; + }; + + template<typename Key, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + ov_tree_tag, + Allocator> + { + private: + typedef + typename types_traits< + Key, + null_mapped_type, + Allocator, + false>::value_type + value_type; + + public: + typedef + typename tree_node_metadata_selector< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + Allocator>::type + metadata_type; + + typedef + ov_tree_node_const_it_< + value_type, + metadata_type, + Allocator> + const_node_iterator; + + typedef const_node_iterator node_iterator; + + typedef + Node_Update< + const_node_iterator, + const_node_iterator, + Cmp_Fn, + Allocator> + node_update; + + typedef + pb_ds::null_tree_node_update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator>* + null_node_update_pointer; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP + diff --git a/libstdc++/include/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..6534f20 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + push(*(first_it++)); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +pairing_heap_() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +pairing_heap_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +pairing_heap_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + PB_DS_BASE_C_DEC::swap(other); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~pairing_heap_() +{ } diff --git a/libstdc++/include/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp new file mode 100644 index 0000000..5e6bb37 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_root == NULL + || base_type::m_p_root->m_p_next_sibling == NULL); + base_type::assert_valid(); +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp new file mode 100644 index 0000000..038b490 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp @@ -0,0 +1,242 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +pop() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + node_pointer p_new_root = join_node_children(base_type::m_p_root); + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_new_root, false);) + if (p_new_root != NULL) + p_new_root->m_p_prev_or_parent = NULL; + + base_type::actual_erase_node(base_type::m_p_root); + base_type::m_p_root = p_new_root; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + remove_node(it.m_p_nd); + base_type::actual_erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +remove_node(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + node_pointer p_new_child = join_node_children(p_nd); + +#ifdef _GLIBCXX_DEBUG + if (p_new_child != NULL) + base_type::assert_node_consistent(p_new_child, false); +#endif + + if (p_nd == base_type::m_p_root) + { + if (p_new_child != NULL) + p_new_child->m_p_prev_or_parent = NULL; + base_type::m_p_root = p_new_child; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(base_type::m_p_root, false);) + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_prev_or_parent != NULL); + if (p_nd->m_p_prev_or_parent->m_p_l_child == p_nd) + { + if (p_new_child != NULL) + { + p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; + if (p_new_child->m_p_next_sibling != NULL) + p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; + p_nd->m_p_prev_or_parent->m_p_l_child = p_new_child; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);) + return; + } + + p_nd->m_p_prev_or_parent->m_p_l_child = p_nd->m_p_next_sibling; + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);) + return; + } + + if (p_new_child != NULL) + { + p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; + if (p_new_child->m_p_next_sibling != NULL) + p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; + p_new_child->m_p_prev_or_parent->m_p_next_sibling = p_new_child; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);) + return; + } + + p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);) +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +join_node_children(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + node_pointer p_ret = p_nd->m_p_l_child; + if (p_ret == NULL) + return NULL; + while (p_ret->m_p_next_sibling != NULL) + p_ret = forward_join(p_ret, p_ret->m_p_next_sibling); + while (p_ret->m_p_prev_or_parent != p_nd) + p_ret = back_join(p_ret->m_p_prev_or_parent, p_ret); + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_ret, false);) + return p_ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +forward_join(node_pointer p_nd, node_pointer p_next) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling == p_next); + if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) + { + p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + base_type::make_child_of(p_nd, p_next); + return p_next->m_p_next_sibling == NULL + ? p_next : p_next->m_p_next_sibling; + } + + if (p_next->m_p_next_sibling != NULL) + { + p_next->m_p_next_sibling->m_p_prev_or_parent = p_nd; + p_nd->m_p_next_sibling = p_next->m_p_next_sibling; + base_type::make_child_of(p_next, p_nd); + return p_nd->m_p_next_sibling; + } + + p_nd->m_p_next_sibling = NULL; + base_type::make_child_of(p_next, p_nd); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false)); + return p_nd; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +back_join(node_pointer p_nd, node_pointer p_next) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_next->m_p_next_sibling == NULL); + + if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) + { + p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + base_type::make_child_of(p_nd, p_next); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_next, false)); + return p_next; + } + + p_nd->m_p_next_sibling = NULL; + base_type::make_child_of(p_next, p_nd); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false)); + return p_nd; +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return 0; + } + base_type::to_linked_list(); + node_pointer p_out = base_type::prune(pred); + size_type ersd = 0; + while (p_out != NULL) + { + ++ersd; + node_pointer p_next = p_out->m_p_next_sibling; + base_type::actual_erase_node(p_out); + p_out = p_next; + } + + node_pointer p_cur = base_type::m_p_root; + base_type::m_p_root = NULL; + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = NULL; + + push_imp(p_cur); + p_cur = p_next; + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return ersd; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp new file mode 100644 index 0000000..f74b0bb --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp @@ -0,0 +1,56 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + return base_type::m_p_root->m_value; +} diff --git a/libstdc++/include/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp new file mode 100644 index 0000000..41ff391 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp @@ -0,0 +1,107 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + node_pointer p_new_nd = base_type::get_new_node_for_insert(r_val); + + push_imp(p_new_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(p_new_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +push_imp(node_pointer p_nd) +{ + p_nd->m_p_l_child = NULL; + + if (base_type::m_p_root == NULL) + { + p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = NULL; + + base_type::m_p_root = p_nd; + } + else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) + { + p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = NULL; + + base_type::make_child_of(base_type::m_p_root, p_nd); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false)); + + base_type::m_p_root = p_nd; + } + else + { + base_type::make_child_of(p_nd, base_type::m_p_root); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(base_type::m_p_root, false)); + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + remove_node(it.m_p_nd); + + it.m_p_nd->m_value = r_new_val; + + push_imp(it.m_p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + diff --git a/libstdc++/include/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp new file mode 100644 index 0000000..6475474 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp @@ -0,0 +1,222 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file pairing_heap_.hpp + * Contains an implementation class for a pairing heap. + */ + +/* + * Pairing heap: + * Michael L. Fredman, Robert Sedgewick, Daniel Dominic Sleator, + * and Robert Endre Tarjan, The Pairing Heap: + * A New Form of Self-Adjusting Heap, Algorithmica, 1(1):111-129, 1986. + */ + +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + pairing_heap_<Value_Type, Cmp_Fn, Allocator> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_< \ + Value_Type, \ + Cmp_Fn, \ + null_left_child_next_sibling_heap_node_metadata, \ + Allocator, \ + false> +#else +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_< \ + Value_Type, \ + Cmp_Fn, \ + null_left_child_next_sibling_heap_node_metadata, \ + Allocator> +#endif + + /** + * class description = "P4ri|\|g h3ap$"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class pairing_heap_ : public PB_DS_BASE_C_DEC + { + + private: + typedef PB_DS_BASE_C_DEC base_type; + + typedef typename base_type::node_pointer node_pointer; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + typename PB_DS_BASE_C_DEC::const_point_iterator + const_point_iterator; + + typedef typename PB_DS_BASE_C_DEC::point_iterator point_iterator; + + typedef typename PB_DS_BASE_C_DEC::const_iterator const_iterator; + + typedef typename PB_DS_BASE_C_DEC::iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + + pairing_heap_(); + + pairing_heap_(const Cmp_Fn& r_cmp_fn); + + pairing_heap_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~pairing_heap_(); + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline const_reference + top() const; + + void + pop(); + + void + erase(point_iterator it); + + template<typename Pred> + size_type + erase_if(Pred pred); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + + protected: + + template<typename It> + void + copy_from_range(It first_it, It last_it); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + + private: + + inline void + push_imp(node_pointer p_nd); + + node_pointer + join_node_children(node_pointer p_nd); + + node_pointer + forward_join(node_pointer p_nd, node_pointer p_next); + + node_pointer + back_join(node_pointer p_nd, node_pointer p_next); + + void + remove_node(node_pointer p_nd); + + }; + +#include <ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds diff --git a/libstdc++/include/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp new file mode 100644 index 0000000..29b8025 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp @@ -0,0 +1,146 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + other.clear(); + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + return; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + while (p_out != NULL) + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); + --base_type::m_size; + + ++other.m_size; + + node_pointer p_next = p_out->m_p_next_sibling; + + p_out->m_p_l_child = p_out->m_p_next_sibling = p_out->m_p_prev_or_parent = NULL; + + other.push_imp(p_out); + + p_out = p_next; + } + + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + node_pointer p_cur = base_type::m_p_root; + + base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = NULL; + + push_imp(p_cur); + + p_cur = p_next; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + if (other.m_p_root == NULL) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + return; + } + + if (base_type::m_p_root == NULL) + base_type::m_p_root = other.m_p_root; + else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, other.m_p_root->m_value)) + { + base_type::make_child_of(base_type::m_p_root, other.m_p_root); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(other.m_p_root, false)); + + base_type::m_p_root = other.m_p_root; + } + else + { + base_type::make_child_of(other.m_p_root, base_type::m_p_root); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(base_type::m_p_root, false)); + } + + base_type::m_size += other.m_size; + + other.m_p_root = NULL; + other.m_size = 0; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/child_iterator.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/child_iterator.hpp new file mode 100644 index 0000000..82c3fbd --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/child_iterator.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file child_iterator.hpp + * Contains a iterator for a patricia tree. + */ + +struct iterator : public const_iterator +{ +public: + typedef std::forward_iterator_tag iterator_category; + typedef typename Allocator::difference_type difference_type; + typedef node_pointer value_type; + typedef node_pointer_pointer pointer; + typedef node_pointer_reference reference; + + inline + iterator(node_pointer_pointer p_p_cur = NULL, + node_pointer_pointer p_p_end = NULL) + : const_iterator(p_p_cur, p_p_end) + { } + + inline bool + operator==(const iterator& other) const + { return const_iterator::m_p_p_cur == other.m_p_p_cur; } + + inline bool + operator!=(const iterator& other) const + { return const_iterator::m_p_p_cur != other.m_p_p_cur; } + + inline iterator& + operator++() + { + const_iterator::operator++(); + return *this; + } + + inline iterator + operator++(int) + { + iterator ret_it(*this); + operator++(); + return ret_it; + } + + node_pointer_pointer + operator->() + { + _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) + return const_iterator::m_p_p_cur; + } + + node_pointer + operator*() + { + _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) + return *const_iterator::m_p_p_cur; + } +}; + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp new file mode 100644 index 0000000..64c16b1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp @@ -0,0 +1,85 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_dtor_entry_dealtor.hpp + * Contains a binary tree container conditional deallocator + */ + +class cond_dealtor +{ +public: + inline + cond_dealtor(leaf_pointer p_nd) : m_p_nd(p_nd), + m_no_action_dtor(false), + m_call_destructor(false) + { } + + inline void + set_no_action_dtor() + { + m_no_action_dtor = true; + } + + inline void + set_call_destructor() + { + m_call_destructor = true; + } + + inline + ~cond_dealtor() + { + if (m_no_action_dtor) + return; + + if (m_call_destructor) + m_p_nd->~leaf(); + + s_leaf_allocator.deallocate(m_p_nd, 1); + } + +protected: + leaf_pointer m_p_nd; + bool m_no_action_dtor; + bool m_call_destructor; +}; + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp new file mode 100644 index 0000000..cd38375 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp @@ -0,0 +1,117 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_child_iterator.hpp + * Contains a const_iterator for a patricia tree. + */ + +struct const_iterator +{ +public: + typedef std::forward_iterator_tag iterator_category; + + typedef typename Allocator::difference_type difference_type; + + typedef node_pointer value_type; + + typedef node_pointer_pointer pointer; + + typedef node_pointer_reference reference; + +public: + inline + const_iterator(node_pointer_pointer p_p_cur = NULL, + node_pointer_pointer p_p_end = NULL) + : m_p_p_cur(p_p_cur), m_p_p_end(p_p_end) + { } + + inline bool + operator==(const const_iterator& other) const + { return m_p_p_cur == other.m_p_p_cur; } + + inline bool + operator!=(const const_iterator& other) const + { return m_p_p_cur != other.m_p_p_cur; } + + inline const_iterator& + operator++() + { + do + ++m_p_p_cur; + while (m_p_p_cur != m_p_p_end&& * m_p_p_cur == NULL); + return *this; + } + + inline const_iterator + operator++(int) + { + const_iterator ret_it(*this); + operator++(); + return ret_it; + } + + const node_pointer_pointer + operator->() const + { + _GLIBCXX_DEBUG_ONLY(assert_referencible();) + return (m_p_p_cur); + } + + const_node_pointer + operator*() const + { + _GLIBCXX_DEBUG_ONLY(assert_referencible();) + return (*m_p_p_cur); + } + +protected: +#ifdef _GLIBCXX_DEBUG + void + assert_referencible() const + { _GLIBCXX_DEBUG_ASSERT(m_p_p_cur != m_p_p_end&& * m_p_p_cur != NULL); } +#endif + +public: + node_pointer_pointer m_p_p_cur; + node_pointer_pointer m_p_p_end; +}; + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..a5a96a5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,220 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::head_allocator +PB_DS_CLASS_C_DEC::s_head_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::internal_node_allocator +PB_DS_CLASS_C_DEC::s_internal_node_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::leaf_allocator +PB_DS_CLASS_C_DEC::s_leaf_allocator; + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() : + m_p_head(s_head_allocator.allocate(1)), + m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const e_access_traits& r_e_access_traits) : + synth_e_access_traits(r_e_access_traits), + m_p_head(s_head_allocator.allocate(1)), + m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif + synth_e_access_traits(other), + node_update(other), + m_p_head(s_head_allocator.allocate(1)), + m_size(0) +{ + initialize(); + m_size = other.m_size; + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (other.m_p_head->m_p_parent == NULL) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return; + } + try + { + m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); + } + catch(...) + { + s_head_allocator.deallocate(m_p_head, 1); + __throw_exception_again; + } + + m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); + m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); + m_p_head->m_p_parent->m_p_parent = m_p_head; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + value_swap(other); + std::swap((e_access_traits& )(*this), (e_access_traits& )other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other);) + std::swap(m_p_head, other.m_p_head); + std::swap(m_size, other.m_size); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ + clear(); + s_head_allocator.deallocate(m_p_head, 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ + new (m_p_head) head(); + m_p_head->m_p_parent = NULL; + m_p_head->m_p_min = m_p_head; + m_p_head->m_p_max = m_p_head; + m_size = 0; +} + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +recursive_copy_node(const_node_pointer p_other_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_other_nd != NULL); + if (p_other_nd->m_type == pat_trie_leaf_node_type) + { + const_leaf_pointer p_other_leaf = static_cast<const_leaf_pointer>(p_other_nd); + + leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); + cond_dealtor cond(p_new_lf); + new (p_new_lf) leaf(p_other_leaf->value()); + apply_update(p_new_lf, (node_update* )this); + cond.set_no_action_dtor(); + return (p_new_lf); + } + + _GLIBCXX_DEBUG_ASSERT(p_other_nd->m_type == pat_trie_internal_node_type); + node_pointer a_p_children[internal_node::arr_size]; + size_type child_i = 0; + const_internal_node_pointer p_other_internal_nd = + static_cast<const_internal_node_pointer>(p_other_nd); + + typename internal_node::const_iterator child_it = + p_other_internal_nd->begin(); + + internal_node_pointer p_ret; + try + { + while (child_it != p_other_internal_nd->end()) + a_p_children[child_i++] = recursive_copy_node(*(child_it++)); + p_ret = s_internal_node_allocator.allocate(1); + } + catch(...) + { + while (child_i-- > 0) + clear_imp(a_p_children[child_i]); + __throw_exception_again; + } + + new (p_ret) internal_node(p_other_internal_nd->get_e_ind(), + pref_begin(a_p_children[0])); + + --child_i; + _GLIBCXX_DEBUG_ASSERT(child_i > 1); + do + p_ret->add_child(a_p_children[child_i], pref_begin(a_p_children[child_i]), + pref_end(a_p_children[child_i]), this); + while (child_i-- > 0); + apply_update(p_ret, (node_update* )this); + return p_ret; +} diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp new file mode 100644 index 0000000..a2253a6 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp @@ -0,0 +1,123 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for pat_trie_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + if (m_p_head->m_p_parent != NULL) + m_p_head->m_p_parent->assert_valid(this); + assert_iterators(); + assert_reverse_iterators(); + if (m_p_head->m_p_parent == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_min == m_p_head); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_max == m_p_head); + _GLIBCXX_DEBUG_ASSERT(empty()); + return; + } + + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_min->m_type == pat_trie_leaf_node_type); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_max->m_type == pat_trie_leaf_node_type); + _GLIBCXX_DEBUG_ASSERT(!empty()); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_iterators() const +{ + size_type calc_size = 0; + for (const_iterator it = begin(); it != end(); ++it) + { + ++calc_size; + map_debug_base::check_key_exists(PB_DS_V2F(*it)); + _GLIBCXX_DEBUG_ASSERT(lower_bound(PB_DS_V2F(*it)) == it); + _GLIBCXX_DEBUG_ASSERT(--upper_bound(PB_DS_V2F(*it)) == it); + } + _GLIBCXX_DEBUG_ASSERT(calc_size == m_size); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_reverse_iterators() const +{ + size_type calc_size = 0; + for (const_reverse_iterator it = rbegin(); it != rend(); ++it) + { + ++calc_size; + const_node_pointer p_nd = + const_cast<PB_DS_CLASS_C_DEC* >(this)->find_imp(PB_DS_V2F(*it)); + _GLIBCXX_DEBUG_ASSERT(p_nd == it.m_p_nd); + } + _GLIBCXX_DEBUG_ASSERT(calc_size == m_size); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +recursive_count_leafs(const_node_pointer p_nd) +{ + if (p_nd == NULL) + return (0); + if (p_nd->m_type == pat_trie_leaf_node_type) + return (1); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + size_type ret = 0; + for (typename internal_node::const_iterator it = + static_cast<const_internal_node_pointer>(p_nd)->begin(); + it != static_cast<const_internal_node_pointer>(p_nd)->end(); + ++it) + ret += recursive_count_leafs(*it); + return ret; +} + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp new file mode 100644 index 0000000..0fba3a4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp @@ -0,0 +1,325 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + node_pointer p_nd = find_imp(r_key); + if (p_nd == NULL || p_nd->m_type == pat_trie_internal_node_type) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return false; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_leaf_node_type); + if (!synth_e_access_traits::equal_keys(PB_DS_V2F(reinterpret_cast<leaf_pointer>(p_nd)->value()), r_key)) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return false; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + erase_leaf(static_cast<leaf_pointer>(p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_fixup(internal_node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) >= 1); + if (std::distance(p_nd->begin(), p_nd->end()) == 1) + { + node_pointer p_parent = p_nd->m_p_parent; + if (p_parent == m_p_head) + m_p_head->m_p_parent =* p_nd->begin(); + else + { + _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == pat_trie_internal_node_type); + node_pointer p_new_child =* p_nd->begin(); + static_cast<internal_node_pointer>(p_parent)->replace_child( + p_new_child, + pref_begin(p_new_child), + pref_end(p_new_child), + this); + } + (*p_nd->begin())->m_p_parent = p_nd->m_p_parent; + p_nd->~internal_node(); + s_internal_node_allocator.deallocate(p_nd, 1); + + if (p_parent == m_p_head) + return; + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == pat_trie_internal_node_type); + p_nd = static_cast<internal_node_pointer>(p_parent); + } + + while (true) + { + _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) > 1); + p_nd->update_prefixes(this); + apply_update(p_nd, (node_update* )this); + _GLIBCXX_DEBUG_ONLY(p_nd->assert_valid(this);) + if (p_nd->m_p_parent->m_type == pat_trie_head_node_type) + return; + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_parent->m_type == + pat_trie_internal_node_type); + + p_nd = static_cast<internal_node_pointer>(p_nd->m_p_parent); + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_leaf(leaf_pointer p_l) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_l->value()))); + p_l->~leaf(); + s_leaf_allocator.deallocate(p_l, 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (empty()) + return; + + clear_imp(m_p_head->m_p_parent); + m_size = 0; + initialize(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_internal_node_type) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + for (typename internal_node::iterator it = + static_cast<internal_node_pointer>(p_nd)->begin(); + it != static_cast<internal_node_pointer>(p_nd)->end(); + ++it) + { + node_pointer p_child =* it; + clear_imp(p_child); + } + s_internal_node_allocator.deallocate(static_cast<internal_node_pointer>(p_nd), 1); + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_leaf_node_type); + static_cast<leaf_pointer>(p_nd)->~leaf(); + s_leaf_allocator.deallocate(static_cast<leaf_pointer>(p_nd), 1); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +erase(const_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + + if (it == end()) + return it; + + const_iterator ret_it = it; + ++ret_it; + _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == pat_trie_leaf_node_type); + erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +#ifdef PB_DS_DATA_TRUE_INDICATOR +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +erase(iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + + if (it == end()) + return it; + iterator ret_it = it; + ++ret_it; + _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == pat_trie_leaf_node_type); + erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} +#endif // #ifdef PB_DS_DATA_TRUE_INDICATOR + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +erase(const_reverse_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + + if (it.m_p_nd == m_p_head) + return it; + const_reverse_iterator ret_it = it; + ++ret_it; + + _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == pat_trie_leaf_node_type); + erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +#ifdef PB_DS_DATA_TRUE_INDICATOR +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +erase(reverse_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + + if (it.m_p_nd == m_p_head) + return it; + reverse_iterator ret_it = it; + ++ret_it; + + _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == pat_trie_leaf_node_type); + erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} +#endif // #ifdef PB_DS_DATA_TRUE_INDICATOR + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + size_type num_ersd = 0; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + iterator it = begin(); + while (it != end()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (pred(*it)) + { + ++num_ersd; + it = erase(it); + } + else + ++it; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_leaf(leaf_pointer p_l) +{ + update_min_max_for_erased_leaf(p_l); + if (p_l->m_p_parent->m_type == pat_trie_head_node_type) + { + _GLIBCXX_DEBUG_ASSERT(size() == 1); + clear(); + return; + } + + _GLIBCXX_DEBUG_ASSERT(size() > 1); + _GLIBCXX_DEBUG_ASSERT(p_l->m_p_parent->m_type == + pat_trie_internal_node_type); + + internal_node_pointer p_parent = + static_cast<internal_node_pointer>(p_l->m_p_parent); + + p_parent->remove_child(p_l); + erase_fixup(p_parent); + actual_erase_leaf(p_l); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +update_min_max_for_erased_leaf(leaf_pointer p_l) +{ + if (m_size == 1) + { + m_p_head->m_p_min = m_p_head; + m_p_head->m_p_max = m_p_head; + return; + } + + if (p_l == static_cast<const_leaf_pointer>(m_p_head->m_p_min)) + { + iterator it(p_l); + ++it; + m_p_head->m_p_min = it.m_p_nd; + return; + } + + if (p_l == static_cast<const_leaf_pointer>(m_p_head->m_p_max)) + { + iterator it(p_l); + --it; + m_p_head->m_p_max = it.m_p_nd; + } +} diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp new file mode 100644 index 0000000..d9b3c4a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp @@ -0,0 +1,275 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + node_pointer p_nd = find_imp(r_key); + + if (p_nd == NULL || p_nd->m_type != pat_trie_leaf_node_type) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return end(); + } + + if (synth_e_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_pointer>(p_nd)->value()), r_key)) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return iterator(p_nd); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return end(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + const_node_pointer p_nd = const_cast<PB_DS_CLASS_C_DEC* >(this)->find_imp(r_key); + + if (p_nd == NULL || p_nd->m_type != pat_trie_leaf_node_type) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return end(); + } + + if (synth_e_access_traits::equal_keys(PB_DS_V2F(static_cast<const_leaf_pointer>(p_nd)->value()), r_key)) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return const_iterator(const_cast<node_pointer>(p_nd)); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return end(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +find_imp(const_key_reference r_key) +{ + if (empty()) + return (NULL); + + typename synth_e_access_traits::const_iterator b_it = + synth_e_access_traits::begin(r_key); + typename synth_e_access_traits::const_iterator e_it = + synth_e_access_traits::end(r_key); + + node_pointer p_nd = m_p_head->m_p_parent; + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + + while (p_nd->m_type != pat_trie_leaf_node_type) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + node_pointer p_next_nd = static_cast<internal_node_pointer>(p_nd)->get_child_node(b_it, e_it, this); + + if (p_next_nd == NULL) + return p_nd; + p_nd = p_next_nd; + } + return p_nd; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +lower_bound_imp(const_key_reference r_key) +{ + if (empty()) + return (m_p_head); + + node_pointer p_nd = m_p_head->m_p_parent; + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + + typename PB_DS_CLASS_C_DEC::const_e_iterator b_it = + synth_e_access_traits::begin(r_key); + + typename PB_DS_CLASS_C_DEC::const_e_iterator e_it = + synth_e_access_traits::end(r_key); + + size_type checked_ind = 0; + while (true) + { + if (p_nd->m_type == pat_trie_leaf_node_type) + { + if (!synth_e_access_traits::cmp_keys(PB_DS_V2F(static_cast<const_leaf_pointer>(p_nd)->value()), r_key)) + return p_nd; + iterator it(p_nd); + ++it; + return it.m_p_nd; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + const size_type new_checked_ind = + static_cast<internal_node_pointer>(p_nd)->get_e_ind(); + + p_nd = + static_cast<internal_node_pointer>(p_nd)->get_lower_bound_child_node( b_it, e_it, checked_ind, this); + checked_ind = new_checked_ind; + } +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +lower_bound(const_key_reference r_key) +{ return point_iterator(lower_bound_imp(r_key)); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +lower_bound(const_key_reference r_key) const +{ + return const_point_iterator(const_cast<PB_DS_CLASS_C_DEC* >(this)->lower_bound_imp(r_key)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +upper_bound(const_key_reference r_key) +{ + point_iterator l_bound_it = lower_bound(r_key); + + _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || + !synth_e_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), + r_key)); + + if (l_bound_it == end() || + synth_e_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) + return l_bound_it; + + return ++l_bound_it; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +upper_bound(const_key_reference r_key) const +{ + const_point_iterator l_bound_it = lower_bound(r_key); + + _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || + !synth_e_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), + r_key)); + + if (l_bound_it == end() || + synth_e_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) + return l_bound_it; + return ++l_bound_it; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_e_iterator +PB_DS_CLASS_C_DEC:: +pref_begin(const_node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return (synth_e_access_traits::begin(PB_DS_V2F(static_cast<const_leaf_pointer>(p_nd)->value()))); + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + return static_cast<const_internal_node_pointer>(p_nd)->pref_b_it(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_e_iterator +PB_DS_CLASS_C_DEC:: +pref_end(const_node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return (synth_e_access_traits::end(PB_DS_V2F(static_cast<const_leaf_pointer>(p_nd)->value()))); + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + return static_cast<const_internal_node_pointer>(p_nd)->pref_e_it(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_leaf_pointer +PB_DS_CLASS_C_DEC:: +leftmost_descendant(const_node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<const_leaf_pointer>(p_nd); + return static_cast<const_internal_node_pointer>(p_nd)->leftmost_descendant(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::leaf_pointer +PB_DS_CLASS_C_DEC:: +leftmost_descendant(node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_nd); + return static_cast<internal_node_pointer>(p_nd)->leftmost_descendant(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_leaf_pointer +PB_DS_CLASS_C_DEC:: +rightmost_descendant(const_node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<const_leaf_pointer>(p_nd); + return static_cast<const_internal_node_pointer>(p_nd)->rightmost_descendant(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::leaf_pointer +PB_DS_CLASS_C_DEC:: +rightmost_descendant(node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_nd); + return static_cast<internal_node_pointer>(p_nd)->rightmost_descendant(); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/head.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/head.hpp new file mode 100644 index 0000000..e8bee52 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/head.hpp @@ -0,0 +1,130 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file head.hpp + * Contains a leaf for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_IHEAD_HPP +#define PB_DS_PAT_TRIE_IHEAD_HPP + +#include <ext/pb_ds/detail/pat_trie_/node_base.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Type_Traits, typename E_Access_Traits, \ + typename Metadata, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + pat_trie_head<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_BASE_C_DEC \ + pat_trie_node_base<Type_Traits, E_Access_Traits, Metadata, Allocator> + + template<typename Type_Traits, + typename E_Access_Traits, + typename Metadata, + typename Allocator> + struct pat_trie_head : public PB_DS_BASE_C_DEC + { + private: + typedef E_Access_Traits e_access_traits; + + typedef + typename Allocator::template rebind< + e_access_traits>::other::const_pointer + const_e_access_traits_pointer; + + typedef + typename Allocator::template rebind< + PB_DS_BASE_C_DEC>::other::pointer + node_pointer; + +#ifdef _GLIBCXX_DEBUG + typedef + typename PB_DS_BASE_C_DEC::subtree_debug_info + subtree_debug_info; +#endif + + public: + pat_trie_head(); + +#ifdef _GLIBCXX_DEBUG + virtual subtree_debug_info + assert_valid_imp(const_e_access_traits_pointer p_traits) const; +#endif + + public: + node_pointer m_p_min; + + node_pointer m_p_max; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + pat_trie_head() : PB_DS_BASE_C_DEC(pat_trie_head_node_type) + { } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::subtree_debug_info + PB_DS_CLASS_C_DEC:: + assert_valid_imp(const_e_access_traits_pointer /*p_traits*/) const + { + _GLIBCXX_DEBUG_ASSERT(false); + return subtree_debug_info(); + } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp new file mode 100644 index 0000000..7e20cd1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp @@ -0,0 +1,64 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (m_size == 0); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return m_size; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_internal_node_allocator.max_size(); } + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp new file mode 100644 index 0000000..4916ae3 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp @@ -0,0 +1,471 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_join_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + split_join_branch_bag bag; + if (!join_prep(other, bag)) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + return; + } + + m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, + other.m_p_head->m_p_parent, 0, bag); + + m_p_head->m_p_parent->m_p_parent = m_p_head; + m_size += other.m_size; + other.initialize(); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); + m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); + _GLIBCXX_DEBUG_ONLY(assert_valid();); +} + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +join_prep(PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (other.m_size == 0) + return false; + + if (m_size == 0) + { + value_swap(other); + return false; + } + + const bool greater = synth_e_access_traits::cmp_keys(PB_DS_V2F(static_cast<const_leaf_pointer>( + m_p_head->m_p_max)->value()),PB_DS_V2F(static_cast<const_leaf_pointer>( + other.m_p_head->m_p_min)->value())); + + const bool lesser = synth_e_access_traits::cmp_keys(PB_DS_V2F(static_cast<const_leaf_pointer>( + other.m_p_head->m_p_max)->value()),PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_min)->value())); + + if (!greater && !lesser) + __throw_join_error(); + + rec_join_prep(m_p_head->m_p_parent, other.m_p_head->m_p_parent, r_bag); + _GLIBCXX_DEBUG_ONLY(map_debug_base::join(other);) + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_node_pointer p_l, const_node_pointer p_r, split_join_branch_bag& r_bag) +{ + if (p_l->m_type == pat_trie_leaf_node_type) + { + if (p_r->m_type == pat_trie_leaf_node_type) + { + rec_join_prep(static_cast<const_leaf_pointer>(p_l), + static_cast<const_leaf_pointer>(p_r), r_bag); + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_r->m_type == pat_trie_internal_node_type); + rec_join_prep(static_cast<const_leaf_pointer>(p_l), + static_cast<const_internal_node_pointer>(p_r), r_bag); + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_l->m_type == pat_trie_internal_node_type); + if (p_r->m_type == pat_trie_leaf_node_type) + { + rec_join_prep(static_cast<const_internal_node_pointer>(p_l), + static_cast<const_leaf_pointer>(p_r), r_bag); + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_r->m_type == pat_trie_internal_node_type); + + rec_join_prep(static_cast<const_internal_node_pointer>(p_l), + static_cast<const_internal_node_pointer>(p_r), r_bag); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_leaf_pointer /*p_l*/, const_leaf_pointer /*p_r*/, + split_join_branch_bag& r_bag) +{ r_bag.add_branch(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_leaf_pointer /*p_l*/, const_internal_node_pointer /*p_r*/, + split_join_branch_bag& r_bag) +{ r_bag.add_branch(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_internal_node_pointer /*p_l*/, const_leaf_pointer /*p_r*/, + split_join_branch_bag& r_bag) +{ r_bag.add_branch(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_internal_node_pointer p_l, const_internal_node_pointer p_r, + split_join_branch_bag& r_bag) +{ + if (p_l->get_e_ind() == p_r->get_e_ind() && + synth_e_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), + p_r->pref_b_it(), p_r->pref_e_it())) + { + for (typename internal_node::const_iterator it = p_r->begin(); + it != p_r->end(); ++ it) + { + const_node_pointer p_l_join_child = p_l->get_join_child(*it, this); + if (p_l_join_child != NULL) + rec_join_prep(p_l_join_child, * it, r_bag); + } + return; + } + + if (p_r->get_e_ind() < p_l->get_e_ind() && + p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) + { + const_node_pointer p_r_join_child = p_r->get_join_child(p_l, this); + if (p_r_join_child != NULL) + rec_join_prep(p_r_join_child, p_l, r_bag); + return; + } + + if (p_r->get_e_ind() < p_l->get_e_ind() && + p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) + { + const_node_pointer p_r_join_child = p_r->get_join_child(p_l, this); + if (p_r_join_child != NULL) + rec_join_prep(p_r_join_child, p_l, r_bag); + return; + } + r_bag.add_branch(); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(node_pointer p_l, node_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + if (p_l == NULL) + { + apply_update(p_r, (node_update* )this); + return (p_r); + } + + if (p_l->m_type == pat_trie_leaf_node_type) + { + if (p_r->m_type == pat_trie_leaf_node_type) + { + node_pointer p_ret = rec_join(static_cast<leaf_pointer>(p_l), + static_cast<leaf_pointer>(p_r), r_bag); + apply_update(p_ret, (node_update* )this); + return p_ret; + } + + _GLIBCXX_DEBUG_ASSERT(p_r->m_type == pat_trie_internal_node_type); + node_pointer p_ret = rec_join(static_cast<leaf_pointer>(p_l), + static_cast<internal_node_pointer>(p_r), + checked_ind, r_bag); + apply_update(p_ret, (node_update* )this); + return p_ret; + } + + _GLIBCXX_DEBUG_ASSERT(p_l->m_type == pat_trie_internal_node_type); + if (p_r->m_type == pat_trie_leaf_node_type) + { + node_pointer p_ret = rec_join(static_cast<internal_node_pointer>(p_l), + static_cast<leaf_pointer>(p_r), + checked_ind, r_bag); + apply_update(p_ret, (node_update* )this); + return p_ret; + } + + _GLIBCXX_DEBUG_ASSERT(p_r->m_type == pat_trie_internal_node_type); + node_pointer p_ret = rec_join(static_cast<internal_node_pointer>(p_l), + static_cast<internal_node_pointer>(p_r), + r_bag); + + apply_update(p_ret, (node_update* )this); + return p_ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(leaf_pointer p_l, leaf_pointer p_r, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + if (p_l == NULL) + return (p_r); + node_pointer p_ret = insert_branch(p_l, p_r, r_bag); + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_ret) == 2); + return p_ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(leaf_pointer p_l, internal_node_pointer p_r, size_type checked_ind, + split_join_branch_bag& r_bag) +{ +#ifdef _GLIBCXX_DEBUG + const size_type lhs_leafs = recursive_count_leafs(p_l); + const size_type rhs_leafs = recursive_count_leafs(p_r); +#endif + + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + node_pointer p_ret = rec_join(p_r, p_l, checked_ind, r_bag); + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_ret) == lhs_leafs + rhs_leafs); + return p_ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(internal_node_pointer p_l, leaf_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(p_l != NULL); + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + +#ifdef _GLIBCXX_DEBUG + const size_type lhs_leafs = recursive_count_leafs(p_l); + const size_type rhs_leafs = recursive_count_leafs(p_r); +#endif + + if (!p_l->should_be_mine(pref_begin(p_r), pref_end(p_r), checked_ind, this)) + { + node_pointer p_ret = insert_branch(p_l, p_r, r_bag); + _GLIBCXX_DEBUG_ONLY(p_ret->assert_valid(this);) + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_ret) == + lhs_leafs + rhs_leafs); + return p_ret; + } + + node_pointer p_pot_child = p_l->add_child(p_r, pref_begin(p_r), + pref_end(p_r), this); + if (p_pot_child != p_r) + { + node_pointer p_new_child = rec_join(p_pot_child, p_r, p_l->get_e_ind(), + r_bag); + + p_l->replace_child(p_new_child, pref_begin(p_new_child), + pref_end(p_new_child), this); + } + + _GLIBCXX_DEBUG_ONLY(p_l->assert_valid(this)); + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_l) == lhs_leafs + rhs_leafs); + return p_l; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(internal_node_pointer p_l, internal_node_pointer p_r, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(p_l != NULL); + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + +#ifdef _GLIBCXX_DEBUG + const size_type lhs_leafs = recursive_count_leafs(p_l); + const size_type rhs_leafs = recursive_count_leafs(p_r); +#endif + + if (p_l->get_e_ind() == p_r->get_e_ind() && + synth_e_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), + p_r->pref_b_it(), p_r->pref_e_it())) + { + for (typename internal_node::iterator it = p_r->begin(); + it != p_r->end(); ++ it) + { + node_pointer p_new_child = rec_join(p_l->get_join_child(*it, this), + * it, 0, r_bag); + p_l->replace_child(p_new_child, pref_begin(p_new_child), + pref_end(p_new_child), this); + } + + p_r->~internal_node(); + s_internal_node_allocator.deallocate(p_r, 1); + _GLIBCXX_DEBUG_ONLY(p_l->assert_valid(this);) + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_l) == lhs_leafs + rhs_leafs); + return p_l; + } + + if (p_l->get_e_ind() < p_r->get_e_ind() && + p_l->should_be_mine(p_r->pref_b_it(), p_r->pref_e_it(), 0, this)) + { + node_pointer p_new_child = rec_join(p_l->get_join_child(p_r, this), + p_r, 0, r_bag); + p_l->replace_child(p_new_child, pref_begin(p_new_child), + pref_end(p_new_child), this); + _GLIBCXX_DEBUG_ONLY(p_l->assert_valid(this);) + return p_l; + } + + if (p_r->get_e_ind() < p_l->get_e_ind() && + p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) + { + node_pointer p_new_child = rec_join(p_r->get_join_child(p_l, this), p_l, + 0, r_bag); + + p_r->replace_child(p_new_child, pref_begin(p_new_child), + pref_end(p_new_child), this); + + _GLIBCXX_DEBUG_ONLY(p_r->assert_valid(this);) + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_r) == lhs_leafs + rhs_leafs); + return p_r; + } + + node_pointer p_ret = insert_branch(p_l, p_r, r_bag); + _GLIBCXX_DEBUG_ONLY(p_ret->assert_valid(this);) + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_ret) == lhs_leafs + rhs_leafs); + return p_ret; +} + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::iterator, bool> +PB_DS_CLASS_C_DEC:: +insert(const_reference r_val) +{ + node_pointer p_lf = find_imp(PB_DS_V2F(r_val)); + if (p_lf != NULL && p_lf->m_type == pat_trie_leaf_node_type && + synth_e_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_pointer>(p_lf)->value()), PB_DS_V2F(r_val))) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(PB_DS_V2F(r_val))); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return std::make_pair(iterator(p_lf), false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(PB_DS_V2F(r_val))); + + leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); + cond_dealtor cond(p_new_lf); + + new (p_new_lf) leaf(r_val); + apply_update(p_new_lf, (node_update* )this); + cond.set_call_destructor(); + split_join_branch_bag bag; + bag.add_branch(); + m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, p_new_lf, 0, bag); + m_p_head->m_p_parent->m_p_parent = m_p_head; + cond.set_no_action_dtor(); + ++m_size; + update_min_max_for_inserted_leaf(p_new_lf); + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return std::make_pair(point_iterator(p_new_lf), true); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +keys_diff_ind(typename e_access_traits::const_iterator b_l, typename e_access_traits::const_iterator e_l, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r) +{ + size_type diff_pos = 0; + while (b_l != e_l) + { + if (b_r == e_r) + return (diff_pos); + if (e_access_traits::e_pos(*b_l) != e_access_traits::e_pos(*b_r)) + return (diff_pos); + ++b_l; + ++b_r; + ++diff_pos; + } + _GLIBCXX_DEBUG_ASSERT(b_r != e_r); + return diff_pos; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::internal_node_pointer +PB_DS_CLASS_C_DEC:: +insert_branch(node_pointer p_l, node_pointer p_r, split_join_branch_bag& r_bag) +{ + typename synth_e_access_traits::const_iterator left_b_it = pref_begin(p_l); + typename synth_e_access_traits::const_iterator left_e_it = pref_end(p_l); + typename synth_e_access_traits::const_iterator right_b_it = pref_begin(p_r); + typename synth_e_access_traits::const_iterator right_e_it = pref_end(p_r); + + const size_type diff_ind = keys_diff_ind(left_b_it, left_e_it, + right_b_it, right_e_it); + + internal_node_pointer p_new_nd = r_bag.get_branch(); + new (p_new_nd) internal_node(diff_ind, left_b_it); + p_new_nd->add_child(p_l, left_b_it, left_e_it, this); + p_new_nd->add_child(p_r, right_b_it, right_e_it, this); + p_l->m_p_parent = p_new_nd; + p_r->m_p_parent = p_new_nd; + _GLIBCXX_DEBUG_ONLY(p_new_nd->assert_valid(this);) + return (p_new_nd); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +update_min_max_for_inserted_leaf(leaf_pointer p_new_lf) +{ + if (m_p_head->m_p_min == m_p_head || + synth_e_access_traits::cmp_keys(PB_DS_V2F(p_new_lf->value()), + PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_min)->value()))) + m_p_head->m_p_min = p_new_lf; + + if (m_p_head->m_p_max == m_p_head || + synth_e_access_traits::cmp_keys(PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_max)->value()), PB_DS_V2F(p_new_lf->value()))) + m_p_head->m_p_max = p_new_lf; +} diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/internal_node.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/internal_node.hpp new file mode 100644 index 0000000..1061988 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/internal_node.hpp @@ -0,0 +1,609 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file internal_node.hpp + * Contains an internal PB_DS_BASE_C_DEC for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_INTERNAL_NODE_HPP +#define PB_DS_PAT_TRIE_INTERNAL_NODE_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Type_Traits, typename E_Access_Traits, \ + typename Metadata, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + pat_trie_internal_node<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_BASE_C_DEC \ + pat_trie_node_base<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_LEAF_C_DEC \ + pat_trie_leaf<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> UNIQUE##static_assert_type + + template<typename Type_Traits, + typename E_Access_Traits, + typename Metadata, + typename Allocator> + struct pat_trie_internal_node : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + typedef Type_Traits type_traits; + typedef typename type_traits::value_type value_type; + typedef typename Allocator::size_type size_type; + + typedef E_Access_Traits e_access_traits; + typedef typename e_access_traits::const_iterator const_e_iterator; + typedef typename Allocator::template rebind<e_access_traits>::other access_rebind; + typedef typename access_rebind::const_pointer const_e_access_traits_pointer; + + typedef typename Allocator::template rebind<base_type>::other base_rebind; + typedef typename base_rebind::pointer node_pointer; + typedef typename base_rebind::const_pointer const_node_pointer; + + typedef PB_DS_LEAF_C_DEC leaf; + typedef typename Allocator::template rebind<leaf>::other leaf_rebind; + typedef typename leaf_rebind::pointer leaf_pointer; + typedef typename leaf_rebind::const_pointer const_leaf_pointer; + + typedef typename Allocator::template rebind<pat_trie_internal_node>::other internal_node_rebind; + typedef typename internal_node_rebind::pointer internal_node_pointer; + typedef typename internal_node_rebind::const_pointer const_internal_node_pointer; + +#ifdef _GLIBCXX_DEBUG + typedef typename base_type::subtree_debug_info subtree_debug_info; + + virtual subtree_debug_info + assert_valid_imp(const_e_access_traits_pointer) const; +#endif + + inline size_type + get_pref_pos(const_e_iterator, const_e_iterator, + const_e_access_traits_pointer) const; + + public: + typedef typename Allocator::template rebind<node_pointer>::other node_pointer_rebind; + typedef typename node_pointer_rebind::pointer node_pointer_pointer; + typedef typename node_pointer_rebind::reference node_pointer_reference; + + enum + { + arr_size = E_Access_Traits::max_size + 1 + }; + PB_DS_STATIC_ASSERT(min_arr_size, arr_size >= 2); + +#include <ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp> +#include <ext/pb_ds/detail/pat_trie_/child_iterator.hpp> + + pat_trie_internal_node(size_type, const const_e_iterator); + + void + update_prefixes(const_e_access_traits_pointer); + + const_iterator + begin() const; + + iterator + begin(); + + const_iterator + end() const; + + iterator + end(); + + inline node_pointer + get_child_node(const_e_iterator, const_e_iterator, + const_e_access_traits_pointer); + + inline const_node_pointer + get_child_node(const_e_iterator, const_e_iterator, + const_e_access_traits_pointer) const; + + inline iterator + get_child_it(const_e_iterator, const_e_iterator, + const_e_access_traits_pointer); + + inline node_pointer + get_lower_bound_child_node(const_e_iterator, const_e_iterator, + size_type, const_e_access_traits_pointer); + + inline node_pointer + add_child(node_pointer, const_e_iterator, const_e_iterator, + const_e_access_traits_pointer); + + inline const_node_pointer + get_join_child(const_node_pointer, const_e_access_traits_pointer) const; + + inline node_pointer + get_join_child(node_pointer, const_e_access_traits_pointer); + + void + remove_child(node_pointer p_nd); + + iterator + remove_child(iterator it); + + void + replace_child(node_pointer, const_e_iterator, const_e_iterator, + const_e_access_traits_pointer); + + inline const_e_iterator + pref_b_it() const; + + inline const_e_iterator + pref_e_it() const; + + inline size_type + get_e_ind() const; + + bool + should_be_mine(const_e_iterator, const_e_iterator, size_type, + const_e_access_traits_pointer) const; + + leaf_pointer + leftmost_descendant(); + + const_leaf_pointer + leftmost_descendant() const; + + leaf_pointer + rightmost_descendant(); + + const_leaf_pointer + rightmost_descendant() const; + +#ifdef _GLIBCXX_DEBUG + size_type + e_ind() const; +#endif + + private: + pat_trie_internal_node(const pat_trie_internal_node&); + + size_type + get_begin_pos() const; + + const size_type m_e_ind; + const_e_iterator m_pref_b_it; + const_e_iterator m_pref_e_it; + node_pointer m_a_p_children[arr_size]; + static leaf_rebind s_leaf_alloc; + static internal_node_rebind s_internal_node_alloc; + }; + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::leaf_rebind + PB_DS_CLASS_C_DEC::s_leaf_alloc; + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::internal_node_rebind + PB_DS_CLASS_C_DEC::s_internal_node_alloc; + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_pref_pos(const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) const + { + if (static_cast<size_t>(std::distance(b_it, e_it)) <= m_e_ind) + return 0; + std::advance(b_it, m_e_ind); + return 1 + p_traits->e_pos(*b_it); + } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + pat_trie_internal_node(size_type len, const const_e_iterator it) : + PB_DS_BASE_C_DEC(pat_trie_internal_node_type), + m_e_ind(len), m_pref_b_it(it), m_pref_e_it(it) + { + std::advance(m_pref_e_it, m_e_ind); + std::fill(m_a_p_children, m_a_p_children + arr_size, + static_cast<node_pointer>(NULL)); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + update_prefixes(const_e_access_traits_pointer p_traits) + { + node_pointer p_first = *begin(); + if (p_first->m_type == pat_trie_leaf_node_type) + { + const_leaf_pointer p = static_cast<const_leaf_pointer>(p_first); + m_pref_b_it = p_traits->begin(e_access_traits::extract_key(p->value())); + } + else + { + _GLIBCXX_DEBUG_ASSERT(p_first->m_type == pat_trie_internal_node_type); + m_pref_b_it = static_cast<internal_node_pointer>(p_first)->pref_b_it(); + } + m_pref_e_it = m_pref_b_it; + std::advance(m_pref_e_it, m_e_ind); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_iterator + PB_DS_CLASS_C_DEC:: + begin() const + { + typedef node_pointer_pointer pointer_type; + pointer_type p = const_cast<pointer_type>(m_a_p_children); + return const_iterator(p + get_begin_pos(), p + arr_size); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + begin() + { + return iterator(m_a_p_children + get_begin_pos(), + m_a_p_children + arr_size); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_iterator + PB_DS_CLASS_C_DEC:: + end() const + { + typedef node_pointer_pointer pointer_type; + pointer_type p = const_cast<pointer_type>(m_a_p_children) + arr_size; + return const_iterator(p, p); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + end() + { return iterator(m_a_p_children + arr_size, m_a_p_children + arr_size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + get_child_node(const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) + { + const size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + return m_a_p_children[i]; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + get_child_it(const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) + { + const size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + _GLIBCXX_DEBUG_ASSERT(m_a_p_children[i] != NULL); + return iterator(m_a_p_children + i, m_a_p_children + i); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::const_node_pointer + PB_DS_CLASS_C_DEC:: + get_child_node(const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) const + { return const_cast<node_pointer>(get_child_node(b_it, e_it, p_traits)); } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + get_lower_bound_child_node(const_e_iterator b_it, const_e_iterator e_it, + size_type checked_ind, + const_e_access_traits_pointer p_traits) + { + if (!should_be_mine(b_it, e_it, checked_ind, p_traits)) + { + if (p_traits->cmp_prefixes(b_it, e_it, m_pref_b_it, m_pref_e_it, true)) + return leftmost_descendant(); + return rightmost_descendant(); + } + + size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + + if (m_a_p_children[i] != NULL) + return m_a_p_children[i]; + + while (++i < arr_size) + if (m_a_p_children[i] != NULL) + { + if (m_a_p_children[i]->m_type == pat_trie_leaf_node_type) + return m_a_p_children[i]; + + _GLIBCXX_DEBUG_ASSERT(m_a_p_children[i]->m_type == pat_trie_internal_node_type); + + return static_cast<internal_node_pointer>(m_a_p_children[i])->leftmost_descendant(); + } + + return rightmost_descendant(); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + add_child(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) + { + const size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + if (m_a_p_children[i] == NULL) + { + m_a_p_children[i] = p_nd; + p_nd->m_p_parent = this; + return p_nd; + } + return m_a_p_children[i]; + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_node_pointer + PB_DS_CLASS_C_DEC:: + get_join_child(const_node_pointer p_nd, const_e_access_traits_pointer p_traits) const + { + node_pointer p = const_cast<node_pointer>(p_nd); + return const_cast<internal_node_pointer>(this)->get_join_child(p, p_traits); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + get_join_child(node_pointer p_nd, const_e_access_traits_pointer p_traits) + { + size_type i; + const_e_iterator b_it; + const_e_iterator e_it; + if (p_nd->m_type == pat_trie_leaf_node_type) + { + typename Type_Traits::const_key_reference r_key = + e_access_traits::extract_key(static_cast<const_leaf_pointer>(p_nd)->value()); + + b_it = p_traits->begin(r_key); + e_it = p_traits->end(r_key); + } + else + { + b_it = static_cast<internal_node_pointer>(p_nd)->pref_b_it(); + e_it = static_cast<internal_node_pointer>(p_nd)->pref_e_it(); + } + i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + return m_a_p_children[i]; + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + remove_child(node_pointer p_nd) + { + size_type i = 0; + for (; i < arr_size; ++i) + if (m_a_p_children[i] == p_nd) + { + m_a_p_children[i] = NULL; + return; + } + _GLIBCXX_DEBUG_ASSERT(i != arr_size); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + remove_child(iterator it) + { + iterator ret = it; + ++ret; + * it.m_p_p_cur = NULL; + return ret; + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + replace_child(node_pointer p_nd, const_e_iterator b_it, + const_e_iterator e_it, + const_e_access_traits_pointer p_traits) + { + const size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + m_a_p_children[i] = p_nd; + p_nd->m_p_parent = this; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::const_e_iterator + PB_DS_CLASS_C_DEC:: + pref_b_it() const + { return m_pref_b_it; } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::const_e_iterator + PB_DS_CLASS_C_DEC:: + pref_e_it() const + { return m_pref_e_it; } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_e_ind() const + { return m_e_ind; } + + PB_DS_CLASS_T_DEC + bool + PB_DS_CLASS_C_DEC:: + should_be_mine(const_e_iterator b_it, const_e_iterator e_it, + size_type checked_ind, + const_e_access_traits_pointer p_traits) const + { + if (m_e_ind == 0) + return true; + + const size_type num_es = std::distance(b_it, e_it); + if (num_es < m_e_ind) + return false; + + const_e_iterator key_b_it = b_it; + std::advance(key_b_it, checked_ind); + const_e_iterator key_e_it = b_it; + std::advance(key_e_it, m_e_ind); + + const_e_iterator value_b_it = m_pref_b_it; + std::advance(value_b_it, checked_ind); + const_e_iterator value_e_it = m_pref_b_it; + std::advance(value_e_it, m_e_ind); + + return p_traits->equal_prefixes(key_b_it, key_e_it, value_b_it, + value_e_it); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::leaf_pointer + PB_DS_CLASS_C_DEC:: + leftmost_descendant() + { + node_pointer p_pot =* begin(); + if (p_pot->m_type == pat_trie_leaf_node_type) + return (static_cast<leaf_pointer>(p_pot)); + _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == pat_trie_internal_node_type); + return static_cast<internal_node_pointer>(p_pot)->leftmost_descendant(); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_leaf_pointer + PB_DS_CLASS_C_DEC:: + leftmost_descendant() const + { + return const_cast<internal_node_pointer>(this)->leftmost_descendant(); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::leaf_pointer + PB_DS_CLASS_C_DEC:: + rightmost_descendant() + { + const size_type num_children = std::distance(begin(), end()); + _GLIBCXX_DEBUG_ASSERT(num_children >= 2); + + iterator it = begin(); + std::advance(it, num_children - 1); + node_pointer p_pot =* it; + if (p_pot->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_pot); + _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == pat_trie_internal_node_type); + return static_cast<internal_node_pointer>(p_pot)->rightmost_descendant(); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_leaf_pointer + PB_DS_CLASS_C_DEC:: + rightmost_descendant() const + { + return const_cast<internal_node_pointer>(this)->rightmost_descendant(); + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + e_ind() const + { return m_e_ind; } +#endif + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_begin_pos() const + { + size_type i; + for (i = 0; i < arr_size && m_a_p_children[i] == NULL; ++i) + ; + return i; + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::subtree_debug_info + PB_DS_CLASS_C_DEC:: + assert_valid_imp(const_e_access_traits_pointer p_traits) const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_type == pat_trie_internal_node_type); + _GLIBCXX_DEBUG_ASSERT(static_cast<size_type>(std::distance(pref_b_it(), pref_e_it())) == m_e_ind); + _GLIBCXX_DEBUG_ASSERT(std::distance(begin(), end()) >= 2); + + for (typename pat_trie_internal_node::const_iterator it = begin(); + it != end(); ++it) + { + const_node_pointer p_nd =* it; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_parent == this); + subtree_debug_info child_ret = p_nd->assert_valid_imp(p_traits); + + _GLIBCXX_DEBUG_ASSERT(static_cast<size_type>(std::distance(child_ret.first, child_ret.second)) >= m_e_ind); + _GLIBCXX_DEBUG_ASSERT(should_be_mine(child_ret.first, child_ret.second, 0, p_traits)); + _GLIBCXX_DEBUG_ASSERT(get_pref_pos(child_ret.first, child_ret.second, p_traits) == static_cast<size_type>(it.m_p_p_cur - m_a_p_children)); + } + return std::make_pair(pref_b_it(), pref_e_it()); + } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC +#undef PB_DS_LEAF_C_DEC +#undef PB_DS_STATIC_ASSERT + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp new file mode 100644 index 0000000..ff117c5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp @@ -0,0 +1,126 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ return iterator(m_p_head->m_p_min); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ return const_iterator(m_p_head->m_p_min); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ return iterator(m_p_head); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ return const_iterator(m_p_head); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +rbegin() const +{ + if (empty()) + return rend(); + return --end(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +rbegin() +{ + if (empty()) + return rend(); + return --end(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +rend() +{ return reverse_iterator(m_p_head); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +rend() const +{ return const_reverse_iterator(m_p_head); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() const +{ return const_node_iterator(m_p_head->m_p_parent, this); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() +{ return node_iterator(m_p_head->m_p_parent, this); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_end() const +{ return const_node_iterator(NULL, this); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_end() +{ return node_iterator(NULL, this); } + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/leaf.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/leaf.hpp new file mode 100644 index 0000000..08f3761 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/leaf.hpp @@ -0,0 +1,177 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file leaf.hpp + * Contains a pat_trie_leaf for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_LEAF_HPP +#define PB_DS_PAT_TRIE_LEAF_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template< \ + class Type_Traits, \ + class E_Access_Traits, \ + class Metadata, \ + class Allocator> + +#define PB_DS_CLASS_C_DEC \ + pat_trie_leaf< \ + Type_Traits, \ + E_Access_Traits, \ + Metadata, \ + Allocator> + +#define PB_DS_BASE_C_DEC \ + pat_trie_node_base< \ + Type_Traits, \ + E_Access_Traits, \ + Metadata, \ + Allocator> + +#define PB_DS_PAT_TRIE_SUBTREE_DEBUG_INFO_C_DEC \ + pat_trie_subtree_debug_info< \ + Type_Traits, \ + E_Access_Traits, \ + Allocator> + + template<typename Type_Traits, + class E_Access_Traits, + class Metadata, + class Allocator> + struct pat_trie_leaf : public PB_DS_BASE_C_DEC + { + private: + typedef typename Type_Traits::value_type value_type; + + typedef typename Type_Traits::const_reference const_reference; + + typedef typename Type_Traits::reference reference; + + typedef + typename Allocator::template rebind< + E_Access_Traits>::other::const_pointer + const_e_access_traits_pointer; + +#ifdef _GLIBCXX_DEBUG + typedef + typename PB_DS_BASE_C_DEC::subtree_debug_info + subtree_debug_info; +#endif + + typedef PB_DS_BASE_C_DEC base_type; + + public: + pat_trie_leaf(const_reference r_val); + + inline reference + value(); + + inline const_reference + value() const; + +#ifdef _GLIBCXX_DEBUG + virtual subtree_debug_info + assert_valid_imp(const_e_access_traits_pointer p_traits) const; + + virtual + ~pat_trie_leaf(); +#endif + + private: + pat_trie_leaf(const PB_DS_CLASS_C_DEC& other); + + value_type m_value; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + pat_trie_leaf(const_reference r_val) : + PB_DS_BASE_C_DEC(pat_trie_leaf_node_type), m_value(r_val) + { } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::reference + PB_DS_CLASS_C_DEC:: + value() + { return m_value; } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::const_reference + PB_DS_CLASS_C_DEC:: + value() const + { return m_value; } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::subtree_debug_info + PB_DS_CLASS_C_DEC:: + assert_valid_imp(const_e_access_traits_pointer p_traits) const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_type == pat_trie_leaf_node_type); + subtree_debug_info ret; + const_reference r_val = value(); + return std::make_pair(p_traits->begin(p_traits->extract_key(r_val)), + p_traits->end(p_traits->extract_key(r_val))); + } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ~pat_trie_leaf() { } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC +#undef PB_DS_PAT_TRIE_SUBTREE_DEBUG_INFO_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_base.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_base.hpp new file mode 100644 index 0000000..753e66b --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_base.hpp @@ -0,0 +1,134 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_base.hpp + * Contains a pat_trie_node_base base for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_NODE_BASE_HPP +#define PB_DS_PAT_TRIE_NODE_BASE_HPP + +#include <ext/pb_ds/detail/pat_trie_/node_metadata_base.hpp> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Type_Traits, typename E_Access_Traits, \ + typename Metadata, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + pat_trie_node_base<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_PAT_TRIE_SUBTREE_DEBUG_INFO_C_DEC \ + pat_trie_subtree_debug_info<Type_Traits, E_Access_Traits, Allocator> + + enum pat_trie_node_type + { + pat_trie_internal_node_type, + pat_trie_leaf_node_type, + pat_trie_head_node_type + }; + + template<typename Type_Traits, + typename E_Access_Traits, + typename Metadata, + typename Allocator> + struct pat_trie_node_base : public pat_trie_node_metadata_base< + Metadata, + Allocator> + { + public: + typedef + typename Allocator::template rebind< + pat_trie_node_base>::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + E_Access_Traits>::other::const_pointer + const_e_access_traits_pointer; + +#ifdef _GLIBCXX_DEBUG + typedef + std::pair< + typename E_Access_Traits::const_iterator, + typename E_Access_Traits::const_iterator> + subtree_debug_info; +#endif + + pat_trie_node_base(pat_trie_node_type type); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid(const_e_access_traits_pointer p_traits) const; + + virtual subtree_debug_info + assert_valid_imp(const_e_access_traits_pointer p_traits) const = 0; +#endif + + node_pointer m_p_parent; + const pat_trie_node_type m_type; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + pat_trie_node_base(pat_trie_node_type type) : m_type(type) + { } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + assert_valid(const_e_access_traits_pointer p_traits) const + { assert_valid_imp(p_traits); } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_PAT_TRIE_SUBTREE_DEBUG_INFO_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_iterators.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_iterators.hpp new file mode 100644 index 0000000..9c8a40c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_iterators.hpp @@ -0,0 +1,344 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_iterators.hpp + * Contains an implementation class for pat_trie_. + */ + +#ifndef PB_DS_PAT_TRIE_NODE_ITERATORS_HPP +#define PB_DS_PAT_TRIE_NODE_ITERATORS_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC \ + pat_trie_const_node_it_< \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + Const_Iterator, \ + Iterator, \ + E_Access_Traits, \ + Allocator> + +#define PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC \ + pat_trie_node_it_< \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + Const_Iterator, \ + Iterator, \ + E_Access_Traits, \ + Allocator> + + // Const node iterator. + template<typename Node, + class Leaf, + class Head, + class Internal_Node, + class Const_Iterator, + class Iterator, + class E_Access_Traits, + class Allocator> + class pat_trie_const_node_it_ + { + protected: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::const_pointer + const_leaf_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::pointer + leaf_pointer; + + typedef + typename Allocator::template rebind< + Internal_Node>::other::pointer + internal_node_pointer; + + typedef + typename Allocator::template rebind< + Internal_Node>::other::const_pointer + const_internal_node_pointer; + + typedef + typename Allocator::template rebind< + E_Access_Traits>::other::const_pointer + const_e_access_traits_pointer; + + private: + inline typename E_Access_Traits::const_iterator + pref_begin() const + { + if (m_p_nd->m_type == pat_trie_leaf_node_type) + return (m_p_traits->begin( + m_p_traits->extract_key( + static_cast<const_leaf_pointer>(m_p_nd)->value()))); + + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_internal_node_type); + + return (static_cast<const_internal_node_pointer>(m_p_nd)->pref_b_it()); + } + + inline typename E_Access_Traits::const_iterator + pref_end() const + { + if (m_p_nd->m_type == pat_trie_leaf_node_type) + return (m_p_traits->end( + m_p_traits->extract_key( + static_cast<const_leaf_pointer>(m_p_nd)->value()))); + + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_internal_node_type); + + return (static_cast<const_internal_node_pointer>(m_p_nd)->pref_e_it()); + } + + public: + + // Size type. + typedef typename Allocator::size_type size_type; + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // __Iterator's value type. + typedef Const_Iterator value_type; + + // __Iterator's reference type. + typedef value_type reference; + + // __Iterator's __const reference type. + typedef value_type const_reference; + + // Element access traits. + typedef E_Access_Traits e_access_traits; + + // A key's element __const iterator. + typedef typename e_access_traits::const_iterator const_e_iterator; + + // Metadata type. + typedef typename Node::metadata_type metadata_type; + + // Const metadata reference type. + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + // Default constructor. + /* + inline + pat_trie_const_node_it_() + */ + inline + pat_trie_const_node_it_(node_pointer p_nd = NULL, + const_e_access_traits_pointer p_traits = NULL) + : m_p_nd(const_cast<node_pointer>(p_nd)), m_p_traits(p_traits) + { } + + // Subtree valid prefix. + inline std::pair<const_e_iterator, const_e_iterator> + valid_prefix() const + { return std::make_pair(pref_begin(), pref_end()); } + + // Const access; returns the __const iterator* associated with + // the current leaf. + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(num_children() == 0); + return Const_Iterator(m_p_nd); + } + + // Metadata access. + inline const_metadata_reference + get_metadata() const + { return m_p_nd->get_metadata(); } + + // Returns the number of children in the corresponding node. + inline size_type + num_children() const + { + if (m_p_nd->m_type == pat_trie_leaf_node_type) + return 0; + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_internal_node_type); + return std::distance(static_cast<internal_node_pointer>(m_p_nd)->begin(), static_cast<internal_node_pointer>(m_p_nd)->end()); + } + + // Returns a __const node __iterator to the corresponding node's + // i-th child. + PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC + get_child(size_type i) const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_internal_node_type); + typename Internal_Node::iterator it = + static_cast<internal_node_pointer>(m_p_nd)->begin(); + + std::advance(it, i); + return PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC(*it, m_p_traits); + } + + // Compares content to a different iterator object. + inline bool + operator==(const PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC& other) const + { return (m_p_nd == other.m_p_nd); } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC& other) const + { return m_p_nd != other.m_p_nd; } + + private: + + friend class PB_DS_CLASS_C_DEC; + + public: + node_pointer m_p_nd; + + const_e_access_traits_pointer m_p_traits; + }; + + // Node iterator. + template<typename Node, + class Leaf, + class Head, + class Internal_Node, + class Const_Iterator, + class Iterator, + class E_Access_Traits, + class Allocator> + class pat_trie_node_it_ : + public PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC + + { + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + typedef Iterator iterator; + + typedef PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC base_type; + + typedef + typename base_type::const_e_access_traits_pointer + const_e_access_traits_pointer; + + typedef typename base_type::internal_node_pointer internal_node_pointer; + + public: + + // Size type. + typedef + typename PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC::size_type + size_type; + + // __Iterator's value type. + typedef Iterator value_type; + + // __Iterator's reference type. + typedef value_type reference; + + // __Iterator's __const reference type. + typedef value_type const_reference; + + // Default constructor. + /* + inline + pat_trie_node_it_() ; + */ + + inline + pat_trie_node_it_(node_pointer p_nd = NULL, const_e_access_traits_pointer p_traits = NULL) : base_type(p_nd, p_traits) + { } + + // Access; returns the iterator* associated with the current leaf. + inline reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(base_type::num_children() == 0); + return Iterator(base_type::m_p_nd); + + } + + // Returns a node __iterator to the corresponding node's i-th child. + PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC + get_child(size_type i) const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == pat_trie_internal_node_type); + + typename Internal_Node::iterator it = + static_cast<internal_node_pointer>(base_type::m_p_nd)->begin(); + + std::advance(it, i); + return PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC(*it, base_type::m_p_traits); + } + + private: + friend class PB_DS_CLASS_C_DEC; + }; + +#undef PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC +#undef PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_metadata_base.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_metadata_base.hpp new file mode 100644 index 0000000..5434ff9 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_metadata_base.hpp @@ -0,0 +1,92 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_metadata_base.hpp + * Contains an internal PB_DS_BASE_C_DEC for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_NODE_METADATA_BASE_HPP +#define PB_DS_PAT_TRIE_NODE_METADATA_BASE_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Metadata, class Allocator> + struct pat_trie_node_metadata_base + { + public: + typedef Metadata metadata_type; + + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + public: + inline const_metadata_reference + get_metadata() const + { + return (m_metadata); + } + + public: + metadata_type m_metadata; + }; + + template<typename Allocator> + struct pat_trie_node_metadata_base< + null_node_metadata, + Allocator> + { + public: + typedef null_node_metadata metadata_type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_PAT_TRIE_NODE_BASE_HPP + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp new file mode 100644 index 0000000..cb0a032 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp @@ -0,0 +1,526 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file pat_trie_.hpp + * Contains an implementation class for a patricia tree. + */ + +/** + * This implementation loosely borrows ideas from: + * 1) "Fast Mergeable Integer Maps", Okasaki, Gill 1998 + * 2) "Ptset: Sets of integers implemented as Patricia trees", + * Jean-Christophe Filliatr, 2000 + **/ + +#include <ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp> +#include <ext/pb_ds/detail/pat_trie_/node_base.hpp> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/tree_policy.hpp> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <iterator> +#include <utility> +#include <algorithm> +#include <functional> +#include <assert.h> +#include <list> +#ifdef _GLIBCXX_DEBUG +#include <ext/pb_ds/detail/map_debug_base.hpp> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Node_And_It_Traits, \ + typename Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME pat_trie_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME pat_trie_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Node_And_It_Traits, Allocator> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, false> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, eq_by_less<Key, \ + std::less<Key> >, typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> \ + UNIQUE##static_assert_type + + /** + * class description = PATRICIA trie implementation."> + **/ + template<typename Key, + typename Mapped, + typename Node_And_It_Traits, + typename Allocator> + class PB_DS_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + public PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif + public Node_And_It_Traits::synth_e_access_traits, + public Node_And_It_Traits::node_update, + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + + typedef typename Node_And_It_Traits::synth_e_access_traits synth_e_access_traits; + typedef typename Allocator::template rebind<synth_e_access_traits>::other::const_pointer const_e_access_traits_pointer; + typedef typename synth_e_access_traits::const_iterator const_e_iterator; + + typedef typename Node_And_It_Traits::node node; + typedef typename Allocator::template rebind<node>::other::const_pointer const_node_pointer; + + typedef typename Allocator::template rebind<node>::other::pointer node_pointer; + + typedef typename Node_And_It_Traits::head head; + typedef typename Allocator::template rebind<head>::other head_allocator; + typedef typename head_allocator::pointer head_pointer; + + typedef typename Node_And_It_Traits::leaf leaf; + typedef typename Allocator::template rebind<leaf>::other leaf_allocator; + typedef typename leaf_allocator::const_pointer const_leaf_pointer; + typedef typename leaf_allocator::pointer leaf_pointer; + + typedef typename Node_And_It_Traits::internal_node internal_node; + typedef typename Allocator::template rebind<internal_node>::other internal_node_allocator; + typedef typename internal_node_allocator::const_pointer const_internal_node_pointer; + typedef typename internal_node_allocator::pointer internal_node_pointer; + +#include <ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp> + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + +#include <ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp> + + typedef typename Node_And_It_Traits::null_node_update_pointer null_node_update_pointer; + + public: + typedef pat_trie_tag container_category; + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + + typedef typename Node_And_It_Traits::const_iterator const_point_iterator; + typedef typename Node_And_It_Traits::iterator point_iterator; + typedef const_point_iterator const_iterator; + typedef point_iterator iterator; + + typedef typename Node_And_It_Traits::const_reverse_iterator const_reverse_iterator; + typedef typename Node_And_It_Traits::reverse_iterator reverse_iterator; + typedef typename Node_And_It_Traits::const_node_iterator const_node_iterator; + typedef typename Node_And_It_Traits::node_iterator node_iterator; + typedef typename Node_And_It_Traits::e_access_traits e_access_traits; + typedef typename Node_And_It_Traits::node_update node_update; + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const e_access_traits&); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + void + swap(PB_DS_CLASS_C_DEC&); + + ~PB_DS_CLASS_NAME(); + + inline bool + empty() const; + + inline size_type + size() const; + + inline size_type + max_size() const; + + e_access_traits& + get_e_access_traits(); + + const e_access_traits& + get_e_access_traits() const; + + node_update& + get_node_update(); + + const node_update& + get_node_update() const; + + inline std::pair<point_iterator, bool> + insert(const_reference); + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + return insert(std::make_pair(r_key, mapped_type())).first->second; +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline point_iterator + find(const_key_reference); + + inline const_point_iterator + find(const_key_reference) const; + + inline point_iterator + lower_bound(const_key_reference); + + inline const_point_iterator + lower_bound(const_key_reference) const; + + inline point_iterator + upper_bound(const_key_reference); + + inline const_point_iterator + upper_bound(const_key_reference) const; + + void + clear(); + + inline bool + erase(const_key_reference); + + inline const_iterator + erase(const_iterator); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + inline iterator + erase(iterator); +#endif + + inline const_reverse_iterator + erase(const_reverse_iterator); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + inline reverse_iterator + erase(reverse_iterator); +#endif + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + join(PB_DS_CLASS_C_DEC&); + + void + split(const_key_reference, PB_DS_CLASS_C_DEC&); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + + inline reverse_iterator + rbegin(); + + inline const_reverse_iterator + rbegin() const; + + inline reverse_iterator + rend(); + + inline const_reverse_iterator + rend() const; + + inline const_node_iterator + node_begin() const; + + inline node_iterator + node_begin(); + + inline const_node_iterator + node_end() const; + + inline node_iterator + node_end(); + +#ifdef PB_DS_PAT_TRIE_TRACE_ + void + trace() const; +#endif + + protected: + + template<typename It> + void + copy_from_range(It, It); + + void + value_swap(PB_DS_CLASS_C_DEC&); + + node_pointer + recursive_copy_node(const_node_pointer); + + private: + + void + initialize(); + + inline void + apply_update(node_pointer, null_node_update_pointer); + + template<typename Node_Update_> + inline void + apply_update(node_pointer, Node_Update_*); + + bool + join_prep(PB_DS_CLASS_C_DEC&, split_join_branch_bag&); + + void + rec_join_prep(const_node_pointer, const_node_pointer, + split_join_branch_bag&); + + void + rec_join_prep(const_leaf_pointer, const_leaf_pointer, + split_join_branch_bag&); + + void + rec_join_prep(const_leaf_pointer, const_internal_node_pointer, + split_join_branch_bag&); + + void + rec_join_prep(const_internal_node_pointer, const_leaf_pointer, + split_join_branch_bag&); + + void + rec_join_prep(const_internal_node_pointer, const_internal_node_pointer, + split_join_branch_bag&); + + node_pointer + rec_join(node_pointer, node_pointer, size_type, split_join_branch_bag&); + + node_pointer + rec_join(leaf_pointer, leaf_pointer, split_join_branch_bag&); + + node_pointer + rec_join(leaf_pointer, internal_node_pointer, size_type, + split_join_branch_bag&); + + node_pointer + rec_join(internal_node_pointer, leaf_pointer, size_type, + split_join_branch_bag&); + + node_pointer + rec_join(internal_node_pointer, internal_node_pointer, + split_join_branch_bag&); + + size_type + keys_diff_ind(typename e_access_traits::const_iterator, typename e_access_traits::const_iterator, typename e_access_traits::const_iterator, typename e_access_traits::const_iterator); + + internal_node_pointer + insert_branch(node_pointer, node_pointer, split_join_branch_bag&); + + void + update_min_max_for_inserted_leaf(leaf_pointer); + + void + erase_leaf(leaf_pointer); + + inline void + actual_erase_leaf(leaf_pointer); + + void + clear_imp(node_pointer); + + void + erase_fixup(internal_node_pointer); + + void + update_min_max_for_erased_leaf(leaf_pointer); + + static inline const_e_iterator + pref_begin(const_node_pointer); + + static inline const_e_iterator + pref_end(const_node_pointer); + + inline node_pointer + find_imp(const_key_reference); + + inline node_pointer + lower_bound_imp(const_key_reference); + + inline node_pointer + upper_bound_imp(const_key_reference); + + inline static const_leaf_pointer + leftmost_descendant(const_node_pointer); + + inline static leaf_pointer + leftmost_descendant(node_pointer); + + inline static const_leaf_pointer + rightmost_descendant(const_node_pointer); + + inline static leaf_pointer + rightmost_descendant(node_pointer); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_iterators() const; + + void + assert_reverse_iterators() const; + + static size_type + recursive_count_leafs(const_node_pointer); +#endif + +#ifdef PB_DS_PAT_TRIE_TRACE_ + static void + trace_node(const_node_pointer, size_type); + + template<typename Metadata_> + static void + trace_node_metadata(const_node_pointer, type_to_type<Metadata_>); + + static void + trace_node_metadata(const_node_pointer, type_to_type<null_node_metadata>); +#endif + + leaf_pointer + split_prep(const_key_reference, PB_DS_CLASS_C_DEC&, + split_join_branch_bag&); + + node_pointer + rec_split(node_pointer, const_e_iterator, const_e_iterator, + PB_DS_CLASS_C_DEC&, split_join_branch_bag&); + + void + split_insert_branch(size_type, const_e_iterator, + typename internal_node::iterator, + size_type, split_join_branch_bag&); + + static head_allocator s_head_allocator; + static internal_node_allocator s_internal_node_allocator; + static leaf_allocator s_leaf_allocator; + + head_pointer m_p_head; + size_type m_size; + }; + +#include <ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S +#undef PB_DS_STATIC_ASSERT + + } // namespace detail +} // namespace pb_ds diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/point_iterators.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/point_iterators.hpp new file mode 100644 index 0000000..1a42dc5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/point_iterators.hpp @@ -0,0 +1,490 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file point_iterators.hpp + * Contains an implementation class for bin_search_tree_. + */ + +#ifndef PB_DS_PAT_TRIE_FIND_ITERATORS_HPP +#define PB_DS_PAT_TRIE_FIND_ITERATORS_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CONST_IT_C_DEC \ + pat_trie_const_it_< \ + Type_Traits, \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_CONST_ODIR_IT_C_DEC \ + pat_trie_const_it_< \ + Type_Traits, \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + !Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_IT_C_DEC \ + pat_trie_it_< \ + Type_Traits, \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_ODIR_IT_C_DEC \ + pat_trie_it_< \ + Type_Traits, \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + !Is_Forward_Iterator, \ + Allocator> + + + // Const iterator. + template<typename Type_Traits, + class Node, + class Leaf, + class Head, + class Internal_Node, + bool Is_Forward_Iterator, + class Allocator> + class pat_trie_const_it_ + { + + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::const_pointer + const_leaf_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::pointer + leaf_pointer; + + typedef + typename Allocator::template rebind< + Head>::other::pointer + head_pointer; + + typedef + typename Allocator::template rebind< + Internal_Node>::other::pointer + internal_node_pointer; + + public: + + typedef std::bidirectional_iterator_tag iterator_category; + + typedef typename Allocator::difference_type difference_type; + + typedef typename Type_Traits::value_type value_type; + + typedef typename Type_Traits::pointer pointer; + + typedef typename Type_Traits::const_pointer const_pointer; + + typedef typename Type_Traits::reference reference; + + typedef typename Type_Traits::const_reference const_reference; + + public: + + inline + pat_trie_const_it_(node_pointer p_nd = NULL) : m_p_nd(p_nd) + { } + + inline + pat_trie_const_it_(const PB_DS_CONST_ODIR_IT_C_DEC& other) + : m_p_nd(other.m_p_nd) + { } + + inline + PB_DS_CONST_IT_C_DEC& + operator=(const PB_DS_CONST_IT_C_DEC& other) + { + m_p_nd = other.m_p_nd; + return *this; + } + + inline + PB_DS_CONST_IT_C_DEC& + operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other) + { + m_p_nd = other.m_p_nd; + return *this; + } + + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type); + return &static_cast<leaf_pointer>(m_p_nd)->value(); + } + + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type); + return static_cast<leaf_pointer>(m_p_nd)->value(); + } + + inline bool + operator==(const PB_DS_CONST_IT_C_DEC& other) const + { return (m_p_nd == other.m_p_nd); } + + inline bool + operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const + { return (m_p_nd == other.m_p_nd); } + + inline bool + operator!=(const PB_DS_CONST_IT_C_DEC& other) const + { return (m_p_nd != other.m_p_nd); } + + inline bool + operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const + { return (m_p_nd != other.m_p_nd); } + + inline PB_DS_CONST_IT_C_DEC& + operator++() + { + inc(integral_constant<int,Is_Forward_Iterator>()); + return *this; + } + + inline PB_DS_CONST_IT_C_DEC + operator++(int) + { + PB_DS_CONST_IT_C_DEC ret_it(m_p_nd); + operator++(); + return ret_it; + } + + inline PB_DS_CONST_IT_C_DEC& + operator--() + { + dec(integral_constant<int,Is_Forward_Iterator>()); + return *this; + } + + inline PB_DS_CONST_IT_C_DEC + operator--(int) + { + PB_DS_CONST_IT_C_DEC ret_it(m_p_nd); + operator--(); + return ret_it; + } + + protected: + inline void + inc(false_type) + { dec(true_type()); } + + void + inc(true_type) + { + if (m_p_nd->m_type == pat_trie_head_node_type) + { + m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_min; + return; + } + + node_pointer p_y = m_p_nd->m_p_parent; + while (p_y->m_type != pat_trie_head_node_type && + get_larger_sibling(m_p_nd) == NULL) + { + m_p_nd = p_y; + p_y = p_y->m_p_parent; + } + + if (p_y->m_type == pat_trie_head_node_type) + { + m_p_nd = p_y; + return; + } + m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd)); + } + + inline void + dec(false_type) + { inc(true_type()); } + + void + dec(true_type) + { + if (m_p_nd->m_type == pat_trie_head_node_type) + { + m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_max; + return; + } + + node_pointer p_y = m_p_nd->m_p_parent; + while (p_y->m_type != pat_trie_head_node_type && + get_smaller_sibling(m_p_nd) == NULL) + { + m_p_nd = p_y; + p_y = p_y->m_p_parent; + } + + if (p_y->m_type == pat_trie_head_node_type) + { + m_p_nd = p_y; + return; + } + m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd)); + } + + inline static node_pointer + get_larger_sibling(node_pointer p_nd) + { + internal_node_pointer p_parent = + static_cast<internal_node_pointer>(p_nd->m_p_parent); + + typename Internal_Node::iterator it = p_parent->begin(); + while (*it != p_nd) + ++it; + + typename Internal_Node::iterator next_it = it; + ++next_it; + return ((next_it == p_parent->end())? NULL :* next_it); + } + + inline static node_pointer + get_smaller_sibling(node_pointer p_nd) + { + internal_node_pointer p_parent = + static_cast<internal_node_pointer>(p_nd->m_p_parent); + + typename Internal_Node::iterator it = p_parent->begin(); + + if (*it == p_nd) + return (NULL); + typename Internal_Node::iterator prev_it; + do + { + prev_it = it; + ++it; + if (*it == p_nd) + return (*prev_it); + } + while (true); + + _GLIBCXX_DEBUG_ASSERT(false); + return (NULL); + } + + inline static leaf_pointer + leftmost_descendant(node_pointer p_nd) + { + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_nd); + return static_cast<internal_node_pointer>(p_nd)->leftmost_descendant(); + } + + inline static leaf_pointer + rightmost_descendant(node_pointer p_nd) + { + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_nd); + return static_cast<internal_node_pointer>(p_nd)->rightmost_descendant(); + } + + public: + node_pointer m_p_nd; + }; + + // Iterator. + template<typename Type_Traits, + class Node, + class Leaf, + class Head, + class Internal_Node, + bool Is_Forward_Iterator, + class Allocator> + class pat_trie_it_ : + public PB_DS_CONST_IT_C_DEC + + { + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::const_pointer + const_leaf_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::pointer + leaf_pointer; + + typedef + typename Allocator::template rebind< + Head>::other::pointer + head_pointer; + + typedef + typename Allocator::template rebind< + Internal_Node>::other::pointer + internal_node_pointer; + + public: + typedef typename Type_Traits::value_type value_type; + + typedef typename Type_Traits::const_pointer const_pointer; + + typedef typename Type_Traits::pointer pointer; + + typedef typename Type_Traits::const_reference const_reference; + + typedef typename Type_Traits::reference reference; + + inline + pat_trie_it_(node_pointer p_nd = NULL) : PB_DS_CONST_IT_C_DEC((node_pointer)p_nd) + { } + + inline + pat_trie_it_(const PB_DS_ODIR_IT_C_DEC& other) : PB_DS_CONST_IT_C_DEC(other.m_p_nd) + { } + + inline + PB_DS_IT_C_DEC& + operator=(const PB_DS_IT_C_DEC& other) + { + base_it_type::m_p_nd = other.m_p_nd; + return *this; + } + + inline + PB_DS_IT_C_DEC& + operator=(const PB_DS_ODIR_IT_C_DEC& other) + { + base_it_type::m_p_nd = other.m_p_nd; + return *this; + } + + inline pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type); + + return &static_cast<leaf_pointer>(base_it_type::m_p_nd)->value(); + } + + inline reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type); + return static_cast<leaf_pointer>(base_it_type::m_p_nd)->value(); + } + + inline PB_DS_IT_C_DEC& + operator++() + { + PB_DS_CONST_IT_C_DEC:: + operator++(); + return *this; + } + + inline PB_DS_IT_C_DEC + operator++(int) + { + PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd); + operator++(); + return ret_it; + } + + inline PB_DS_IT_C_DEC& + operator--() + { + PB_DS_CONST_IT_C_DEC::operator--(); + return *this; + } + + inline PB_DS_IT_C_DEC + operator--(int) + { + PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd); + operator--(); + return ret_it; + } + + protected: + typedef PB_DS_CONST_IT_C_DEC base_it_type; + + friend class PB_DS_CLASS_C_DEC; + }; + +#undef PB_DS_CONST_IT_C_DEC +#undef PB_DS_CONST_ODIR_IT_C_DEC +#undef PB_DS_IT_C_DEC +#undef PB_DS_ODIR_IT_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp new file mode 100644 index 0000000..7c6eb0f --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp @@ -0,0 +1,69 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::e_access_traits& +PB_DS_CLASS_C_DEC:: +get_e_access_traits() +{ return *this; } + +PB_DS_CLASS_T_DEC +const typename PB_DS_CLASS_C_DEC::e_access_traits& +PB_DS_CLASS_C_DEC:: +get_e_access_traits() const +{ return *this; } + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_update& +PB_DS_CLASS_C_DEC:: +get_node_update() +{ return *this; } + +PB_DS_CLASS_T_DEC +const typename PB_DS_CLASS_C_DEC::node_update& +PB_DS_CLASS_C_DEC:: +get_node_update() const +{ return *this; } diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hpp new file mode 100644 index 0000000..63553ec --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hpp @@ -0,0 +1,109 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file r_erase_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_node(node_pointer p_z) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value))); + p_z->~node(); + s_node_allocator.deallocate(p_z, 1); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_min_max_for_erased_node(node_pointer p_z) +{ + if (m_size == 1) + { + m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; + return; + } + + if (m_p_head->m_p_left == p_z) + { + iterator it(p_z); + ++it; + m_p_head->m_p_left = it.m_p_nd; + } + else if (m_p_head->m_p_right == p_z) + { + iterator it(p_z); + --it; + m_p_head->m_p_right = it.m_p_nd; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) + clear_imp(m_p_head->m_p_parent); + m_size = 0; + initialize(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + if (p_nd == NULL) + return; + clear_imp(p_nd->m_p_left); + clear_imp(p_nd->m_p_right); + p_nd->~Node(); + s_node_allocator.deallocate(p_nd, 1); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hpp new file mode 100644 index 0000000..84e6fdd --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hpp @@ -0,0 +1,156 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rotate_fn_imps.hpp + * Contains imps for rotating nodes. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_left(node_pointer p_x) +{ + node_pointer p_y = p_x->m_p_right; + p_x->m_p_right = p_y->m_p_left; + + if (p_y->m_p_left != NULL) + p_y->m_p_left->m_p_parent = p_x; + + p_y->m_p_parent = p_x->m_p_parent; + if (p_x == m_p_head->m_p_parent) + m_p_head->m_p_parent = p_y; + else if (p_x == p_x->m_p_parent->m_p_left) + p_x->m_p_parent->m_p_left = p_y; + else + p_x->m_p_parent->m_p_right = p_y; + + p_y->m_p_left = p_x; + p_x->m_p_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) + + apply_update(p_x, (Node_Update* )this); + apply_update(p_x->m_p_parent, (Node_Update* )this); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_right(node_pointer p_x) +{ + node_pointer p_y = p_x->m_p_left; + p_x->m_p_left = p_y->m_p_right; + + if (p_y->m_p_right != NULL) + p_y->m_p_right->m_p_parent = p_x; + + p_y->m_p_parent = p_x->m_p_parent; + if (p_x == m_p_head->m_p_parent) + m_p_head->m_p_parent = p_y; + else if (p_x == p_x->m_p_parent->m_p_right) + p_x->m_p_parent->m_p_right = p_y; + else + p_x->m_p_parent->m_p_left = p_y; + + p_y->m_p_right = p_x; + p_x->m_p_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) + + apply_update(p_x, (Node_Update* )this); + apply_update(p_x->m_p_parent, (Node_Update* )this); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_parent(node_pointer p_nd) +{ + node_pointer p_parent = p_nd->m_p_parent; + if (p_nd == p_parent->m_p_left) + rotate_right(p_parent); + else + rotate_left(p_parent); + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || p_nd->m_p_right == p_parent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer /*p_nd*/, pb_ds::null_node_update* /*p_update*/) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer p_nd, Node_Update_* p_update) +{ + p_update->operator()(& PB_DS_V2F(p_nd->m_value),(p_nd->m_p_left == NULL) ? + NULL : + & PB_DS_V2F(p_nd->m_p_left->m_value),(p_nd->m_p_right == NULL) ? + NULL : + & PB_DS_V2F(p_nd->m_p_right->m_value)); +} + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +update_to_top(node_pointer p_nd, Node_Update_* p_update) +{ + while (p_nd != m_p_head) + { + apply_update(p_nd, p_update); + p_nd = p_nd->m_p_parent; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_to_top(node_pointer /*p_nd*/, pb_ds::null_node_update* /*p_update*/) +{ } + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp new file mode 100644 index 0000000..ed5d890 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp @@ -0,0 +1,260 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + split_join_branch_bag bag; + leaf_pointer p_split_lf = split_prep(r_key, other, bag); + if (p_split_lf == NULL) + { + _GLIBCXX_DEBUG_ASSERT(bag.empty()); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + _GLIBCXX_DEBUG_ASSERT(!bag.empty()); + other.clear(); + m_p_head->m_p_parent = rec_split(m_p_head->m_p_parent, + pref_begin(p_split_lf), + pref_end(p_split_lf), + other, + bag); + + m_p_head->m_p_parent->m_p_parent = m_p_head; + + other.m_p_head->m_p_max = m_p_head->m_p_max; + m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); + other.m_p_head->m_p_min = + other.leftmost_descendant(other.m_p_head->m_p_parent); + + other.m_size = std::distance(other.PB_DS_CLASS_C_DEC::begin(), + other.PB_DS_CLASS_C_DEC::end()); + m_size -= other.m_size; + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::leaf_pointer +PB_DS_CLASS_C_DEC:: +split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(r_bag.empty()); + if (m_size == 0) + { + other.clear(); + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + return (NULL); + } + + if (synth_e_access_traits::cmp_keys(r_key, + PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_min)->value()))) + { + other.clear(); + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + return (NULL); + } + + if (!synth_e_access_traits::cmp_keys(r_key, + PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_max)->value()))) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + return (NULL); + } + + iterator it = lower_bound(r_key); + + if (!synth_e_access_traits::equal_keys(PB_DS_V2F(*it), r_key)) + --it; + + node_pointer p_nd = it.m_p_nd; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_leaf_node_type); + leaf_pointer p_ret_l = static_cast<leaf_pointer>(p_nd); + while (p_nd->m_type != pat_trie_head_node_type) + { + r_bag.add_branch(); + p_nd = p_nd->m_p_parent; + } + _GLIBCXX_DEBUG_ONLY(map_debug_base::split(r_key,(synth_e_access_traits& )(*this), other);) + + return (p_ret_l); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_split(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + { + _GLIBCXX_DEBUG_ASSERT(other.m_p_head->m_p_parent == NULL); + return (p_nd); + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + internal_node_pointer p_internal_nd = static_cast<internal_node_pointer>(p_nd); + + node_pointer p_child_ret = rec_split(p_internal_nd->get_child_node(b_it, e_it, this), b_it, e_it, other, r_bag); + + _GLIBCXX_DEBUG_ONLY(p_child_ret->assert_valid(this);) + p_internal_nd->replace_child(p_child_ret, b_it, e_it, this); + apply_update(p_internal_nd, (node_update* )this); + + typename internal_node::iterator child_it = + p_internal_nd->get_child_it(b_it, e_it, this); + + const size_type lhs_num_children = + std::distance(p_internal_nd->begin(), child_it) + 1; + + _GLIBCXX_DEBUG_ASSERT(lhs_num_children > 0); + + size_type rhs_num_children = + std::distance(p_internal_nd->begin(), p_internal_nd->end()) - + lhs_num_children; + + if (rhs_num_children == 0) + { + apply_update(p_internal_nd, (node_update* )this); + return (p_internal_nd); + } + + ++child_it; + other.split_insert_branch(p_internal_nd->get_e_ind(), + b_it, child_it, rhs_num_children, r_bag); + + child_it = p_internal_nd->get_child_it(b_it, e_it, this); + ++child_it; + while (rhs_num_children != 0) + { + child_it = p_internal_nd->remove_child(child_it); + --rhs_num_children; + } + + apply_update(p_internal_nd, (node_update* )this); + _GLIBCXX_DEBUG_ASSERT(std::distance(p_internal_nd->begin(), + p_internal_nd->end()) >= 1); + + if (std::distance(p_internal_nd->begin(), p_internal_nd->end()) > 1) + { + p_internal_nd->update_prefixes(this); + _GLIBCXX_DEBUG_ONLY(p_internal_nd->assert_valid(this);) + apply_update(p_internal_nd, (node_update* )this); + return (p_internal_nd); + } + + node_pointer p_ret =* p_internal_nd->begin(); + p_internal_nd->~internal_node(); + s_internal_node_allocator.deallocate(p_internal_nd, 1); + apply_update(p_ret, (node_update* )this); + return (p_ret); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split_insert_branch(size_type e_ind, const_e_iterator b_it, typename internal_node::iterator child_b_it, size_type num_children, split_join_branch_bag& r_bag) +{ +#ifdef _GLIBCXX_DEBUG + if (m_p_head->m_p_parent != NULL) + m_p_head->m_p_parent->assert_valid(this); +#endif + + const size_type total_num_children =((m_p_head->m_p_parent == NULL)? 0 : 1) + num_children; + + if (total_num_children == 0) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == NULL); + return; + } + + if (total_num_children == 1) + { + if (m_p_head->m_p_parent != NULL) + { + _GLIBCXX_DEBUG_ONLY(m_p_head->m_p_parent->assert_valid(this);) + return; + } + + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == NULL); + m_p_head->m_p_parent =* child_b_it; + m_p_head->m_p_parent->m_p_parent = m_p_head; + apply_update(m_p_head->m_p_parent, (node_update* )this); + _GLIBCXX_DEBUG_ONLY(m_p_head->m_p_parent->assert_valid(this);) + return; + } + + _GLIBCXX_DEBUG_ASSERT(total_num_children > 1); + internal_node_pointer p_new_root = r_bag.get_branch(); + new (p_new_root) internal_node(e_ind, b_it); + size_type num_inserted = 0; + while (num_inserted++ < num_children) + { + _GLIBCXX_DEBUG_ONLY((*child_b_it)->assert_valid(this);) + p_new_root->add_child(*child_b_it, pref_begin(*child_b_it), + pref_end(*child_b_it), this); + ++child_b_it; + } + + if (m_p_head->m_p_parent != NULL) + p_new_root->add_child(m_p_head->m_p_parent, + pref_begin(m_p_head->m_p_parent), + pref_end(m_p_head->m_p_parent), this); + + m_p_head->m_p_parent = p_new_root; + p_new_root->m_p_parent = m_p_head; + apply_update(m_p_head->m_p_parent, (node_update* )this); + _GLIBCXX_DEBUG_ONLY(m_p_head->m_p_parent->assert_valid(this);) +} diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp new file mode 100644 index 0000000..bf04cb4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_branch_bag.hpp + * Contains an implementation class for pat_trie_. + */ + +class split_join_branch_bag +{ +private: + typedef + std::list< + internal_node_pointer, + typename Allocator::template rebind< + internal_node_pointer>::other> + bag_t; + +public: + + void + add_branch() + { + internal_node_pointer p_nd = s_internal_node_allocator.allocate(1); + try + { + m_bag.push_back(p_nd); + } + catch(...) + { + s_internal_node_allocator.deallocate(p_nd, 1); + __throw_exception_again; + } + } + + internal_node_pointer + get_branch() + { + _GLIBCXX_DEBUG_ASSERT(!m_bag.empty()); + internal_node_pointer p_nd =* m_bag.begin(); + m_bag.pop_front(); + return p_nd; + } + + ~split_join_branch_bag() + { + while (!m_bag.empty()) + { + internal_node_pointer p_nd =* m_bag.begin(); + s_internal_node_allocator.deallocate(p_nd, 1); + m_bag.pop_front(); + } + } + + inline bool + empty() const + { return m_bag.empty(); } + +private: + bag_t m_bag; +}; diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp new file mode 100644 index 0000000..79cd72c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp @@ -0,0 +1,235 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file synth_e_access_traits.hpp + * Contains an implementation class for a patricia tree. + */ + +#ifndef PB_DS_SYNTH_E_ACCESS_TRAITS_HPP +#define PB_DS_SYNTH_E_ACCESS_TRAITS_HPP + +#include <ext/pb_ds/detail/type_utils.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC \ + template<typename Type_Traits, bool Set, class E_Access_Traits> + +#define PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC \ + synth_e_access_traits< \ + Type_Traits, \ + Set, \ + E_Access_Traits> + + template<typename Type_Traits, bool Set, class E_Access_Traits> + struct synth_e_access_traits : public E_Access_Traits + { + + private: + typedef E_Access_Traits base_type; + + typedef Type_Traits type_traits; + + typedef typename type_traits::const_key_reference const_key_reference; + + typedef typename type_traits::const_reference const_reference; + + public: + synth_e_access_traits(); + + synth_e_access_traits(const E_Access_Traits& r_traits); + + inline bool + equal_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after = true) const; + + bool + equal_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const; + + bool + cmp_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after = false) const; + + bool + cmp_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const; + + inline static const_key_reference + extract_key(const_reference r_val); + +#ifdef _GLIBCXX_DEBUG + bool + operator()(const_key_reference r_lhs, const_key_reference r_rhs); +#endif + + private: + inline static const_key_reference + extract_key(const_reference r_val, true_type); + + inline static const_key_reference + extract_key(const_reference r_val, false_type); + + private: + static integral_constant<int,Set> s_set_ind; + }; + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + integral_constant<int,Set> + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::s_set_ind; + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + synth_e_access_traits() + { } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + synth_e_access_traits(const E_Access_Traits& r_traits) : + E_Access_Traits(r_traits) + { } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + inline bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + equal_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after /*= false */) const + { + while (b_l != e_l) + { + if (b_r == e_r) + return (false); + if (base_type::e_pos(*b_l) != base_type::e_pos(*b_r)) + return (false); + ++b_l; + ++b_r; + } + return (!compare_after || b_r == e_r); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + equal_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const + { + return (equal_prefixes(base_type::begin(r_lhs_key), + base_type::end(r_lhs_key), + base_type::begin(r_rhs_key), + base_type::end(r_rhs_key), + true)); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + cmp_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after /* = false*/) const + { + while (b_l != e_l) + { + if (b_r == e_r) + return (false); + const typename base_type::size_type l_pos = + base_type::e_pos(*b_l); + const typename base_type::size_type r_pos = + base_type::e_pos(*b_r); + if (l_pos != r_pos) + return (l_pos < r_pos); + ++b_l; + ++b_r; + } + + if (!compare_after) + return (false); + return (b_r != e_r); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + cmp_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const + { + return (cmp_prefixes(base_type::begin(r_lhs_key), + base_type::end(r_lhs_key), + base_type::begin(r_rhs_key), + base_type::end(r_rhs_key), + true)); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::const_key_reference + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + extract_key(const_reference r_val) + { + return (extract_key(r_val, s_set_ind)); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::const_key_reference + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + extract_key(const_reference r_val, true_type) + { + return (r_val); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::const_key_reference + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + extract_key(const_reference r_val, false_type) + { + return (r_val.first); + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + operator()(const_key_reference r_lhs, const_key_reference r_rhs) + { + return (cmp_keys(r_lhs, r_rhs)); + } +#endif + +#undef PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC +#undef PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp new file mode 100644 index 0000000..cab28ca --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp @@ -0,0 +1,119 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation class for pat_trie_. + */ + +#ifdef PB_DS_PAT_TRIE_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << std::endl; + if (m_p_head->m_p_parent == NULL) + return; + trace_node(m_p_head->m_p_parent, 0); + std::cerr << std::endl; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_node(const_node_pointer p_nd, size_type level) +{ + for (size_type i = 0; i < level; ++i) + std::cerr << ' '; + std::cerr << p_nd << " "; + std::cerr << ((p_nd->m_type == pat_trie_leaf_node_type) ? "l " : "i "); + + trace_node_metadata(p_nd, type_to_type<typename node::metadata_type>()); + typename e_access_traits::const_iterator el_it = pref_begin(p_nd); + while (el_it != pref_end(p_nd)) + { + std::cerr <<* el_it; + ++el_it; + } + + if (p_nd->m_type == pat_trie_leaf_node_type) + { + std::cerr << std::endl; + return; + } + + const_internal_node_pointer p_internal = + static_cast<const_internal_node_pointer>(p_nd); + + std::cerr << " " << + static_cast<unsigned long>(p_internal->get_e_ind()) << std::endl; + + const size_type num_children = std::distance(p_internal->begin(), + p_internal->end()); + + for (size_type child_i = 0; child_i < num_children; ++child_i) + { + typename internal_node::const_iterator child_it = + p_internal->begin(); + std::advance(child_it, num_children - child_i - 1); + trace_node(*child_it, level + 1); + } +} + +PB_DS_CLASS_T_DEC +template<typename Metadata_> +void +PB_DS_CLASS_C_DEC:: +trace_node_metadata(const_node_pointer p_nd, type_to_type<Metadata_>) +{ + std::cerr << "(" << static_cast<unsigned long>(p_nd->get_metadata()) << ") "; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_node_metadata(const_node_pointer, type_to_type<null_node_metadata>) +{ } + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/traits.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/traits.hpp new file mode 100644 index 0000000..b103809 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/traits.hpp @@ -0,0 +1,356 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation class for pat_trie_. + */ + +#ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/pat_trie_/node_base.hpp> +#include <ext/pb_ds/detail/pat_trie_/head.hpp> +#include <ext/pb_ds/detail/pat_trie_/leaf.hpp> +#include <ext/pb_ds/detail/pat_trie_/internal_node.hpp> +#include <ext/pb_ds/detail/pat_trie_/point_iterators.hpp> +#include <ext/pb_ds/detail/pat_trie_/node_iterators.hpp> +#include <ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Key, + typename Mapped, + class E_Access_Traits, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct trie_traits< + Key, + Mapped, + E_Access_Traits, + Node_Update, + pat_trie_tag, + Allocator> + { + private: + typedef types_traits< Key, Mapped, Allocator, false> type_traits; + + public: + typedef + typename trie_node_metadata_selector< + Key, + Mapped, + E_Access_Traits, + Node_Update, + Allocator>::type + metadata_type; + + typedef E_Access_Traits e_access_traits; + + typedef + synth_e_access_traits< + type_traits, + false, + e_access_traits> + synth_e_access_traits; + + typedef + pat_trie_node_base< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + node; + + typedef + pat_trie_leaf< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + leaf; + + typedef + pat_trie_head< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + head; + + typedef + pat_trie_internal_node< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + internal_node; + + typedef + pat_trie_const_it_< + type_traits, + node, + leaf, + head, + internal_node, + true, + Allocator> + const_iterator; + + typedef + pat_trie_it_< + type_traits, + node, + leaf, + head, + internal_node, + true, + Allocator> + iterator; + + typedef + pat_trie_const_it_< + type_traits, + node, + leaf, + head, + internal_node, + false, + Allocator> + const_reverse_iterator; + + typedef + pat_trie_it_< + type_traits, + node, + leaf, + head, + internal_node, + false, + Allocator> + reverse_iterator; + + typedef + pat_trie_const_node_it_< + node, + leaf, + head, + internal_node, + const_iterator, + iterator, + synth_e_access_traits, + Allocator> + const_node_iterator; + + typedef + pat_trie_node_it_< + node, + leaf, + head, + internal_node, + const_iterator, + iterator, + synth_e_access_traits, + Allocator> + node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + E_Access_Traits, + Allocator> + node_update; + + typedef + pb_ds::null_trie_node_update< + const_node_iterator, + node_iterator, + E_Access_Traits, + Allocator>* + null_node_update_pointer; + }; + + template<typename Key, + class E_Access_Traits, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct trie_traits< + Key, + null_mapped_type, + E_Access_Traits, + Node_Update, + pat_trie_tag, + Allocator> + { + private: + typedef + types_traits< + Key, + null_mapped_type, + Allocator, + false> + type_traits; + + public: + typedef + typename trie_node_metadata_selector< + Key, + null_mapped_type, + E_Access_Traits, + Node_Update, + Allocator>::type + metadata_type; + + typedef E_Access_Traits e_access_traits; + + typedef + synth_e_access_traits< + type_traits, + true, + e_access_traits> + synth_e_access_traits; + + typedef + pat_trie_node_base< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + node; + + typedef + pat_trie_leaf< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + leaf; + + typedef + pat_trie_head< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + head; + + typedef + pat_trie_internal_node< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + internal_node; + + typedef + pat_trie_const_it_< + type_traits, + node, + leaf, + head, + internal_node, + true, + Allocator> + const_iterator; + + typedef const_iterator iterator; + + typedef + pat_trie_const_it_< + type_traits, + node, + leaf, + head, + internal_node, + false, + Allocator> + const_reverse_iterator; + + typedef const_reverse_iterator reverse_iterator; + + typedef + pat_trie_const_node_it_< + node, + leaf, + head, + internal_node, + const_iterator, + iterator, + synth_e_access_traits, + Allocator> + const_node_iterator; + + typedef const_node_iterator node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + E_Access_Traits, + Allocator> + node_update; + + typedef + pb_ds::null_trie_node_update< + const_node_iterator, + const_node_iterator, + E_Access_Traits, + Allocator>* + null_node_update_pointer; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP + diff --git a/libstdc++/include/ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp new file mode 100644 index 0000000..445376e --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file update_fn_imps.hpp + * Contains an implementation class for pat_trie_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer /*p_nd*/, null_node_update_pointer) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer p_nd, Node_Update_* /*p_update*/) +{ + Node_Update_::operator()(node_iterator(p_nd, this), + const_node_iterator(NULL, this)); +} diff --git a/libstdc++/include/ext/pb_ds/detail/priority_queue_base_dispatch.hpp b/libstdc++/include/ext/pb_ds/detail/priority_queue_base_dispatch.hpp new file mode 100644 index 0000000..67a7052 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/priority_queue_base_dispatch.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file priority_queue_base_dispatch.hpp + * Contains an pqiative container dispatching base. + */ + +#ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP +#define PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP + +#include <ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp> +#include <ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp> +#include <ext/pb_ds/detail/binary_heap_/binary_heap_.hpp> +#include <ext/pb_ds/detail/thin_heap_/thin_heap_.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Value_Type, typename Cmp_Fn, typename Tag, typename Allocator> + struct priority_queue_base_dispatch; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, pairing_heap_tag, Allocator> + { + typedef pairing_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, binomial_heap_tag, Allocator> + { + typedef binomial_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, rc_binomial_heap_tag, Allocator> + { + typedef rc_binomial_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, binary_heap_tag, Allocator> + { + typedef binary_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, thin_heap_tag, Allocator> + { + typedef thin_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..c4a1bb8 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,106 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn) : + base_type(r_cmp_fn) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : + base_type(r_cmp_fn, r_node_update) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : + base_type(other) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + base_type::swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ base_type::m_p_head->m_red = true; } diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp new file mode 100644 index 0000000..08107ec --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp @@ -0,0 +1,84 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const node_pointer p_nd) const +{ + if (p_nd == NULL) + return 1; + + const size_type l_height = assert_node_consistent(p_nd->m_p_left); + const size_type r_height = assert_node_consistent(p_nd->m_p_right); + if (p_nd->m_red) + { + _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_nd->m_p_left)); + _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_nd->m_p_right)); + } + _GLIBCXX_DEBUG_ASSERT(l_height == r_height); + return (p_nd->m_red ? 0 : 1) + l_height; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + base_type::assert_valid(); + const node_pointer p_head = base_type::m_p_head; + _GLIBCXX_DEBUG_ASSERT(p_head->m_red); + if (p_head->m_p_parent != NULL) + { + _GLIBCXX_DEBUG_ASSERT(!p_head->m_p_parent->m_red); + assert_node_consistent(p_head->m_p_parent); + } +} + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp new file mode 100644 index 0000000..77b4990 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp @@ -0,0 +1,295 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + point_iterator it = find(r_key); + if (it == base_type::end()) + return false; + erase(it); + return true; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +erase(iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + if (it == base_type::end()) + return it; + + iterator ret_it = it; + ++ret_it; + erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +erase(reverse_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + if (it.m_p_nd == base_type::m_p_head) + return it; + + reverse_iterator ret_it = it; + ++ret_it; + erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + size_type num_ersd = 0; + iterator it = base_type::begin(); + while (it != base_type::end()) + { + if (pred(*it)) + { + ++num_ersd; + it = erase(it); + } + else + ++it; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_node(node_pointer p_nd) +{ + remove_node(p_nd); + base_type::actual_erase_node(p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +remove_node(node_pointer p_z) +{ + update_min_max_for_erased_node(p_z); + node_pointer p_y = p_z; + node_pointer p_x = NULL; + node_pointer p_new_x_parent = NULL; + + if (p_y->m_p_left == NULL) + p_x = p_y->m_p_right; + else if (p_y->m_p_right == NULL) + p_x = p_y->m_p_left; + else + { + p_y = p_y->m_p_right; + while (p_y->m_p_left != NULL) + p_y = p_y->m_p_left; + p_x = p_y->m_p_right; + } + + if (p_y == p_z) + { + p_new_x_parent = p_y->m_p_parent; + if (p_x != NULL) + p_x->m_p_parent = p_y->m_p_parent; + + if (base_type::m_p_head->m_p_parent == p_z) + base_type::m_p_head->m_p_parent = p_x; + else if (p_z->m_p_parent->m_p_left == p_z) + { + p_y->m_p_left = p_z->m_p_parent; + p_z->m_p_parent->m_p_left = p_x; + } + else + { + p_y->m_p_left = NULL; + p_z->m_p_parent->m_p_right = p_x; + } + } + else + { + p_z->m_p_left->m_p_parent = p_y; + p_y->m_p_left = p_z->m_p_left; + if (p_y != p_z->m_p_right) + { + p_new_x_parent = p_y->m_p_parent; + if (p_x != NULL) + p_x->m_p_parent = p_y->m_p_parent; + p_y->m_p_parent->m_p_left = p_x; + p_y->m_p_right = p_z->m_p_right; + p_z->m_p_right->m_p_parent = p_y; + } + else + p_new_x_parent = p_y; + + if (base_type::m_p_head->m_p_parent == p_z) + base_type::m_p_head->m_p_parent = p_y; + else if (p_z->m_p_parent->m_p_left == p_z) + p_z->m_p_parent->m_p_left = p_y; + else + p_z->m_p_parent->m_p_right = p_y; + + p_y->m_p_parent = p_z->m_p_parent; + std::swap(p_y->m_red, p_z->m_red); + p_y = p_z; + } + + update_to_top(p_new_x_parent, (node_update* )this); + + if (p_y->m_red) + return; + + remove_fixup(p_x, p_new_x_parent); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +remove_fixup(node_pointer p_x, node_pointer p_new_x_parent) +{ + _GLIBCXX_DEBUG_ASSERT(p_x == NULL || p_x->m_p_parent == p_new_x_parent); + + while (p_x != base_type::m_p_head->m_p_parent && is_effectively_black(p_x)) + if (p_x == p_new_x_parent->m_p_left) + { + node_pointer p_w = p_new_x_parent->m_p_right; + if (p_w->m_red) + { + p_w->m_red = false; + p_new_x_parent->m_red = true; + base_type::rotate_left(p_new_x_parent); + p_w = p_new_x_parent->m_p_right; + } + + if (is_effectively_black(p_w->m_p_left) + && is_effectively_black(p_w->m_p_right)) + { + p_w->m_red = true; + p_x = p_new_x_parent; + p_new_x_parent = p_new_x_parent->m_p_parent; + } + else + { + if (is_effectively_black(p_w->m_p_right)) + { + if (p_w->m_p_left != NULL) + p_w->m_p_left->m_red = false; + + p_w->m_red = true; + base_type::rotate_right(p_w); + p_w = p_new_x_parent->m_p_right; + } + + p_w->m_red = p_new_x_parent->m_red; + p_new_x_parent->m_red = false; + + if (p_w->m_p_right != NULL) + p_w->m_p_right->m_red = false; + + base_type::rotate_left(p_new_x_parent); + update_to_top(p_new_x_parent, (node_update* )this); + break; + } + } + else + { + node_pointer p_w = p_new_x_parent->m_p_left; + if (p_w->m_red == true) + { + p_w->m_red = false; + p_new_x_parent->m_red = true; + base_type::rotate_right(p_new_x_parent); + p_w = p_new_x_parent->m_p_left; + } + + if (is_effectively_black(p_w->m_p_right) + && is_effectively_black(p_w->m_p_left)) + { + p_w->m_red = true; + p_x = p_new_x_parent; + p_new_x_parent = p_new_x_parent->m_p_parent; + } + else + { + if (is_effectively_black(p_w->m_p_left)) + { + if (p_w->m_p_right != NULL) + p_w->m_p_right->m_red = false; + + p_w->m_red = true; + base_type::rotate_left(p_w); + p_w = p_new_x_parent->m_p_left; + } + + p_w->m_red = p_new_x_parent->m_red; + p_new_x_parent->m_red = false; + + if (p_w->m_p_left != NULL) + p_w->m_p_left->m_red = false; + + base_type::rotate_right(p_new_x_parent); + update_to_top(p_new_x_parent, (node_update* )this); + break; + } + } + + if (p_x != NULL) + p_x->m_red = false; +} diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hpp new file mode 100644 index 0000000..25938ae --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hpp @@ -0,0 +1,45 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp new file mode 100644 index 0000000..7b65baa --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp @@ -0,0 +1,52 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_effectively_black(const node_pointer p_nd) +{ return (p_nd == NULL || !p_nd->m_red); } + diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp new file mode 100644 index 0000000..3bc7ce1 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp @@ -0,0 +1,121 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert(const_reference r_value) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + std::pair<point_iterator, bool> ins_pair = base_type::insert_leaf(r_value); + if (ins_pair.second == true) + { + ins_pair.first.m_p_nd->m_red = true; + _GLIBCXX_DEBUG_ONLY(this->structure_only_assert_valid();) + insert_fixup(ins_pair.first.m_p_nd); + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return ins_pair; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_fixup(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd->m_red == true); + while (p_nd != base_type::m_p_head->m_p_parent && p_nd->m_p_parent->m_red) + { + if (p_nd->m_p_parent == p_nd->m_p_parent->m_p_parent->m_p_left) + { + node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_right; + if (p_y != NULL && p_y->m_red) + { + p_nd->m_p_parent->m_red = false; + p_y->m_red = false; + p_nd->m_p_parent->m_p_parent->m_red = true; + p_nd = p_nd->m_p_parent->m_p_parent; + } + else + { + if (p_nd == p_nd->m_p_parent->m_p_right) + { + p_nd = p_nd->m_p_parent; + base_type::rotate_left(p_nd); + } + p_nd->m_p_parent->m_red = false; + p_nd->m_p_parent->m_p_parent->m_red = true; + base_type::rotate_right(p_nd->m_p_parent->m_p_parent); + } + } + else + { + node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_left; + if (p_y != NULL && p_y->m_red) + { + p_nd->m_p_parent->m_red = false; + p_y->m_red = false; + p_nd->m_p_parent->m_p_parent->m_red = true; + p_nd = p_nd->m_p_parent->m_p_parent; + } + else + { + if (p_nd == p_nd->m_p_parent->m_p_left) + { + p_nd = p_nd->m_p_parent; + base_type::rotate_right(p_nd); + } + p_nd->m_p_parent->m_red = false; + p_nd->m_p_parent->m_p_parent->m_red = true; + base_type::rotate_left(p_nd->m_p_parent->m_p_parent); + } + } + } + + base_type::update_to_top(p_nd, (node_update* )this); + base_type::m_p_head->m_p_parent->m_red = false; +} diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/node.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/node.hpp new file mode 100644 index 0000000..164f965 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/node.hpp @@ -0,0 +1,144 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node.hpp + * Contains an implementation for rb_tree_. + */ + +#ifndef PB_DS_RB_TREE_NODE_HPP +#define PB_DS_RB_TREE_NODE_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Value_Type, class Metadata, class Allocator> + struct rb_tree_node_ + { + public: + typedef Value_Type value_type; + typedef Metadata metadata_type; + + typedef + typename Allocator::template rebind< + rb_tree_node_< + Value_Type, + Metadata, + Allocator> >::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + metadata_type>::other::reference + metadata_reference; + + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + inline bool + special() const + { return m_red; } + + inline const_metadata_reference + get_metadata() const + { return m_metadata; } + + inline metadata_reference + get_metadata() + { return m_metadata; } + +#ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ + void + trace() const + { + std::cout << PB_DS_V2F(m_value) <<(m_red? " <r> " : " <b> ") + << "(" << m_metadata << ")"; + } +#endif + + node_pointer m_p_left; + node_pointer m_p_right; + node_pointer m_p_parent; + value_type m_value; + bool m_red; + metadata_type m_metadata; + }; + + template<typename Value_Type, class Allocator> + struct rb_tree_node_<Value_Type, null_node_metadata, Allocator> + { + public: + typedef Value_Type value_type; + typedef null_node_metadata metadata_type; + + typedef + typename Allocator::template rebind< + rb_tree_node_< + Value_Type, + null_node_metadata, + Allocator> >::other::pointer + node_pointer; + + inline bool + special() const + { return m_red; } + +#ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ + void + trace() const + { std::cout << PB_DS_V2F(m_value) <<(m_red? " <r> " : " <b> "); } +#endif + + node_pointer m_p_left; + node_pointer m_p_right; + node_pointer m_p_parent; + value_type m_value; + bool m_red; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp new file mode 100644 index 0000000..d08b2db --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp @@ -0,0 +1,286 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rb_tree_.hpp + * Contains an implementation for rb_tree_. + */ +/* + * This implementation uses an idea from the SGI STL (using a "header" node + * which is needed for efficient iteration). + */ + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#ifndef PB_DS_BIN_SEARCH_TREE_HPP__DATA_TRUE_INDICATOR +#define PB_DS_BIN_SEARCH_TREE_HPP__DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> +#endif +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#ifndef PB_DS_BIN_SEARCH_TREE_HPP__DATA_FALSE_INDICATOR +#define PB_DS_BIN_SEARCH_TREE_HPP__DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> +#endif +#endif + +#include <ext/pb_ds/detail/standard_policies.hpp> +#include <ext/pb_ds/detail/basic_types.hpp> +#include <utility> +#include <vector> +#include <assert.h> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Cmp_Fn, \ + typename Node_And_It_Traits, typename Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME rb_tree_data_ +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_BASE_CLASS_NAME bin_search_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME rb_tree_no_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_BASE_CLASS_NAME bin_search_tree_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#define PB_DS_BASE_C_DEC \ + PB_DS_BASE_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + + template<typename Key, + typename Mapped, + typename Cmp_Fn, + typename Node_And_It_Traits, + typename Allocator> + class PB_DS_CLASS_NAME : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + typedef typename base_type::node_pointer node_pointer; + + public: + typedef Cmp_Fn cmp_fn; + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef typename base_type::key_type key_type; + typedef typename base_type::key_pointer key_pointer; + typedef typename base_type::const_key_pointer const_key_pointer; + typedef typename base_type::key_reference key_reference; + typedef typename base_type::const_key_reference const_key_reference; + typedef typename base_type::mapped_type mapped_type; + typedef typename base_type::mapped_pointer mapped_pointer; + typedef typename base_type::const_mapped_pointer const_mapped_pointer; + typedef typename base_type::mapped_reference mapped_reference; + typedef typename base_type::const_mapped_reference const_mapped_reference; + typedef typename base_type::value_type value_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_iterator const_point_iterator; + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::reverse_iterator reverse_iterator; + typedef typename base_type::const_reverse_iterator const_reverse_iterator; + typedef typename base_type::node_update node_update; + + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const Cmp_Fn&); + + PB_DS_CLASS_NAME(const Cmp_Fn&, const node_update&); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + void + swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_range(It, It); + + inline std::pair<point_iterator, bool> + insert(const_reference); + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + _GLIBCXX_DEBUG_ONLY(assert_valid();) + std::pair<point_iterator, bool> ins_pair = + base_type::insert_leaf(value_type(r_key, mapped_type())); + + if (ins_pair.second == true) + { + ins_pair.first.m_p_nd->m_red = true; + _GLIBCXX_DEBUG_ONLY(this->structure_only_assert_valid();) + insert_fixup(ins_pair.first.m_p_nd); + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return ins_pair.first.m_p_nd->m_value.second; +#else + insert(r_key); + return base_type::s_null_mapped; +#endif + } + + inline bool + erase(const_key_reference); + + inline iterator + erase(iterator); + + inline reverse_iterator + erase(reverse_iterator); + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + join(PB_DS_CLASS_C_DEC&); + + void + split(const_key_reference, PB_DS_CLASS_C_DEC&); + + protected: + + private: + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + size_type + assert_node_consistent(const node_pointer) const; +#endif + + inline static bool + is_effectively_black(const node_pointer); + + void + initialize(); + + void + insert_fixup(node_pointer); + + void + erase_node(node_pointer); + + void + remove_node(node_pointer); + + void + remove_fixup(node_pointer, node_pointer); + + void + split_imp(node_pointer, PB_DS_CLASS_C_DEC&); + + inline node_pointer + split_min(); + + std::pair<node_pointer, node_pointer> + split_min_imp(); + + void + join_imp(node_pointer, node_pointer); + + std::pair<node_pointer, node_pointer> + find_join_pos_right(node_pointer, size_type, size_type); + + std::pair<node_pointer, node_pointer> + find_join_pos_left(node_pointer, size_type, size_type); + + inline size_type + black_height(node_pointer); + + void + split_at_node(node_pointer, PB_DS_CLASS_C_DEC&); + }; + +#include <ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_BASE_CLASS_NAME +#undef PB_DS_BASE_C_DEC +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S + + } // namespace detail +} // namespace pb_ds + diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp new file mode 100644 index 0000000..94b5ac3 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp @@ -0,0 +1,319 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.base_type::assert_valid();) + if (base_type::join_prep(other) == false) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + const node_pointer p_x = other.split_min(); + join_imp(p_x, other.m_p_head->m_p_parent); + base_type::join_finish(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(base_type::assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.base_type::assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +join_imp(node_pointer p_x, node_pointer p_r) +{ + _GLIBCXX_DEBUG_ASSERT(p_x != NULL); + if (p_r != NULL) + p_r->m_red = false; + + const size_type h = black_height(base_type::m_p_head->m_p_parent); + const size_type other_h = black_height(p_r); + node_pointer p_x_l; + node_pointer p_x_r; + std::pair<node_pointer, node_pointer> join_pos; + const bool right_join = h >= other_h; + if (right_join) + { + join_pos = find_join_pos_right(base_type::m_p_head->m_p_parent, + h, other_h); + p_x_l = join_pos.first; + p_x_r = p_r; + } + else + { + p_x_l = base_type::m_p_head->m_p_parent; + base_type::m_p_head->m_p_parent = p_r; + if (p_r != NULL) + p_r->m_p_parent = base_type::m_p_head; + + join_pos = find_join_pos_left(base_type::m_p_head->m_p_parent, + h, other_h); + p_x_r = join_pos.first; + } + + node_pointer p_parent = join_pos.second; + if (p_parent == base_type::m_p_head) + { + base_type::m_p_head->m_p_parent = p_x; + p_x->m_p_parent = base_type::m_p_head; + } + else + { + p_x->m_p_parent = p_parent; + if (right_join) + p_x->m_p_parent->m_p_right = p_x; + else + p_x->m_p_parent->m_p_left = p_x; + } + + p_x->m_p_left = p_x_l; + if (p_x_l != NULL) + p_x_l->m_p_parent = p_x; + + p_x->m_p_right = p_x_r; + if (p_x_r != NULL) + p_x_r->m_p_parent = p_x; + + p_x->m_red = true; + + base_type::initialize_min_max(); + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + base_type::update_to_top(p_x, (node_update* )this); + insert_fixup(p_x); + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +split_min() +{ + node_pointer p_min = base_type::m_p_head->m_p_left; + +#ifdef _GLIBCXX_DEBUG + const node_pointer p_head = base_type::m_p_head; + _GLIBCXX_DEBUG_ASSERT(p_min != p_head); +#endif + + remove_node(p_min); + return p_min; +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::node_pointer, + typename PB_DS_CLASS_C_DEC::node_pointer> +PB_DS_CLASS_C_DEC:: +find_join_pos_right(node_pointer p_l, size_type h_l, size_type h_r) +{ + _GLIBCXX_DEBUG_ASSERT(h_l >= h_r); + + if (base_type::m_p_head->m_p_parent == NULL) + return (std::make_pair((node_pointer)NULL, base_type::m_p_head)); + + node_pointer p_l_parent = base_type::m_p_head; + while (h_l > h_r) + { + if (p_l->m_red == false) + { + _GLIBCXX_DEBUG_ASSERT(h_l > 0); + --h_l; + } + + p_l_parent = p_l; + p_l = p_l->m_p_right; + } + + if (!is_effectively_black(p_l)) + { + p_l_parent = p_l; + p_l = p_l->m_p_right; + } + + _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_l)); + _GLIBCXX_DEBUG_ASSERT(black_height(p_l) == h_r); + _GLIBCXX_DEBUG_ASSERT(p_l == NULL || p_l->m_p_parent == p_l_parent); + return std::make_pair(p_l, p_l_parent); +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::node_pointer, + typename PB_DS_CLASS_C_DEC::node_pointer> +PB_DS_CLASS_C_DEC:: +find_join_pos_left(node_pointer p_r, size_type h_l, size_type h_r) +{ + _GLIBCXX_DEBUG_ASSERT(h_r > h_l); + if (base_type::m_p_head->m_p_parent == NULL) + return (std::make_pair((node_pointer)NULL, + base_type::m_p_head)); + node_pointer p_r_parent = base_type::m_p_head; + while (h_r > h_l) + { + if (p_r->m_red == false) + { + _GLIBCXX_DEBUG_ASSERT(h_r > 0); + --h_r; + } + + p_r_parent = p_r; + p_r = p_r->m_p_left; + } + + if (!is_effectively_black(p_r)) + { + p_r_parent = p_r; + p_r = p_r->m_p_left; + } + + _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_r)); + _GLIBCXX_DEBUG_ASSERT(black_height(p_r) == h_l); + _GLIBCXX_DEBUG_ASSERT(p_r == NULL || p_r->m_p_parent == p_r_parent); + return std::make_pair(p_r, p_r_parent); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +black_height(node_pointer p_nd) +{ + size_type h = 1; + while (p_nd != NULL) + { + if (p_nd->m_red == false) + ++h; + p_nd = p_nd->m_p_left; + } + return h; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(base_type::assert_valid();) + + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.base_type::assert_valid();) + + if (base_type::split_prep(r_key, other) == false) + { + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + return; + } + + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.base_type::structure_only_assert_valid();) + node_pointer p_nd = upper_bound(r_key).m_p_nd; + do + { + node_pointer p_next_nd = p_nd->m_p_parent; + if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) + split_at_node(p_nd, other); + + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.base_type::structure_only_assert_valid();) + p_nd = p_next_nd; + } + while (p_nd != base_type::m_p_head); + + base_type::split_finish(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split_at_node(node_pointer p_nd, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + + node_pointer p_l = p_nd->m_p_left; + node_pointer p_r = p_nd->m_p_right; + node_pointer p_parent = p_nd->m_p_parent; + if (p_parent == base_type::m_p_head) + { + base_type::m_p_head->m_p_parent = p_l; + if (p_l != NULL) + { + p_l->m_p_parent = base_type::m_p_head; + p_l->m_red = false; + } + } + else + { + if (p_parent->m_p_left == p_nd) + p_parent->m_p_left = p_l; + else + p_parent->m_p_right = p_l; + + if (p_l != NULL) + p_l->m_p_parent = p_parent; + + update_to_top(p_parent, (node_update* )this); + + if (!p_nd->m_red) + remove_fixup(p_l, p_parent); + } + + base_type::initialize_min_max(); + other.join_imp(p_nd, p_r); + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.base_type::structure_only_assert_valid()); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/traits.hpp b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/traits.hpp new file mode 100644 index 0000000..67570d8 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/traits.hpp @@ -0,0 +1,130 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation for rb_tree_. + */ + +#ifndef PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/rb_tree_map_/node.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, + typename Mapped, + typename Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + typename Allocator> + struct tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + rb_tree_tag, + Allocator> : public bin_search_tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + rb_tree_node_< + typename types_traits< + Key, + Mapped, + Allocator, + false>::value_type, + typename tree_node_metadata_selector< + Key, + Mapped, + Cmp_Fn, + Node_Update, + Allocator>::type, + Allocator>, + Allocator> + { }; + + template<typename Key, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + rb_tree_tag, + Allocator> : public bin_search_tree_traits< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + rb_tree_node_< + typename types_traits< + Key, + null_mapped_type, + Allocator, + false>::value_type, + typename tree_node_metadata_selector< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + Allocator>::type, + Allocator>, + Allocator> + { }; + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..8b439c8 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,94 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +rc_binomial_heap_() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +rc_binomial_heap_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +rc_binomial_heap_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other) +{ + make_binomial_heap(); + + base_type::find_max(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~rc_binomial_heap_() +{ } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + base_type::swap(other); + + m_rc.swap(other.m_rc); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + diff --git a/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp new file mode 100644 index 0000000..e621cb5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp @@ -0,0 +1,127 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + base_type::assert_valid(false); + if (!base_type::empty()) + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_max != NULL); + base_type::assert_max(); + } + + m_rc.assert_valid(); + + if (m_rc.empty()) + { + base_type::assert_valid(true); + _GLIBCXX_DEBUG_ASSERT(next_2_pointer(base_type::m_p_root) == NULL); + return; + } + + const_node_pointer p_nd = next_2_pointer(base_type::m_p_root); + typename rc_t::const_iterator it = m_rc.end(); + --it; + + while (p_nd != NULL) + { + _GLIBCXX_DEBUG_ASSERT(*it == p_nd); + const_node_pointer p_next = p_nd->m_p_next_sibling; + _GLIBCXX_DEBUG_ASSERT(p_next != NULL); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_next->m_metadata); + _GLIBCXX_DEBUG_ASSERT(p_next->m_p_next_sibling == NULL || + p_next->m_metadata < p_next->m_p_next_sibling->m_metadata); + + --it; + p_nd = next_2_pointer(next_after_0_pointer(p_nd)); + } + _GLIBCXX_DEBUG_ASSERT(it + 1 == m_rc.begin()); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::const_node_pointer +PB_DS_CLASS_C_DEC:: +next_2_pointer(const_node_pointer p_nd) +{ + if (p_nd == NULL) + return NULL; + + node_pointer p_next = p_nd->m_p_next_sibling; + + if (p_next == NULL) + return NULL; + + if (p_nd->m_metadata == p_next->m_metadata) + return p_nd; + + return next_2_pointer(p_next); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::const_node_pointer +PB_DS_CLASS_C_DEC:: +next_after_0_pointer(const_node_pointer p_nd) +{ + if (p_nd == NULL) + return NULL; + + node_pointer p_next = p_nd->m_p_next_sibling; + + if (p_next == NULL) + return NULL; + + if (p_nd->m_metadata < p_next->m_metadata) + return p_next; + + return next_after_0_pointer(p_next); +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp new file mode 100644 index 0000000..b38141c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp @@ -0,0 +1,113 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +pop() +{ + make_binomial_heap(); + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + base_type::pop(); + base_type::find_max(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + base_type::clear(); + m_rc.clear(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +make_binomial_heap() +{ + node_pointer p_nd = base_type::m_p_root; + while (p_nd != NULL) + { + node_pointer p_next = p_nd->m_p_next_sibling; + if (p_next == NULL) + p_nd = p_next; + else if (p_nd->m_metadata == p_next->m_metadata) + p_nd = link_with_next_sibling(p_nd); + else if (p_nd->m_metadata < p_next->m_metadata) + p_nd = p_next; +#ifdef _GLIBCXX_DEBUG + else + _GLIBCXX_DEBUG_ASSERT(0); +#endif + } + + m_rc.clear(); +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + make_binomial_heap(); + const size_type ersd = base_type::erase_if(pred); + base_type::find_max(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + make_binomial_heap(); + base_type::erase(it); + base_type::find_max(); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp new file mode 100644 index 0000000..c0f0d01 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp @@ -0,0 +1,160 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + make_0_exposed(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + node_pointer p_nd = base_type::get_new_node_for_insert(r_val); + + p_nd->m_p_l_child = p_nd->m_p_prev_or_parent = NULL; + p_nd->m_metadata = 0; + + if (base_type::m_p_max == NULL || Cmp_Fn::operator()(base_type::m_p_max->m_value, r_val)) + base_type::m_p_max = p_nd; + + p_nd->m_p_next_sibling = base_type::m_p_root; + + if (base_type::m_p_root != NULL) + base_type::m_p_root->m_p_prev_or_parent = p_nd; + + base_type::m_p_root = p_nd; + + if (p_nd->m_p_next_sibling != NULL&& p_nd->m_p_next_sibling->m_metadata == 0) + m_rc.push(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(p_nd); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + make_binomial_heap(); + + base_type::modify(it, r_new_val); + + base_type::find_max(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +link_with_next_sibling(node_pointer p_nd) +{ + node_pointer p_next = p_nd->m_p_next_sibling; + + _GLIBCXX_DEBUG_ASSERT(p_next != NULL); + _GLIBCXX_DEBUG_ASSERT(p_next->m_p_prev_or_parent == p_nd); + + if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) + { + p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + + if (p_next->m_p_prev_or_parent == NULL) + base_type::m_p_root = p_next; + else + p_next->m_p_prev_or_parent->m_p_next_sibling = p_next; + + if (base_type::m_p_max == p_nd) + base_type::m_p_max = p_next; + + base_type::make_child_of(p_nd, p_next); + + ++p_next->m_metadata; + + return p_next; + } + + p_nd->m_p_next_sibling = p_next->m_p_next_sibling; + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; + + if (base_type::m_p_max == p_next) + base_type::m_p_max = p_nd; + + base_type::make_child_of(p_next, p_nd); + + ++p_nd->m_metadata; + + return p_nd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +make_0_exposed() +{ + if (m_rc.empty()) + return; + + node_pointer p_nd = m_rc.top(); + + m_rc.pop(); + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling != NULL); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata); + + node_pointer p_res = link_with_next_sibling(p_nd); + + if (p_res->m_p_next_sibling != NULL&& p_res->m_metadata == p_res->m_p_next_sibling->m_metadata) + m_rc.push(p_res); +} diff --git a/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp new file mode 100644 index 0000000..dc7869c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp @@ -0,0 +1,268 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rc.hpp + * Contains a redundant (binary counter). + */ + +#ifndef PB_DS_RC_HPP +#define PB_DS_RC_HPP + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Node, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + rc<Node, Allocator> + + template<typename Node, class Allocator> + class rc + { + private: + typedef Allocator allocator; + + typedef typename allocator::size_type size_type; + + typedef Node node; + + typedef + typename allocator::template rebind< + node>::other::pointer + node_pointer; + + typedef + typename allocator::template rebind< + node_pointer>::other::pointer + entry_pointer; + + typedef + typename allocator::template rebind< + node_pointer>::other::const_pointer + const_entry_pointer; + + enum + { + max_entries = sizeof(size_type) << 3 + }; + + public: + typedef node_pointer entry; + + typedef const_entry_pointer const_iterator; + + public: + rc(); + + rc(const PB_DS_CLASS_C_DEC& other); + + inline void + swap(PB_DS_CLASS_C_DEC& other); + + inline void + push(entry p_nd); + + inline node_pointer + top() const; + + inline void + pop(); + + inline bool + empty() const; + + inline size_type + size() const; + + void + clear(); + + const const_iterator + begin() const; + + const const_iterator + end() const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ + void + trace() const; +#endif + + private: + node_pointer m_a_entries[max_entries]; + + size_type m_over_top; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + rc() : m_over_top(0) + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + rc(const PB_DS_CLASS_C_DEC& other) : m_over_top(0) + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + const size_type over_top = std::max(m_over_top, other.m_over_top); + + for (size_type i = 0; i < over_top; ++i) + std::swap(m_a_entries[i], other.m_a_entries[i]); + + std::swap(m_over_top, other.m_over_top); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + push(entry p_nd) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(m_over_top < max_entries); + m_a_entries[m_over_top++] = p_nd; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + pop() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + --m_over_top; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + top() const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + return *(m_a_entries + m_over_top - 1); + } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + empty() const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return m_over_top == 0; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + size() const + { return m_over_top; } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + clear() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + m_over_top = 0; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + const typename PB_DS_CLASS_C_DEC::const_iterator + PB_DS_CLASS_C_DEC:: + begin() const + { return& m_a_entries[0]; } + + PB_DS_CLASS_T_DEC + const typename PB_DS_CLASS_C_DEC::const_iterator + PB_DS_CLASS_C_DEC:: + end() const + { return& m_a_entries[m_over_top]; } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + assert_valid() const + { _GLIBCXX_DEBUG_ASSERT(m_over_top < max_entries); } +#endif + +#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace() const + { + std::cout << "rc" << std::endl; + for (size_type i = 0; i < m_over_top; ++i) + std::cerr << m_a_entries[i] << std::endl; + std::cout << std::endl; + } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp new file mode 100644 index 0000000..42417ed --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp @@ -0,0 +1,204 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rc_binomial_heap_.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +/* + * Redundant-counter binomial heap. + */ + +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/rc.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + rc_binomial_heap_<Value_Type, Cmp_Fn, Allocator> + +#define PB_DS_BASE_C_DEC \ + binomial_heap_base_<Value_Type, Cmp_Fn, Allocator> + +#define PB_DS_RC_C_DEC \ + rc<typename PB_DS_BASE_C_DEC::node, Allocator> + + /** + * class description = "8y|\|0|\/|i41 h34p 74813"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class rc_binomial_heap_ : public PB_DS_BASE_C_DEC + { + + private: + typedef PB_DS_BASE_C_DEC base_type; + + typedef typename base_type::node_pointer node_pointer; + + typedef typename base_type::const_node_pointer const_node_pointer; + + typedef PB_DS_RC_C_DEC rc_t; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef typename base_type::pointer pointer; + + typedef typename base_type::const_pointer const_pointer; + + typedef typename base_type::reference reference; + + typedef typename base_type::const_reference const_reference; + + typedef typename base_type::const_point_iterator const_point_iterator; + + typedef typename base_type::point_iterator point_iterator; + + typedef typename base_type::const_iterator const_iterator; + + typedef typename base_type::iterator iterator; + + typedef typename base_type::cmp_fn cmp_fn; + + typedef typename base_type::allocator allocator; + + public: + + rc_binomial_heap_(); + + rc_binomial_heap_(const Cmp_Fn& r_cmp_fn); + + rc_binomial_heap_(const PB_DS_CLASS_C_DEC& other); + + ~rc_binomial_heap_(); + + void + swap(PB_DS_CLASS_C_DEC& other); + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline void + pop(); + + void + erase(point_iterator it); + + inline void + clear(); + + template<typename Pred> + size_type + erase_if(Pred pred); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ + void + trace() const; +#endif + + private: + + inline node_pointer + link_with_next_sibling(node_pointer p_nd); + + void + make_0_exposed(); + + void + make_binomial_heap(); + +#ifdef _GLIBCXX_DEBUG + static const_node_pointer + next_2_pointer(const_node_pointer p_nd); + + static const_node_pointer + next_after_0_pointer(const_node_pointer p_nd); +#endif + + private: + rc_t m_rc; + }; + +#include <ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_BASE_C_DEC + +#undef PB_DS_RC_C_DEC + } // namespace detail +} // namespace pb_ds diff --git a/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp new file mode 100644 index 0000000..356732b --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp @@ -0,0 +1,87 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + make_binomial_heap(); + other.make_binomial_heap(); + + base_type::split(pred, other); + + base_type::find_max(); + other.find_max(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + make_binomial_heap(); + other.make_binomial_heap(); + + base_type::join(other); + + base_type::find_max(); + other.find_max(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + diff --git a/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp new file mode 100644 index 0000000..48c2e52 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + base_type::trace(); + + m_rc.trace(); +} + +#endif // #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ diff --git a/libstdc++/include/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp b/libstdc++/include/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp new file mode 100644 index 0000000..c10f7b6 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp @@ -0,0 +1,221 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cc_hash_max_collision_check_resize_trigger_imp.hpp + * Contains a resize trigger implementation. + */ + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef detail::static_assert_dumclass<sizeof(detail::static_assert<(bool)(E)>)> UNIQUE##static_assert_type + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +cc_hash_max_collision_check_resize_trigger(float load) : + m_load(load), + m_size(0), + m_num_col(0), + m_max_col(0), + m_resize_needed(false) +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_start() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_collision() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_end() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_start() +{ m_num_col = 0; } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_collision() +{ ++m_num_col; } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_end() +{ calc_resize_needed(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_start() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_collision() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_end() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_inserted(size_type) +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erased(size_type) +{ m_resize_needed = true; } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_cleared() +{ m_resize_needed = false; } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_resize_needed() const +{ return m_resize_needed; } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_grow_needed(size_type /*size*/, size_type /*num_used_e*/) const +{ return m_num_col >= m_max_col; } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type new_size) +{ + m_size = new_size; + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "chmccrt::notify_resized " + << static_cast<unsigned long>(new_size) << std::endl; +#endif + + calc_max_num_coll(); + calc_resize_needed(); + m_num_col = 0; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +calc_max_num_coll() +{ + // max_col <-- \sqrt{2 load \ln( 2 m \ln( m ) ) } + const double ln_arg = 2 * m_size * ::log(double(m_size)); + m_max_col = size_type(::ceil(::sqrt(2 * m_load * ::log(ln_arg)))); + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "chmccrt::calc_max_num_coll " + << static_cast<unsigned long>(m_size) << " " + << static_cast<unsigned long>(m_max_col) << std::endl; +#endif +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_externally_resized(size_type new_size) +{ notify_resized(new_size); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_load, other.m_load); + std::swap(m_size, other.m_size); + std::swap(m_num_col, other.m_num_col); + std::swap(m_max_col, other.m_max_col); + std::swap(m_resize_needed, other.m_resize_needed); +} + +PB_DS_CLASS_T_DEC +inline float +PB_DS_CLASS_C_DEC:: +get_load() const +{ + PB_DS_STATIC_ASSERT(access, external_load_access); + return m_load; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +calc_resize_needed() +{ m_resize_needed = m_resize_needed || m_num_col >= m_max_col; } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +set_load(float load) +{ + PB_DS_STATIC_ASSERT(access, external_load_access); + m_load = load; + calc_max_num_coll(); + calc_resize_needed(); +} + +#undef PB_DS_STATIC_ASSERT diff --git a/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp new file mode 100644 index 0000000..51cfc45 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp @@ -0,0 +1,96 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_exponential_size_policy_imp.hpp + * Contains a resize size policy implementation. + */ + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_exponential_size_policy(size_type start_size, size_type grow_factor) : + m_start_size(start_size), + m_grow_factor(grow_factor) +{ } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_start_size, other.m_start_size); + std::swap(m_grow_factor, other.m_grow_factor); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_nearest_larger_size(size_type size) const +{ + size_type ret = m_start_size; + while (ret <= size) + { + const size_type next_ret = ret* m_grow_factor; + if (next_ret < ret) + __throw_insert_error(); + ret = next_ret; + } + return ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_nearest_smaller_size(size_type size) const +{ + size_type ret = m_start_size; + while (true) + { + const size_type next_ret = ret* m_grow_factor; + if (next_ret < ret) + __throw_resize_error(); + if (next_ret >= size) + return (ret); + ret = next_ret; + } + return ret; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp new file mode 100644 index 0000000..f3c597f --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp @@ -0,0 +1,300 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_load_check_resize_trigger_imp.hpp + * Contains a resize trigger implementation. + */ + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef detail::static_assert_dumclass<sizeof(detail::static_assert<bool(E)>)> UNIQUE##static_assert_type + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_load_check_resize_trigger(float load_min, float load_max) +: m_load_min(load_min), m_load_max(load_max), m_next_shrink_size(0), + m_next_grow_size(0), m_resize_needed(false) +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_start() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_collision() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_end() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_start() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_collision() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_end() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_start() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_collision() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_end() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_inserted(size_type num_entries) +{ + m_resize_needed = (num_entries >= m_next_grow_size); + size_base::set_size(num_entries); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erased(size_type num_entries) +{ + size_base::set_size(num_entries); + m_resize_needed = num_entries <= m_next_shrink_size; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_resize_needed() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return m_resize_needed; +} + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_grow_needed(size_type /*size*/, size_type num_entries) const +{ + _GLIBCXX_DEBUG_ASSERT(m_resize_needed); + return num_entries >= m_next_grow_size; +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~hash_load_check_resize_trigger() { } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type new_size) +{ + m_resize_needed = false; + m_next_grow_size = size_type(m_load_max * new_size - 1); + m_next_shrink_size = size_type(m_load_min * new_size); + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "hlcrt::notify_resized " << + static_cast<unsigned long>(new_size) << " " << + static_cast<unsigned long>(m_load_min) << " " << + static_cast<unsigned long>(m_load_max) << " " << + static_cast<unsigned long>(m_next_shrink_size) << " " << + static_cast<unsigned long>(m_next_grow_size) << " " << std::endl; +#endif + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_externally_resized(size_type new_size) +{ + m_resize_needed = false; + size_type new_grow_size = size_type(m_load_max * new_size - 1); + size_type new_shrink_size = size_type(m_load_min * new_size ); + if (new_grow_size >= m_next_grow_size) + { + _GLIBCXX_DEBUG_ASSERT(new_shrink_size > m_next_shrink_size); + m_next_grow_size = new_grow_size; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "hlcrt::notify_externally_resized1 " << + static_cast<unsigned long>(new_size) << " " << + static_cast<unsigned long>(m_load_min) << " " << + static_cast<unsigned long>(m_load_max) << " " << + static_cast<unsigned long>(m_next_shrink_size) << " " << + static_cast<unsigned long>(m_next_grow_size) << " " << std::endl; +#endif + return; + } + + _GLIBCXX_DEBUG_ASSERT(new_shrink_size <= m_next_shrink_size); + m_next_shrink_size = new_shrink_size; + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "hlcrt::notify_externally_resized2 " << + static_cast<unsigned long>(new_size) << " " << + static_cast<unsigned long>(m_load_min) << " " << + static_cast<unsigned long>(m_load_max) << " " << + static_cast<unsigned long>(m_next_shrink_size) << " " << + static_cast<unsigned long>(m_next_grow_size) << " " << std::endl; +#endif + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_cleared() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + size_base::set_size(0); + m_resize_needed = (0 < m_next_shrink_size); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + size_base::swap(other); + std::swap(m_load_min, other.m_load_min); + std::swap(m_load_max, other.m_load_max); + std::swap(m_resize_needed, other.m_resize_needed); + std::swap(m_next_grow_size, other.m_next_grow_size); + std::swap(m_next_shrink_size, other.m_next_shrink_size); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +inline std::pair<float, float> +PB_DS_CLASS_C_DEC:: +get_loads() const +{ + PB_DS_STATIC_ASSERT(access, external_load_access); + return std::make_pair(m_load_min, m_load_max); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +set_loads(std::pair<float, float> load_pair) +{ + PB_DS_STATIC_ASSERT(access, external_load_access); + const float old_load_min = m_load_min; + const float old_load_max = m_load_max; + const size_type old_next_shrink_size = m_next_shrink_size; + const size_type old_next_grow_size = m_next_grow_size; + const bool old_resize_needed = m_resize_needed; + + try + { + m_load_min = load_pair.first; + m_load_max = load_pair.second; + do_resize(static_cast<size_type>(size_base::get_size() / ((m_load_min + m_load_max) / 2))); + } + catch (...) + { + m_load_min = old_load_min; + m_load_max = old_load_max; + m_next_shrink_size = old_next_shrink_size; + m_next_grow_size = old_next_grow_size; + m_resize_needed = old_resize_needed; + __throw_exception_again; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +do_resize(size_type) +{ abort(); } + +#ifdef _GLIBCXX_DEBUG +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + _GLIBCXX_DEBUG_ASSERT(m_load_max > m_load_min); + _GLIBCXX_DEBUG_ASSERT(m_next_grow_size >= m_next_shrink_size); +} +#endif + +#undef PB_DS_STATIC_ASSERT + diff --git a/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp new file mode 100644 index 0000000..436de79 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp @@ -0,0 +1,100 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_load_check_resize_trigger_size_base.hpp + * Contains an base holding size for some resize policies. + */ + +#ifndef PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP +#define PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP + +namespace pb_ds +{ + namespace detail + { + // Primary template. + template<typename Size_Type, bool Hold_Size> + class hash_load_check_resize_trigger_size_base; + + // Specializations. + template<typename Size_Type> + class hash_load_check_resize_trigger_size_base<Size_Type, true> + { + protected: + typedef Size_Type size_type; + + hash_load_check_resize_trigger_size_base(): m_size(0) + { } + + inline void + swap(hash_load_check_resize_trigger_size_base& other) + { std::swap(m_size, other.m_size); } + + inline void + set_size(size_type size) + { m_size = size; } + + inline size_type + get_size() const + { return m_size; } + + private: + size_type m_size; + }; + + template<typename Size_Type> + class hash_load_check_resize_trigger_size_base<Size_Type, false> + { + protected: + typedef Size_Type size_type; + + protected: + inline void + swap(hash_load_check_resize_trigger_size_base& other) { } + + inline void + set_size(size_type size) { } + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp new file mode 100644 index 0000000..3328c91 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp @@ -0,0 +1,165 @@ +// -*- C++ -*- + +// Copyright (C) 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_prime_size_policy_imp.hpp + * Contains a resize size policy implementation. + */ + +namespace detail +{ + enum + { + num_distinct_sizes_32_bit = 30, + num_distinct_sizes_64_bit = 62, + num_distinct_sizes = sizeof(std::size_t) != 8 ? + num_distinct_sizes_32_bit : num_distinct_sizes_64_bit, + }; + + // Originally taken from the SGI implementation; acknowledged in the docs. + // Further modified (for 64 bits) from tr1's hashtable. + static const std::size_t g_a_sizes[num_distinct_sizes_64_bit] = + { + /* 0 */ 5ul, + /* 1 */ 11ul, + /* 2 */ 23ul, + /* 3 */ 47ul, + /* 4 */ 97ul, + /* 5 */ 199ul, + /* 6 */ 409ul, + /* 7 */ 823ul, + /* 8 */ 1741ul, + /* 9 */ 3469ul, + /* 10 */ 6949ul, + /* 11 */ 14033ul, + /* 12 */ 28411ul, + /* 13 */ 57557ul, + /* 14 */ 116731ul, + /* 15 */ 236897ul, + /* 16 */ 480881ul, + /* 17 */ 976369ul, + /* 18 */ 1982627ul, + /* 19 */ 4026031ul, + /* 20 */ 8175383ul, + /* 21 */ 16601593ul, + /* 22 */ 33712729ul, + /* 23 */ 68460391ul, + /* 24 */ 139022417ul, + /* 25 */ 282312799ul, + /* 26 */ 573292817ul, + /* 27 */ 1164186217ul, + /* 28 */ 2364114217ul, + /* 29 */ 4294967291ul, + /* 30 */ (std::size_t)8589934583ull, + /* 31 */ (std::size_t)17179869143ull, + /* 32 */ (std::size_t)34359738337ull, + /* 33 */ (std::size_t)68719476731ull, + /* 34 */ (std::size_t)137438953447ull, + /* 35 */ (std::size_t)274877906899ull, + /* 36 */ (std::size_t)549755813881ull, + /* 37 */ (std::size_t)1099511627689ull, + /* 38 */ (std::size_t)2199023255531ull, + /* 39 */ (std::size_t)4398046511093ull, + /* 40 */ (std::size_t)8796093022151ull, + /* 41 */ (std::size_t)17592186044399ull, + /* 42 */ (std::size_t)35184372088777ull, + /* 43 */ (std::size_t)70368744177643ull, + /* 44 */ (std::size_t)140737488355213ull, + /* 45 */ (std::size_t)281474976710597ull, + /* 46 */ (std::size_t)562949953421231ull, + /* 47 */ (std::size_t)1125899906842597ull, + /* 48 */ (std::size_t)2251799813685119ull, + /* 49 */ (std::size_t)4503599627370449ull, + /* 50 */ (std::size_t)9007199254740881ull, + /* 51 */ (std::size_t)18014398509481951ull, + /* 52 */ (std::size_t)36028797018963913ull, + /* 53 */ (std::size_t)72057594037927931ull, + /* 54 */ (std::size_t)144115188075855859ull, + /* 55 */ (std::size_t)288230376151711717ull, + /* 56 */ (std::size_t)576460752303423433ull, + /* 57 */ (std::size_t)1152921504606846883ull, + /* 58 */ (std::size_t)2305843009213693951ull, + /* 59 */ (std::size_t)4611686018427387847ull, + /* 60 */ (std::size_t)9223372036854775783ull, + /* 61 */ (std::size_t)18446744073709551557ull, + }; + +} // namespace detail + +PB_DS_CLASS_T_DEC +inline +PB_DS_CLASS_C_DEC:: +hash_prime_size_policy(size_type n) : m_start_size(n) +{ m_start_size = get_nearest_larger_size(n); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ std::swap(m_start_size, other.m_start_size); } + +PB_DS_CLASS_T_DEC +inline PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_nearest_larger_size(size_type n) const +{ + const std::size_t* const p_upper = std::upper_bound(detail::g_a_sizes, + detail::g_a_sizes + detail::num_distinct_sizes, n); + + if (p_upper == detail::g_a_sizes + detail::num_distinct_sizes) + __throw_resize_error(); + return *p_upper; +} + +PB_DS_CLASS_T_DEC +inline PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_nearest_smaller_size(size_type n) const +{ + const size_t* p_lower = std::lower_bound(detail::g_a_sizes, + detail::g_a_sizes + detail::num_distinct_sizes, n); + + if (*p_lower >= n && p_lower != detail::g_a_sizes) + --p_lower; + if (*p_lower < m_start_size) + return m_start_size; + return *p_lower; +} diff --git a/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp new file mode 100644 index 0000000..b848991 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp @@ -0,0 +1,260 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_standard_resize_policy_imp.hpp + * Contains a resize policy implementation. + */ + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef detail::static_assert_dumclass<sizeof(detail::static_assert<(bool)(E)>)> UNIQUE##static_assert_type + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_standard_resize_policy() +: m_size(Size_Policy::get_nearest_larger_size(1)) +{ trigger_policy_base::notify_externally_resized(m_size); } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_standard_resize_policy(const Size_Policy& r_size_policy) +: Size_Policy(r_size_policy), m_size(Size_Policy::get_nearest_larger_size(1)) +{ trigger_policy_base::notify_externally_resized(m_size); } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_standard_resize_policy(const Size_Policy& r_size_policy, + const Trigger_Policy& r_trigger_policy) +: Size_Policy(r_size_policy), Trigger_Policy(r_trigger_policy), + m_size(Size_Policy::get_nearest_larger_size(1)) +{ trigger_policy_base::notify_externally_resized(m_size); } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~hash_standard_resize_policy() +{ } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + trigger_policy_base::swap(other); + size_policy_base::swap(other); + std::swap(m_size, other.m_size); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_start() +{ trigger_policy_base::notify_find_search_start(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_collision() +{ trigger_policy_base::notify_find_search_collision(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_end() +{ trigger_policy_base::notify_find_search_end(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_start() +{ trigger_policy_base::notify_insert_search_start(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_collision() +{ trigger_policy_base::notify_insert_search_collision(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_end() +{ trigger_policy_base::notify_insert_search_end(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_start() +{ trigger_policy_base::notify_erase_search_start(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_collision() +{ trigger_policy_base::notify_erase_search_collision(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_end() +{ trigger_policy_base::notify_erase_search_end(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_inserted(size_type num_e) +{ trigger_policy_base::notify_inserted(num_e); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erased(size_type num_e) +{ trigger_policy_base::notify_erased(num_e); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_cleared() +{ trigger_policy_base::notify_cleared(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_resize_needed() const +{ return trigger_policy_base::is_resize_needed(); } + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_new_size(size_type size, size_type num_used_e) const +{ + if (trigger_policy_base::is_grow_needed(size, num_used_e)) + return size_policy_base::get_nearest_larger_size(size); + return size_policy_base::get_nearest_smaller_size(size); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type new_size) +{ + trigger_policy_base::notify_resized(new_size); + m_size = new_size; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_actual_size() const +{ + PB_DS_STATIC_ASSERT(access, external_size_access); + return m_size; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize(size_type new_size) +{ + PB_DS_STATIC_ASSERT(access, external_size_access); + size_type actual_size = size_policy_base::get_nearest_larger_size(1); + while (actual_size < new_size) + { + const size_type pot = size_policy_base::get_nearest_larger_size(actual_size); + + if (pot == actual_size && pot < new_size) + __throw_resize_error(); + actual_size = pot; + } + + if (actual_size > 0) + --actual_size; + + const size_type old_size = m_size; + try + { + do_resize(actual_size - 1); + } + catch(insert_error& ) + { + m_size = old_size; + __throw_resize_error(); + } + catch(...) + { + m_size = old_size; + __throw_exception_again; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +do_resize(size_type) +{ + // Do nothing +} + +PB_DS_CLASS_T_DEC +Trigger_Policy& +PB_DS_CLASS_C_DEC:: +get_trigger_policy() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Trigger_Policy& +PB_DS_CLASS_C_DEC:: +get_trigger_policy() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Size_Policy& +PB_DS_CLASS_C_DEC:: +get_size_policy() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Size_Policy& +PB_DS_CLASS_C_DEC:: +get_size_policy() const +{ return *this; } + +#undef PB_DS_STATIC_ASSERT + diff --git a/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_policy.hpp b/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_policy.hpp new file mode 100644 index 0000000..cf7b1fb --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_policy.hpp @@ -0,0 +1,131 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_resize_policy.hpp + * Contains a sample resize policy for hash tables. + */ + +#ifndef PB_DS_SAMPLE_RESIZE_POLICY_HPP +#define PB_DS_SAMPLE_RESIZE_POLICY_HPP + +// A sample resize policy. +class sample_resize_policy +{ +public: + + // Size type. + typedef size_t size_type; + + // Default constructor. + sample_resize_policy(); + + // Copy constructor. + sample_range_hashing(const sample_resize_policy& other); + + // Swaps content. + inline void + swap(sample_resize_policy& other); + +protected: + + // Notifies a search started. + inline void + notify_insert_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_insert_search_collision(); + + // Notifies a search ended. + inline void + notify_insert_search_end(); + + // Notifies a search started. + inline void + notify_find_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_find_search_collision(); + + // Notifies a search ended. + inline void + notify_find_search_end(); + + // Notifies a search started. + inline void + notify_erase_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_erase_search_collision(); + + // Notifies a search ended. + inline void + notify_erase_search_end(); + + // Notifies an element was inserted. + inline void + notify_inserted(size_type num_e); + + // Notifies an element was erased. + inline void + notify_erased(size_type num_e); + + // Notifies the table was cleared. + void + notify_cleared(); + + // Notifies the table was resized to new_size. + void + notify_resized(size_type new_size); + + // Queries whether a resize is needed. + inline bool + is_resize_needed() const; + + // Queries what the new size should be. + size_type + get_new_size(size_type size, size_type num_used_e) const; +}; + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hpp b/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hpp new file mode 100644 index 0000000..db07fbb --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hpp @@ -0,0 +1,145 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_resize_trigger.hpp + * Contains a sample resize trigger policy class. + */ + +#ifndef PB_DS_SAMPLE_RESIZE_TRIGGER_HPP +#define PB_DS_SAMPLE_RESIZE_TRIGGER_HPP + +// A sample resize trigger policy. +class sample_resize_trigger +{ +public: + + // Size type. + typedef size_t size_type; + + // Default constructor. + sample_resize_trigger(); + + // Copy constructor. + sample_range_hashing(const sample_resize_trigger& other); + + // Swaps content. + inline void + swap(sample_resize_trigger& other); + +protected: + + // Notifies a search started. + inline void + notify_insert_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_insert_search_collision(); + + // Notifies a search ended. + inline void + notify_insert_search_end(); + + // Notifies a search started. + inline void + notify_find_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_find_search_collision(); + + // Notifies a search ended. + inline void + notify_find_search_end(); + + // Notifies a search started. + inline void + notify_erase_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_erase_search_collision(); + + // Notifies a search ended. + inline void + notify_erase_search_end(); + + // Notifies an element was inserted. the total number of entries in + // the table is num_entries. + inline void + notify_inserted(size_type num_entries); + + // Notifies an element was erased. + inline void + notify_erased(size_type num_entries); + + // Notifies the table was cleared. + void + notify_cleared(); + + // Notifies the table was resized as a result of this object's + // signifying that a resize is needed. + void + notify_resized(size_type new_size); + + // Notifies the table was resized externally. + void + notify_externally_resized(size_type new_size); + + // Queries whether a resize is needed. + inline bool + is_resize_needed() const; + + // Queries whether a grow is needed. + inline bool + is_grow_needed(size_type size, size_type num_entries) const; + +private: + + // Resizes to new_size. + virtual void + do_resize(size_type new_size); +}; + +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_size_policy.hpp b/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_size_policy.hpp new file mode 100644 index 0000000..b88e703 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_size_policy.hpp @@ -0,0 +1,79 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_size_policy.hpp + * Contains a sample size resize-policy. + */ + +#ifndef PB_DS_SAMPLE_SIZE_POLICY_HPP +#define PB_DS_SAMPLE_SIZE_POLICY_HPP + +// A sample size policy. +class sample_size_policy +{ +public: + + // Size type. + typedef size_t size_type; + + // Default constructor. + sample_size_policy(); + + // Copy constructor. + sample_range_hashing(const sample_size_policy& other); + + // Swaps content. + inline void + swap(sample_size_policy& other); + +protected: + + // Given a __size size, returns a __size that is larger. + inline size_type + get_nearest_larger_size(size_type size) const; + + // Given a __size size, returns a __size that is smaller. + inline size_type + get_nearest_smaller_size(size_type size) const; +}; + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..b05a672 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,108 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn) : + base_type(r_cmp_fn) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : + base_type(r_cmp_fn, r_node_update) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : + base_type(other) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + base_type::swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ base_type::m_p_head->m_special = true; } diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp new file mode 100644 index 0000000..cf7aaa8 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + base_type::assert_valid(); + const node_pointer p_head = base_type::m_p_head; + assert_special_imp(p_head); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_special_imp(const node_pointer p_nd) const +{ + if (p_nd == NULL) + return; + + if (p_nd == base_type::m_p_head) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_special); + assert_special_imp(p_nd->m_p_parent); + return; + } + + _GLIBCXX_DEBUG_ASSERT(!p_nd->m_special); + assert_special_imp(p_nd->m_p_left); + assert_special_imp(p_nd->m_p_right); +} + +#endif + diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp new file mode 100644 index 0000000..26288fb --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp @@ -0,0 +1,163 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + point_iterator it = find(r_key); + if (it == base_type::end()) + return false; + erase(it); + return true; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +erase(iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + if (it == base_type::end()) + return it; + iterator ret_it = it; + ++ret_it; + erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +erase(reverse_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + if (it.m_p_nd == base_type::m_p_head) + return (it); + reverse_iterator ret_it = it; + ++ret_it; + erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + size_type num_ersd = 0; + iterator it = base_type::begin(); + while (it != base_type::end()) + { + if (pred(*it)) + { + ++num_ersd; + it = erase(it); + } + else + ++it; + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_node(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + splay(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); + + node_pointer p_l = p_nd->m_p_left; + node_pointer p_r = p_nd->m_p_right; + + base_type::update_min_max_for_erased_node(p_nd); + base_type::actual_erase_node(p_nd); + if (p_r == NULL) + { + base_type::m_p_head->m_p_parent = p_l; + if (p_l != NULL) + p_l->m_p_parent = base_type::m_p_head; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return; + } + + node_pointer p_target_r = leftmost(p_r); + _GLIBCXX_DEBUG_ASSERT(p_target_r != NULL); + p_r->m_p_parent = base_type::m_p_head; + base_type::m_p_head->m_p_parent = p_r; + splay(p_target_r); + + _GLIBCXX_DEBUG_ONLY(p_target_r->m_p_left = NULL); + _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_parent == this->m_p_head); + _GLIBCXX_DEBUG_ASSERT(this->m_p_head->m_p_parent == p_target_r); + + p_target_r->m_p_left = p_l; + if (p_l != NULL) + p_l->m_p_parent = p_target_r; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + apply_update(p_target_r, (node_update* )this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +leftmost(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + while (p_nd->m_p_left != NULL) + p_nd = p_nd->m_p_left; + return p_nd; +} diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp new file mode 100644 index 0000000..6fdb8f5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp @@ -0,0 +1,105 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + node_pointer p_found = find_imp(r_key); + if (p_found != base_type::m_p_head) + splay(p_found); + return point_iterator(p_found); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + const node_pointer p_found = find_imp(r_key); + if (p_found != base_type::m_p_head) + const_cast<PB_DS_CLASS_C_DEC* >(this)->splay(p_found); + return point_iterator(p_found); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +find_imp(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + node_pointer p_nd = base_type::m_p_head->m_p_parent; + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) + { + if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) + return p_nd; + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + return base_type::m_p_head; +} + +PB_DS_CLASS_T_DEC +inline const typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +find_imp(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + node_pointer p_nd = base_type::m_p_head->m_p_parent; + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) + { + if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) + return p_nd; + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + return base_type::m_p_head; +} diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/info_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/info_fn_imps.hpp new file mode 100644 index 0000000..0d07362 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/info_fn_imps.hpp @@ -0,0 +1,45 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation. + */ diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp new file mode 100644 index 0000000..f4b9f95 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert(const_reference r_value) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + std::pair<point_iterator, bool> ins_pair = insert_leaf_imp(r_value); + ins_pair.first.m_p_nd->m_special = false; + _GLIBCXX_DEBUG_ONLY(assert_valid()); + splay(ins_pair.first.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ins_pair; +} + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_leaf_imp(const_reference r_value) +{ + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + if (base_type::m_size == 0) + return std::make_pair(base_type::insert_imp_empty(r_value), true); + + node_pointer p_nd = base_type::m_p_head->m_p_parent; + node_pointer p_pot = base_type::m_p_head; + + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))) + { + if (!Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_nd->m_value))) + { + return std::make_pair(point_iterator(p_nd), false); + } + p_pot = p_nd; + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + if (p_pot == base_type::m_p_head) + return std::make_pair(base_type::insert_leaf_new(r_value, base_type::m_p_head->m_p_right, false), true); + + _GLIBCXX_DEBUG_ONLY(base_type::check_key_does_not_exist(PB_DS_V2F(r_value))); + + p_nd = p_pot->m_p_left; + if (p_nd == NULL) + return (std::make_pair(base_type::insert_leaf_new(r_value, p_pot, true), true)); + + while (p_nd->m_p_right != NULL) + p_nd = p_nd->m_p_right; + + return std::make_pair(insert_leaf_new(r_value, p_nd, false), true); +} diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/node.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/node.hpp new file mode 100644 index 0000000..d23e931 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/node.hpp @@ -0,0 +1,131 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node.hpp + * Contains an implementation struct for splay_tree_'s node. + */ + +#ifndef PB_DS_SPLAY_TREE_NODE_HPP +#define PB_DS_SPLAY_TREE_NODE_HPP + +namespace pb_ds +{ + namespace detail + { + template<typename Value_Type, class Metadata, class Allocator> + struct splay_tree_node_ + { + public: + typedef Value_Type value_type; + typedef Metadata metadata_type; + + typedef + typename Allocator::template rebind< + splay_tree_node_<Value_Type, Metadata, Allocator> >::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind<metadata_type>::other::reference + metadata_reference; + + typedef + typename Allocator::template rebind<metadata_type>::other::const_reference + const_metadata_reference; + +#ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ + void + trace() const + { std::cout << PB_DS_V2F(m_value) << "(" << m_metadata << ")"; } +#endif + + inline bool + special() const + { return m_special; } + + inline const_metadata_reference + get_metadata() const + { return m_metadata; } + + inline metadata_reference + get_metadata() + { return m_metadata; } + + value_type m_value; + bool m_special; + node_pointer m_p_left; + node_pointer m_p_right; + node_pointer m_p_parent; + metadata_type m_metadata; + }; + + template<typename Value_Type, typename Allocator> + struct splay_tree_node_<Value_Type, null_node_metadata, Allocator> + { + public: + typedef Value_Type value_type; + typedef null_node_metadata metadata_type; + + typedef + typename Allocator::template rebind< + splay_tree_node_<Value_Type, null_node_metadata, Allocator> >::other::pointer + node_pointer; + + inline bool + special() const + { return m_special; } + +#ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ + void + trace() const + { std::cout << PB_DS_V2F(m_value); } +#endif + + node_pointer m_p_left; + node_pointer m_p_right; + node_pointer m_p_parent; + value_type m_value; + bool m_special; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp new file mode 100644 index 0000000..62def3c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp @@ -0,0 +1,289 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file splay_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +splay(node_pointer p_nd) +{ + while (p_nd->m_p_parent != base_type::m_p_head) + { +#ifdef _GLIBCXX_DEBUG + { + node_pointer p_head = base_type::m_p_head; + assert_special_imp(p_head); + } +#endif + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd);) + + if (p_nd->m_p_parent->m_p_parent == base_type::m_p_head) + { + base_type::rotate_parent(p_nd); + _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); + } + else + { + const node_pointer p_parent = p_nd->m_p_parent; + const node_pointer p_grandparent = p_parent->m_p_parent; + +#ifdef _GLIBCXX_DEBUG + const size_type total = + base_type::recursive_count(p_grandparent); + _GLIBCXX_DEBUG_ASSERT(total >= 3); +#endif + + if (p_parent->m_p_left == p_nd && + p_grandparent->m_p_right == p_parent) + splay_zig_zag_left(p_nd, p_parent, p_grandparent); + else if (p_parent->m_p_right == p_nd && + p_grandparent->m_p_left == p_parent) + splay_zig_zag_right(p_nd, p_parent, p_grandparent); + else if (p_parent->m_p_left == p_nd && + p_grandparent->m_p_left == p_parent) + splay_zig_zig_left(p_nd, p_parent, p_grandparent); + else + splay_zig_zig_right(p_nd, p_parent, p_grandparent); + _GLIBCXX_DEBUG_ASSERT(total ==this->recursive_count(p_nd)); + } + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd);) + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zig_zag_left(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_grandparent);) + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && + p_grandparent->m_p_right == p_parent); + + splay_zz_start(p_nd, p_parent, p_grandparent); + + node_pointer p_b = p_nd->m_p_right; + node_pointer p_c = p_nd->m_p_left; + + p_nd->m_p_right = p_parent; + p_parent->m_p_parent = p_nd; + + p_nd->m_p_left = p_grandparent; + p_grandparent->m_p_parent = p_nd; + + p_parent->m_p_left = p_b; + if (p_b != NULL) + p_b->m_p_parent = p_parent; + + p_grandparent->m_p_right = p_c; + if (p_c != NULL) + p_c->m_p_parent = p_grandparent; + + splay_zz_end(p_nd, p_parent, p_grandparent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zig_zag_right(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_grandparent);) + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && + p_grandparent->m_p_left == p_parent); + + splay_zz_start(p_nd, p_parent, p_grandparent); + + node_pointer p_b = p_nd->m_p_left; + node_pointer p_c = p_nd->m_p_right; + + p_nd->m_p_left = p_parent; + p_parent->m_p_parent = p_nd; + + p_nd->m_p_right = p_grandparent; + p_grandparent->m_p_parent = p_nd; + + p_parent->m_p_right = p_b; + if (p_b != NULL) + p_b->m_p_parent = p_parent; + + p_grandparent->m_p_left = p_c; + if (p_c != NULL) + p_c->m_p_parent = p_grandparent; + + splay_zz_end(p_nd, p_parent, p_grandparent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zig_zig_left(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_grandparent);) + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && + p_nd->m_p_parent->m_p_parent->m_p_left == p_nd->m_p_parent); + + splay_zz_start(p_nd, p_parent, p_grandparent); + + node_pointer p_b = p_nd->m_p_right; + node_pointer p_c = p_parent->m_p_right; + + p_nd->m_p_right = p_parent; + p_parent->m_p_parent = p_nd; + + p_parent->m_p_right = p_grandparent; + p_grandparent->m_p_parent = p_parent; + + p_parent->m_p_left = p_b; + if (p_b != NULL) + p_b->m_p_parent = p_parent; + + p_grandparent->m_p_left = p_c; + if (p_c != NULL) + p_c->m_p_parent = p_grandparent; + + splay_zz_end(p_nd, p_parent, p_grandparent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zig_zig_right(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_grandparent);) + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && + p_nd->m_p_parent->m_p_parent->m_p_right == p_nd->m_p_parent); + + splay_zz_start(p_nd, p_parent, p_grandparent); + + node_pointer p_b = p_nd->m_p_left; + node_pointer p_c = p_parent->m_p_left; + + p_nd->m_p_left = p_parent; + p_parent->m_p_parent = p_nd; + + p_parent->m_p_left = p_grandparent; + p_grandparent->m_p_parent = p_parent; + + p_parent->m_p_right = p_b; + if (p_b != NULL) + p_b->m_p_parent = p_parent; + + p_grandparent->m_p_right = p_c; + if (p_c != NULL) + p_c->m_p_parent = p_grandparent; + + base_type::update_to_top(p_grandparent, (node_update* )this); + splay_zz_end(p_nd, p_parent, p_grandparent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zz_start(node_pointer p_nd, +#ifdef _GLIBCXX_DEBUG + node_pointer p_parent, +#else + node_pointer /*p_parent*/, +#endif + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_parent != NULL); + _GLIBCXX_DEBUG_ASSERT(p_grandparent != NULL); + + const bool grandparent_head = p_grandparent->m_p_parent == base_type::m_p_head; + + if (grandparent_head) + { + base_type::m_p_head->m_p_parent = base_type::m_p_head->m_p_parent; + p_nd->m_p_parent = base_type::m_p_head; + return; + } + + node_pointer p_greatgrandparent = p_grandparent->m_p_parent; + + p_nd->m_p_parent = p_greatgrandparent; + + if (p_grandparent == p_greatgrandparent->m_p_left) + p_greatgrandparent->m_p_left = p_nd; + else + p_greatgrandparent->m_p_right = p_nd; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zz_end(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + if (p_nd->m_p_parent == base_type::m_p_head) + base_type::m_p_head->m_p_parent = p_nd; + + apply_update(p_grandparent, (node_update* )this); + apply_update(p_parent, (node_update* )this); + apply_update(p_nd, (node_update* )this); + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd);) +} + diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_tree_.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_tree_.hpp new file mode 100644 index 0000000..bf90525 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_tree_.hpp @@ -0,0 +1,304 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file splay_tree_.hpp + * Contains an implementation class for splay_tree_. + */ +/* + * This implementation uses an idea from the SGI STL (using a "header" node + * which is needed for efficient iteration). Following is the SGI STL + * copyright. + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + */ + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#ifndef PB_DS_BIN_SEARCH_TREE_HPP__DATA_TRUE_INDICATOR +#define PB_DS_BIN_SEARCH_TREE_HPP__DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> +#endif +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#ifndef PB_DS_BIN_SEARCH_TREE_HPP__DATA_FALSE_INDICATOR +#define PB_DS_BIN_SEARCH_TREE_HPP__DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> +#endif +#endif + +#include <utility> +#include <vector> +#include <assert.h> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Cmp_Fn, \ + typename Node_And_It_Traits, typename Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME splay_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME splay_tree_no_data_ +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_BASE_CLASS_NAME bin_search_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_BASE_CLASS_NAME bin_search_tree_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#define PB_DS_BASE_C_DEC \ + PB_DS_BASE_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + + // $p14y 7r33 7481. + template<typename Key, typename Mapped, typename Cmp_Fn, + typename Node_And_It_Traits, typename Allocator> + class PB_DS_CLASS_NAME : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + typedef typename base_type::node_pointer node_pointer; + + public: + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef Cmp_Fn cmp_fn; + typedef typename base_type::key_type key_type; + typedef typename base_type::key_pointer key_pointer; + typedef typename base_type::const_key_pointer const_key_pointer; + typedef typename base_type::key_reference key_reference; + typedef typename base_type::const_key_reference const_key_reference; + typedef typename base_type::mapped_type mapped_type; + typedef typename base_type::mapped_pointer mapped_pointer; + typedef typename base_type::const_mapped_pointer const_mapped_pointer; + typedef typename base_type::mapped_reference mapped_reference; + typedef typename base_type::const_mapped_reference const_mapped_reference; + typedef typename base_type::value_type value_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_iterator const_point_iterator; + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::reverse_iterator reverse_iterator; + typedef typename base_type::const_reverse_iterator const_reverse_iterator; + typedef typename base_type::node_update node_update; + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const Cmp_Fn&); + + PB_DS_CLASS_NAME(const Cmp_Fn&, const node_update&); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + void + swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_range(It, It); + + void + initialize(); + + inline std::pair<point_iterator, bool> + insert(const_reference r_value); + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + std::pair<point_iterator, bool> ins_pair = + insert_leaf_imp(value_type(r_key, mapped_type())); + + ins_pair.first.m_p_nd->m_special = false; + _GLIBCXX_DEBUG_ONLY(base_type::assert_valid()); + splay(ins_pair.first.m_p_nd); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return ins_pair.first.m_p_nd->m_value.second; +#else + insert(r_key); + return base_type::s_null_mapped; +#endif + } + + inline point_iterator + find(const_key_reference); + + inline const_point_iterator + find(const_key_reference) const; + + inline bool + erase(const_key_reference); + + inline iterator + erase(iterator it); + + inline reverse_iterator + erase(reverse_iterator); + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + join(PB_DS_CLASS_C_DEC&); + + void + split(const_key_reference, PB_DS_CLASS_C_DEC&); + + private: + inline std::pair<point_iterator, bool> + insert_leaf_imp(const_reference); + + inline node_pointer + find_imp(const_key_reference); + + inline const node_pointer + find_imp(const_key_reference) const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_special_imp(const node_pointer) const; +#endif + + void + splay(node_pointer); + + inline void + splay_zig_zag_left(node_pointer, node_pointer, node_pointer); + + inline void + splay_zig_zag_right(node_pointer, node_pointer, node_pointer); + + inline void + splay_zig_zig_left(node_pointer, node_pointer, node_pointer); + + inline void + splay_zig_zig_right(node_pointer, node_pointer, node_pointer); + + inline void + splay_zz_start(node_pointer, node_pointer, node_pointer); + + inline void + splay_zz_end(node_pointer, node_pointer, node_pointer); + + inline node_pointer + leftmost(node_pointer); + + void + erase_node(node_pointer); + }; + +#include <ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_BASE_CLASS_NAME +#undef PB_DS_BASE_C_DEC +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S + } // namespace detail +} // namespace pb_ds + diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp new file mode 100644 index 0000000..c752f71 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp @@ -0,0 +1,118 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (base_type::join_prep(other) == false) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + node_pointer p_target_r = other.leftmost(other.m_p_head); + _GLIBCXX_DEBUG_ASSERT(p_target_r != NULL); + other.splay(p_target_r); + + _GLIBCXX_DEBUG_ASSERT(p_target_r == other.m_p_head->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left == NULL); + + p_target_r->m_p_left = base_type::m_p_head->m_p_parent; + + _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left != NULL); + p_target_r->m_p_left->m_p_parent = p_target_r; + + base_type::m_p_head->m_p_parent = p_target_r; + p_target_r->m_p_parent = base_type::m_p_head; + apply_update(p_target_r, (node_update* )this); + + base_type::join_finish(other); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + + if (base_type::split_prep(r_key, other) == false) + { + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + return; + } + + node_pointer p_upper_bound = upper_bound(r_key).m_p_nd; + _GLIBCXX_DEBUG_ASSERT(p_upper_bound != NULL); + + splay(p_upper_bound); + _GLIBCXX_DEBUG_ASSERT(p_upper_bound->m_p_parent == this->m_p_head); + + node_pointer p_new_root = p_upper_bound->m_p_left; + _GLIBCXX_DEBUG_ASSERT(p_new_root != NULL); + + base_type::m_p_head->m_p_parent = p_new_root; + p_new_root->m_p_parent = base_type::m_p_head; + other.m_p_head->m_p_parent = p_upper_bound; + p_upper_bound->m_p_parent = other.m_p_head; + p_upper_bound->m_p_left = NULL; + apply_update(p_upper_bound, (node_update* )this); + base_type::split_finish(other); + + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/splay_tree_/traits.hpp b/libstdc++/include/ext/pb_ds/detail/splay_tree_/traits.hpp new file mode 100644 index 0000000..a758ef9 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/splay_tree_/traits.hpp @@ -0,0 +1,119 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation for splay_tree_. + */ + +#ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/splay_tree_/node.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Key, + typename Mapped, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + splay_tree_tag, + Allocator> : public bin_search_tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + splay_tree_node_< + typename types_traits< + Key, + Mapped, + Allocator, + false>::value_type, + typename tree_node_metadata_selector< + Key, + Mapped, + Cmp_Fn, + Node_Update, + Allocator>::type, + Allocator>, + Allocator> + { }; + + template<typename Key, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits<Key, null_mapped_type, Cmp_Fn, Node_Update, + splay_tree_tag, Allocator> + : public bin_search_tree_traits<Key, null_mapped_type, Cmp_Fn, + Node_Update, + splay_tree_node_<typename types_traits<Key, null_mapped_type, Allocator, false>::value_type, + typename tree_node_metadata_selector< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + Allocator>::type, + Allocator>, + Allocator> + { }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/standard_policies.hpp b/libstdc++/include/ext/pb_ds/detail/standard_policies.hpp new file mode 100644 index 0000000..000e3a4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/standard_policies.hpp @@ -0,0 +1,163 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file standard_policies.hpp + * Contains standard policies for containers. + */ + +#ifndef PB_DS_STANDARD_POLICIES_HPP +#define PB_DS_STANDARD_POLICIES_HPP + +#include <memory> +#include <ext/pb_ds/hash_policy.hpp> +#include <ext/pb_ds/list_update_policy.hpp> +#include <ext/pb_ds/tree_policy.hpp> +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> +#include <ext/pb_ds/trie_policy.hpp> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/hash_map> + +namespace pb_ds +{ + namespace detail + { + template<typename Key> + struct default_hash_fn + { + typedef __gnu_cxx::hash< Key> type; + }; + + template<typename Key> + struct default_eq_fn + { + typedef std::equal_to< Key> type; + }; + + enum + { + default_store_hash = false + }; + + struct default_comb_hash_fn + { + typedef pb_ds::direct_mask_range_hashing<> type; + }; + + template<typename Comb_Hash_Fn> + struct default_resize_policy + { + private: + typedef typename Comb_Hash_Fn::size_type size_type; + + typedef + typename __conditional_type< + is_same< + pb_ds::direct_mask_range_hashing< + size_type>, + Comb_Hash_Fn>::value, + pb_ds::hash_exponential_size_policy< + size_type>, + pb_ds::hash_prime_size_policy>::__type + size_policy_type; + + public: + typedef + pb_ds::hash_standard_resize_policy< + size_policy_type, + pb_ds::hash_load_check_resize_trigger< + false, + size_type>, + false, + size_type> + type; + }; + + struct default_update_policy + { + typedef pb_ds::move_to_front_lu_policy<> type; + }; + + template<typename Comb_Probe_Fn> + struct default_probe_fn + { + private: + typedef typename Comb_Probe_Fn::size_type size_type; + + public: + typedef + typename __conditional_type< + is_same< + pb_ds::direct_mask_range_hashing<size_t>, + Comb_Probe_Fn>::value, + pb_ds::linear_probe_fn< + size_type>, + pb_ds::quadratic_probe_fn< + size_type> >::__type + type; + }; + + template<typename Key> + struct default_trie_e_access_traits; + + template<typename Char, class Char_Traits> + struct default_trie_e_access_traits< + std::basic_string< + Char, + Char_Traits, + std::allocator< + char> > > + { + typedef + pb_ds::string_trie_e_access_traits< + std::basic_string< + Char, + Char_Traits, + std::allocator< + char> > > + type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_STANDARD_POLICIES_HPP + diff --git a/libstdc++/include/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 0000000..1b0c6e5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,112 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + push(*(first_it++)); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +thin_heap_() : + m_p_max(NULL) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +thin_heap_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn), + m_p_max(NULL) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +thin_heap_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other) +{ + initialize(); + m_p_max = base_type::m_p_root; + for (node_pointer p_nd = base_type::m_p_root; p_nd != NULL; p_nd = p_nd->m_p_next_sibling) + if (Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) + m_p_max = p_nd; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + base_type::swap(other); + std::swap(m_p_max, other.m_p_max); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~thin_heap_() +{ } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ std::fill(m_a_aux, m_a_aux + max_rank, static_cast<node_pointer>(NULL)); } + diff --git a/libstdc++/include/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp new file mode 100644 index 0000000..310907d --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp @@ -0,0 +1,118 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + base_type::assert_valid(); + assert_node_consistent(base_type::m_p_root, true); + assert_max(); + assert_aux_null(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_aux_null() const +{ + for (size_type i = 0; i < max_rank; ++i) + _GLIBCXX_DEBUG_ASSERT(m_a_aux[i] == NULL); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_max() const +{ + if (m_p_max == NULL) + { + _GLIBCXX_DEBUG_ASSERT(base_type::empty()); + return; + } + + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + _GLIBCXX_DEBUG_ASSERT(base_type::parent(m_p_max) == NULL); + _GLIBCXX_DEBUG_ASSERT(m_p_max->m_p_prev_or_parent == NULL); + for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const_node_pointer p_nd, bool root) const +{ + base_type::assert_node_consistent(p_nd, root); + if (p_nd == NULL) + return; + + assert_node_consistent(p_nd->m_p_next_sibling, root); + assert_node_consistent(p_nd->m_p_l_child, false); + if (!root) + { + if (p_nd->m_metadata == 0) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling == NULL); + else + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata + 1); + } + + if (p_nd->m_p_l_child != NULL) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child->m_metadata + 1 == base_type::degree(p_nd)); + + const bool unmarked_valid =(p_nd->m_p_l_child == NULL&& p_nd->m_metadata == 0) ||(p_nd->m_p_l_child != NULL&& p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 1); + + const bool marked_valid =(p_nd->m_p_l_child == NULL&& p_nd->m_metadata == 1) ||(p_nd->m_p_l_child != NULL&& p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 2); + + _GLIBCXX_DEBUG_ASSERT(unmarked_valid || marked_valid); + if (root) + _GLIBCXX_DEBUG_ASSERT(unmarked_valid); +} + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp new file mode 100644 index 0000000..9f409df --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp @@ -0,0 +1,302 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +pop() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + _GLIBCXX_DEBUG_ASSERT(m_p_max != NULL); + + node_pointer p_nd = m_p_max; + + remove_max_node(); + + base_type::actual_erase_node(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +remove_max_node() +{ + to_aux_except_max(); + + make_from_aux(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +to_aux_except_max() +{ + node_pointer p_add = base_type::m_p_root; + + while (p_add != m_p_max) + { + node_pointer p_next_add = p_add->m_p_next_sibling; + + add_to_aux(p_add); + + p_add = p_next_add; + } + + p_add = m_p_max->m_p_l_child; + + while (p_add != NULL) + { + node_pointer p_next_add = p_add->m_p_next_sibling; + + p_add->m_metadata = p_add->m_p_l_child == NULL? + 0 : + p_add->m_p_l_child->m_metadata + 1; + + add_to_aux(p_add); + + p_add = p_next_add; + } + + p_add = m_p_max->m_p_next_sibling; + + while (p_add != NULL) + { + node_pointer p_next_add = p_add->m_p_next_sibling; + + add_to_aux(p_add); + + p_add = p_next_add; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +add_to_aux(node_pointer p_nd) +{ + size_type r = p_nd->m_metadata; + + while (m_a_aux[r] != NULL) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); + + if (Cmp_Fn::operator()(m_a_aux[r]->m_value, p_nd->m_value)) + make_child_of(m_a_aux[r], p_nd); + else + { + make_child_of(p_nd, m_a_aux[r]); + + p_nd = m_a_aux[r]; + } + + m_a_aux[r] = NULL; + + ++r; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); + + m_a_aux[r] = p_nd; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_child_of(node_pointer p_nd, node_pointer p_new_parent) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_new_parent->m_metadata); + _GLIBCXX_DEBUG_ASSERT(m_a_aux[p_nd->m_metadata] == p_nd || + m_a_aux[p_nd->m_metadata] == p_new_parent); + + ++p_new_parent->m_metadata; + + base_type::make_child_of(p_nd, p_new_parent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_from_aux() +{ + base_type::m_p_root = m_p_max = NULL; + + const size_type rnk_bnd = rank_bound(); + + size_type i = 0; + + while (i < rnk_bnd) + { + if (m_a_aux[i] != NULL) + { + make_root_and_link(m_a_aux[i]); + + m_a_aux[i] = NULL; + } + + ++i; + } + + _GLIBCXX_DEBUG_ONLY(assert_aux_null();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +remove_node(node_pointer p_nd) +{ + node_pointer p_parent = p_nd; + while (base_type::parent(p_parent) != NULL) + p_parent = base_type::parent(p_parent); + + base_type::bubble_to_top(p_nd); + + m_p_max = p_nd; + + node_pointer p_fix = base_type::m_p_root; + while (p_fix != NULL&& p_fix->m_p_next_sibling != p_parent) + p_fix = p_fix->m_p_next_sibling; + + if (p_fix != NULL) + p_fix->m_p_next_sibling = p_nd; + + remove_max_node(); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +clear() +{ + base_type::clear(); + + m_p_max = NULL; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + node_pointer p_nd = it.m_p_nd; + + remove_node(p_nd); + + base_type::actual_erase_node(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return 0; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + size_type ersd = 0; + + while (p_out != NULL) + { + ++ersd; + + node_pointer p_next = p_out->m_p_next_sibling; + + base_type::actual_erase_node(p_out); + + p_out = p_next; + } + + node_pointer p_cur = base_type::m_p_root; + + m_p_max = base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + make_root_and_link(p_cur); + + p_cur = p_next; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return ersd; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +rank_bound() +{ + const std::size_t* const p_upper = + std::upper_bound( g_a_rank_bounds, g_a_rank_bounds + num_distinct_rank_bounds, base_type::m_size); + + if (p_upper == g_a_rank_bounds + num_distinct_rank_bounds) + return max_rank; + + return (p_upper - g_a_rank_bounds); +} + diff --git a/libstdc++/include/ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp new file mode 100644 index 0000000..256bd1c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp @@ -0,0 +1,57 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + _GLIBCXX_DEBUG_ASSERT(m_p_max != NULL); + return m_p_max->m_value; +} diff --git a/libstdc++/include/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp new file mode 100644 index 0000000..451793f --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp @@ -0,0 +1,332 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + node_pointer p_nd = base_type::get_new_node_for_insert(r_val); + + p_nd->m_metadata = 0; + + p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = NULL; + + if (base_type::m_p_root == NULL) + { + p_nd->m_p_next_sibling = NULL; + + m_p_max = base_type::m_p_root = p_nd; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(p_nd); + } + + p_nd->m_p_next_sibling = base_type::m_p_root; + + base_type::m_p_root->m_p_prev_or_parent = NULL; + + base_type::m_p_root = p_nd; + + update_max(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(p_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_root(node_pointer p_nd) +{ + p_nd->m_metadata = + p_nd->m_p_l_child == NULL? + 0 : + 1 + p_nd->m_p_l_child->m_metadata; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_root_and_link(node_pointer p_nd) +{ + make_root(p_nd); + + p_nd->m_p_prev_or_parent = NULL; + + p_nd->m_p_next_sibling = base_type::m_p_root; + + if (base_type::m_p_root != NULL) + base_type::m_p_root->m_p_prev_or_parent = NULL; + + base_type::m_p_root = p_nd; + + update_max(p_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix(node_pointer p_y) +{ + while (true) + { + if (p_y->m_p_prev_or_parent == NULL) + { + fix_root(p_y); + + return; + } + else if (p_y->m_metadata == 1&& p_y->m_p_next_sibling == NULL) + { + if (p_y->m_p_l_child != NULL) + { + fix_sibling_rank_1_unmarked(p_y); + + return; + } + + fix_sibling_rank_1_marked(p_y); + + p_y = p_y->m_p_prev_or_parent; + } + else if (p_y->m_metadata > p_y->m_p_next_sibling->m_metadata + 1) + { + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child != NULL); + + if (p_y->m_metadata != p_y->m_p_l_child->m_metadata + 2) + { + fix_sibling_general_unmarked(p_y); + + return; + } + + fix_sibling_general_marked(p_y); + + p_y = p_y->m_p_prev_or_parent; + } + else if ((p_y->m_p_l_child == NULL&& + p_y->m_metadata == 2) ||(p_y->m_p_l_child != NULL&& + p_y->m_metadata == p_y->m_p_l_child->m_metadata + 3)) + { + node_pointer p_z = p_y->m_p_prev_or_parent; + + fix_child(p_y); + + p_y = p_z; + } + else + return; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_root(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent == NULL); + + make_root(p_y); + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, true);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_sibling_rank_1_unmarked(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + + _GLIBCXX_DEBUG_ONLY(node_pointer p_w = p_y->m_p_l_child;) + _GLIBCXX_DEBUG_ASSERT(p_w != NULL); + _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling == NULL); + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_next_sibling == NULL); + + p_y->m_p_next_sibling = p_y->m_p_l_child; + + p_y->m_p_next_sibling->m_p_prev_or_parent = p_y; + + p_y->m_p_l_child = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, false);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_sibling_rank_1_marked(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child == NULL); + + p_y->m_metadata = 0; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, false);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_sibling_general_unmarked(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + + node_pointer p_w = p_y->m_p_l_child; + _GLIBCXX_DEBUG_ASSERT(p_w != NULL); + _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != NULL); + + p_y->m_p_l_child = p_w->m_p_next_sibling; + p_w->m_p_next_sibling->m_p_prev_or_parent = p_y; + + p_w->m_p_next_sibling = p_y->m_p_next_sibling; + _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != NULL); + p_w->m_p_next_sibling->m_p_prev_or_parent = p_w; + + p_y->m_p_next_sibling = p_w; + p_w->m_p_prev_or_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, false);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_sibling_general_marked(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + + --p_y->m_metadata; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, false);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_child(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + + if (p_y->m_p_next_sibling != NULL) + p_y->m_p_next_sibling->m_p_prev_or_parent = p_y->m_p_prev_or_parent; + + if (p_y->m_p_prev_or_parent->m_p_l_child == p_y) + p_y->m_p_prev_or_parent->m_p_l_child = p_y->m_p_next_sibling; + else + p_y->m_p_prev_or_parent->m_p_next_sibling = p_y->m_p_next_sibling; + + make_root_and_link(p_y); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + node_pointer p_nd = it.m_p_nd; + + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + + const bool smaller = Cmp_Fn::operator()(r_new_val, p_nd->m_value); + + p_nd->m_value = r_new_val; + + if (smaller) + { + remove_node(p_nd); + + p_nd->m_p_l_child = NULL; + + make_root_and_link(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return; + } + + if (p_nd->m_p_prev_or_parent == NULL) + { + update_max(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return; + } + + node_pointer p_y = p_nd->m_p_prev_or_parent; + _GLIBCXX_DEBUG_ASSERT(p_y != NULL); + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_y; + + if (p_y->m_p_l_child == p_nd) + p_y->m_p_l_child = p_nd->m_p_next_sibling; + else + p_y->m_p_next_sibling = p_nd->m_p_next_sibling; + + fix(p_y); + + make_root_and_link(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_max(node_pointer p_nd) +{ + if (m_p_max == NULL || Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) + m_p_max = p_nd; +} + diff --git a/libstdc++/include/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp new file mode 100644 index 0000000..a24d0aa --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp @@ -0,0 +1,132 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + other.clear(); + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + return; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + while (p_out != NULL) + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); + --base_type::m_size; + + ++other.m_size; + + node_pointer p_next = p_out->m_p_next_sibling; + + other.make_root_and_link(p_out); + + p_out = p_next; + } + + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + node_pointer p_cur = base_type::m_p_root; + + m_p_max = NULL; + + base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + make_root_and_link(p_cur); + + p_cur = p_next; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + node_pointer p_other = other.m_p_root; + + while (p_other != NULL) + { + node_pointer p_next = p_other->m_p_next_sibling; + + make_root_and_link(p_other); + + p_other = p_next; + } + + base_type::m_size += other.m_size; + + other.m_p_root = NULL; + other.m_size = 0; + other.m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } diff --git a/libstdc++/include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp b/libstdc++/include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp new file mode 100644 index 0000000..6d1f4ba --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp @@ -0,0 +1,357 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file thin_heap_.hpp + * Contains an implementation class for a thin heap. + */ + +#ifndef PB_DS_THIN_HEAP_HPP +#define PB_DS_THIN_HEAP_HPP + +/* + * Thin heaps. + * Tarjan and Kaplan. + */ + +#include <algorithm> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + thin_heap_<Value_Type, Cmp_Fn, Allocator> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_<Value_Type, Cmp_Fn, \ + typename Allocator::size_type, Allocator, true> +#else +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_<Value_Type, Cmp_Fn, \ + typename Allocator::size_type, Allocator> +#endif + + /** + * class description = "t|-|i|\| h34p"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class thin_heap_ : public PB_DS_BASE_C_DEC + { + + private: + typedef PB_DS_BASE_C_DEC base_type; + + protected: + typedef typename base_type::node node; + + typedef typename base_type::node_pointer node_pointer; + + typedef typename base_type::const_node_pointer const_node_pointer; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + typename PB_DS_BASE_C_DEC::const_point_iterator + const_point_iterator; + + typedef typename PB_DS_BASE_C_DEC::point_iterator point_iterator; + + typedef typename PB_DS_BASE_C_DEC::const_iterator const_iterator; + + typedef typename PB_DS_BASE_C_DEC::iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + public: + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline const_reference + top() const; + + void + pop(); + + void + erase(point_iterator it); + + inline void + clear(); + + template<typename Pred> + size_type + erase_if(Pred pred); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + + protected: + + thin_heap_(); + + thin_heap_(const Cmp_Fn& r_cmp_fn); + + thin_heap_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~thin_heap_(); + + template<typename It> + void + copy_from_range(It first_it, It last_it); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_max() const; +#endif + +#ifdef PB_DS_THIN_HEAP_TRACE_ + void + trace() const; +#endif + + private: + enum + { + max_rank = (sizeof(size_type) << 4) + 2 + }; + + private: + + void + initialize(); + + inline void + update_max(node_pointer p_nd); + + inline void + fix(node_pointer p_nd); + + inline void + fix_root(node_pointer p_y); + + inline void + fix_sibling_rank_1_unmarked(node_pointer p_y); + + inline void + fix_sibling_rank_1_marked(node_pointer p_y); + + inline void + fix_sibling_general_unmarked(node_pointer p_y); + + inline void + fix_sibling_general_marked(node_pointer p_y); + + inline void + fix_child(node_pointer p_y); + + inline static void + make_root(node_pointer p_nd); + + inline void + make_root_and_link(node_pointer p_nd); + + inline void + remove_max_node(); + + void + to_aux_except_max(); + + inline void + add_to_aux(node_pointer p_nd); + + inline void + make_from_aux(); + + inline size_type + rank_bound(); + + inline void + make_child_of(node_pointer p_nd, node_pointer p_new_parent); + + inline void + remove_node(node_pointer p_nd); + + inline node_pointer + join(node_pointer p_lhs, node_pointer p_rhs) const; + +#ifdef _GLIBCXX_DEBUG + void + assert_node_consistent(const_node_pointer p_nd, bool root) const; + + void + assert_aux_null() const; +#endif + + private: + node_pointer m_p_max; + + node_pointer m_a_aux[max_rank]; + }; + + enum + { + num_distinct_rank_bounds = 48 + }; + + // Taken from the SGI implementation; acknowledged in the docs. + static const std::size_t g_a_rank_bounds[num_distinct_rank_bounds] = + { + /* Dealing cards... */ + /* 0 */ 0ul, + /* 1 */ 1ul, + /* 2 */ 1ul, + /* 3 */ 2ul, + /* 4 */ 4ul, + /* 5 */ 6ul, + /* 6 */ 11ul, + /* 7 */ 17ul, + /* 8 */ 29ul, + /* 9 */ 46ul, + /* 10 */ 76ul, + /* 11 */ 122ul, + /* 12 */ 199ul, + /* 13 */ 321ul, + /* 14 */ 521ul, + /* 15 */ 842ul, + /* 16 */ 1364ul, + /* 17 */ 2206ul, + /* 18 */ 3571ul, + /* 19 */ 5777ul, + /* 20 */ 9349ul, + /* 21 */ 15126ul, + /* 22 */ 24476ul, + /* 23 */ 39602ul, + /* 24 */ 64079ul, + /* 25 */ 103681ul, + /* 26 */ 167761ul, + /* 27 */ 271442ul, + /* 28 */ 439204ul, + /* 29 */ 710646ul, + /* 30 */ 1149851ul, + /* 31 */ 1860497ul, + /* 32 */ 3010349ul, + /* 33 */ 4870846ul, + /* 34 */ 7881196ul, + /* 35 */ 12752042ul, + /* 36 */ 20633239ul, + /* 37 */ 33385282ul, + /* 38 */ 54018521ul, + /* 39 */ 87403803ul, + /* 40 */ 141422324ul, + /* 41 */ 228826127ul, + /* 42 */ 370248451ul, + /* 43 */ 599074578ul, + /* 44 */ 969323029ul, + /* 45 */ 1568397607ul, + /* 46 */ 2537720636ul, + /* 47 */ 4106118243ul + /* Pot's good, let's play */ + }; + +#include <ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp b/libstdc++/include/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp new file mode 100644 index 0000000..a4f9c87 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +#ifdef PB_DS_THIN_HEAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << std::endl; + + std::cerr << "m_p_max " << m_p_max << std::endl; + + base_type::trace(); +} + +#endif // #ifdef PB_DS_THIN_HEAP_TRACE_ diff --git a/libstdc++/include/ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp b/libstdc++/include/ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp new file mode 100644 index 0000000..3fd7dc9 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp @@ -0,0 +1,122 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_metadata_selector.hpp + * Contains an implementation class for trees. + */ + +#ifndef PB_DS_TREE_NODE_METADATA_SELECTOR_HPP +#define PB_DS_TREE_NODE_METADATA_SELECTOR_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Node_Update, bool Null> + struct tree_metadata_helper + { + typedef typename Node_Update::metadata_type type; + }; + + template<typename Node_Update> + struct tree_metadata_helper< + Node_Update, + true> + { + typedef null_node_metadata type; + }; + + template<typename Key, + typename Data, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Const_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_node_metadata_selector + { + private: + typedef + dumconst_node_iterator< + Key, + Data, + Allocator> + dumconst_node_it; + + enum + { + null_update = + is_same< + Node_Update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator>, + null_tree_node_update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator> >::value + }; + + public: + typedef + typename tree_metadata_helper< + Node_Update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator>, + null_update>::type + type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_TREE_NODE_METADATA_SELECTOR_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/tree_policy/null_node_update_imp.hpp b/libstdc++/include/ext/pb_ds/detail/tree_policy/null_node_update_imp.hpp new file mode 100644 index 0000000..d9c5967 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/tree_policy/null_node_update_imp.hpp @@ -0,0 +1,56 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file null_node_update_imp.hpp + * Contains an implementation of null_node_update. + */ + +PB_DS_CLASS_T_DEC +template<typename Const_Node_Iterator_, + typename Node_Iterator_, + class Cmp_Fn_, + typename Allocator_> +inline void +PB_DS_CLASS_C_DEC:: +swap(null_tree_node_update< Const_Node_Iterator_, Node_Iterator_, Cmp_Fn_, Allocator_>& /*other*/) +{ } + diff --git a/libstdc++/include/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp b/libstdc++/include/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp new file mode 100644 index 0000000..85f4d16 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp @@ -0,0 +1,147 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file order_statistics_imp.hpp + * Contains forward declarations for order_statistics_key + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +find_by_order(size_type order) +{ + node_iterator it = node_begin(); + + node_iterator end_it = node_end(); + + while (it != end_it) + { + node_iterator l_it = it.get_l_child(); + + const size_type o = (l_it == end_it)? + 0 : + l_it.get_metadata(); + + if (order == o) + return (*it); + else if (order < o) + it = l_it; + else + { + order -= o + 1; + + it = it.get_r_child(); + } + } + + return (PB_DS_BASE_C_DEC::end_iterator()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +find_by_order(size_type order) const +{ + return (const_cast<PB_DS_CLASS_C_DEC* >(this)->find_by_order(order)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +order_of_key(const_key_reference r_key) const +{ + const_node_iterator it = node_begin(); + + const_node_iterator end_it = node_end(); + + const cmp_fn& r_cmp_fn = + const_cast<PB_DS_CLASS_C_DEC* >(this)->get_cmp_fn(); + + size_type ord = 0; + + while (it != end_it) + { + const_node_iterator l_it = it.get_l_child(); + + if (r_cmp_fn(r_key, extract_key(*(*it)))) + it = l_it; + else if (r_cmp_fn(extract_key(*(*it)), r_key)) + { + + ord += (l_it == end_it)? + 1 : + 1 + l_it.get_metadata(); + + it = it.get_r_child(); + } + else + { + ord += (l_it == end_it)? + 0 : + l_it.get_metadata(); + + it = end_it; + } + } + + return (ord); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +operator()(node_iterator node_it, const_node_iterator end_nd_it) const +{ + node_iterator l_child_it = node_it.get_l_child(); + const size_type l_rank =(l_child_it == end_nd_it)? 0 : l_child_it.get_metadata(); + + node_iterator r_child_it = node_it.get_r_child(); + const size_type r_rank =(r_child_it == end_nd_it)? 0 : r_child_it.get_metadata(); + + const_cast<metadata_reference>(node_it.get_metadata())= + 1 + l_rank + r_rank; +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~tree_order_statistics_node_update() +{ } diff --git a/libstdc++/include/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hpp b/libstdc++/include/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hpp new file mode 100644 index 0000000..5b7d7c5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_tree_node_update.hpp + * Contains a samle node update functor. + */ + +#ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP +#define PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP + +// A sample node updator. +template<typename Const_Node_Iterator, + + class Node_Iterator, + + class Cmp_Fn, + + class Allocator + > +class sample_tree_node_update +{ + +public: + + // Metadata type. + typedef size_t metadata_type; + +protected: + + // Default constructor. + sample_tree_node_update(); + + // Updates the rank of a node through a node_iterator node_it; end_nd_it is the end node iterator. + inline void + operator()(node_iterator node_it, const_node_iterator end_nd_it) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/tree_trace_base.hpp b/libstdc++/include/ext/pb_ds/detail/tree_trace_base.hpp new file mode 100644 index 0000000..791f2fc --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/tree_trace_base.hpp @@ -0,0 +1,215 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file tree_trace_base.hpp + * Contains tree-related policies. + */ + +#ifndef PB_DS_TREE_TRACE_BASE_HPP +#define PB_DS_TREE_TRACE_BASE_HPP + +#ifdef PB_DS_TREE_TRACE + +#include <ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp> +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> + +namespace pb_ds +{ + + namespace detail + { + +#ifdef PB_DS_TREE_TRACE + +#define PB_DS_CLASS_T_DEC \ + template< \ + class Const_Node_Iterator, \ + class Node_Iterator, \ + class Cmp_Fn, \ + bool Node_Based, \ + class Allocator> + +#define PB_DS_CLASS_C_DEC \ + tree_trace_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + Cmp_Fn, \ + Node_Based, \ + Allocator> + +#define PB_DS_BASE_C_DEC \ + basic_tree_policy_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + Allocator> + + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn, + bool Node_Based, + class Allocator> + class tree_trace_base : private PB_DS_BASE_C_DEC + { + public: + void + trace() const; + + private: + typedef PB_DS_BASE_C_DEC base_type; + + typedef Const_Node_Iterator const_node_iterator; + + typedef typename Allocator::size_type size_type; + + private: + void + trace_node(const_node_iterator nd_it, size_type level) const; + + virtual bool + empty() const = 0; + + virtual const_node_iterator + node_begin() const = 0; + + virtual const_node_iterator + node_end() const = 0; + + static void + print_node_pointer(Const_Node_Iterator nd_it, integral_constant<int,true>); + + static void + print_node_pointer(Const_Node_Iterator nd_it, integral_constant<int,false>); + + template<typename Metadata_> + static void + trace_it_metadata(Const_Node_Iterator nd_it, type_to_type<Metadata_>); + + static void + trace_it_metadata(Const_Node_Iterator, type_to_type<null_node_metadata>); + }; + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace() const + { + if (empty()) + return; + + trace_node(node_begin(), 0); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace_node(const_node_iterator nd_it, size_type level) const + { + if (nd_it.get_r_child() != node_end()) + trace_node(nd_it.get_r_child(), level + 1); + + for (size_type i = 0; i < level; ++i) + std::cerr << ' '; + + print_node_pointer(nd_it, integral_constant<int,Node_Based>()); + std::cerr << base_type::extract_key(*(*nd_it)); + + typedef + type_to_type< + typename const_node_iterator::metadata_type> + m_type_ind_t; + + trace_it_metadata(nd_it, m_type_ind_t()); + + std::cerr << std::endl; + + if (nd_it.get_l_child() != node_end()) + trace_node(nd_it.get_l_child(), level + 1); + } + + PB_DS_CLASS_T_DEC + template<typename Metadata_> + void + PB_DS_CLASS_C_DEC:: + trace_it_metadata(Const_Node_Iterator nd_it, type_to_type<Metadata_>) + { + std::cerr << " (" << + static_cast<unsigned long>(nd_it.get_metadata()) << ") "; + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace_it_metadata(Const_Node_Iterator, type_to_type<null_node_metadata>) + { } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + print_node_pointer(Const_Node_Iterator nd_it, integral_constant<int,true>) + { + std::cerr << nd_it.m_p_nd << " "; + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + print_node_pointer(Const_Node_Iterator nd_it, integral_constant<int,false>) + { + std::cerr <<* nd_it << " "; + } + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_BASE_C_DEC + +#endif // #ifdef PB_DS_TREE_TRACE + + } // namespace detail + +} // namespace pb_ds + +#endif // #ifdef PB_DS_TREE_TRACE + +#endif // #ifndef PB_DS_TREE_TRACE_BASE_HPP + diff --git a/libstdc++/include/ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp b/libstdc++/include/ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp new file mode 100644 index 0000000..ed9e1aa --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp @@ -0,0 +1,122 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_metadata_selector.hpp + * Contains an implementation class for tries. + */ + +#ifndef PB_DS_TRIE_NODE_METADATA_SELECTOR_HPP +#define PB_DS_TRIE_NODE_METADATA_SELECTOR_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Node_Update, bool Null> + struct trie_metadata_helper + { + typedef typename Node_Update::metadata_type type; + }; + + template<typename Node_Update> + struct trie_metadata_helper< + Node_Update, + true> + { + typedef null_node_metadata type; + }; + + template<typename Key, + typename Data, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Const_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct trie_node_metadata_selector + { + private: + typedef + dumconst_node_iterator< + Key, + Data, + Allocator> + dumconst_node_it; + + enum + { + null_update = + is_same< + Node_Update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator>, + null_trie_node_update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator> >::value + }; + + public: + typedef + typename trie_metadata_helper< + Node_Update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator>, + null_update>::type + type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_TRIE_NODE_METADATA_SELECTOR_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/trie_policy/null_node_update_imp.hpp b/libstdc++/include/ext/pb_ds/detail/trie_policy/null_node_update_imp.hpp new file mode 100644 index 0000000..cb0b57f --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/trie_policy/null_node_update_imp.hpp @@ -0,0 +1,56 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file null_node_update_imp.hpp + * Contains an implementation of null_node_update. + */ + +PB_DS_CLASS_T_DEC +template<typename Const_Node_Iterator_, + typename Node_Iterator_, + class E_Access_Traits_, + typename Allocator_> +inline void +PB_DS_CLASS_C_DEC:: +swap(null_trie_node_update< Const_Node_Iterator_, Node_Iterator_, E_Access_Traits_, Allocator_>& /*other*/) +{ } + diff --git a/libstdc++/include/ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp b/libstdc++/include/ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp new file mode 100644 index 0000000..9351217 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp @@ -0,0 +1,189 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file order_statistics_imp.hpp + * Contains forward declarations for order_statistics_key + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +find_by_order(size_type order) +{ + if (empty()) + return (end()); + + ++order; + + node_iterator nd_it = node_begin(); + + node_iterator end_nd_it = node_end(); + + while (true) + { + if (order > nd_it.get_metadata()) + return (++base_type::rightmost_it(nd_it)); + + const size_type num_children = nd_it.num_children(); + + if (num_children == 0) + return (*nd_it); + + for (size_type i = 0; i < num_children; ++i) + { + node_iterator child_nd_it = nd_it.get_child(i); + + if (order <= child_nd_it.get_metadata()) + { + i = num_children; + + nd_it = child_nd_it; + } + else + order -= child_nd_it.get_metadata(); + } + } +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +find_by_order(size_type order) const +{ + return (const_cast<PB_DS_CLASS_C_DEC* >(this)->find_by_order(order)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +order_of_key(const_key_reference r_key) const +{ + const E_Access_Traits& r_traits = + const_cast<PB_DS_CLASS_C_DEC* >(this)->get_e_access_traits(); + + return (order_of_prefix( + r_traits.begin(r_key), + r_traits.end(r_key))); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +order_of_prefix(typename e_access_traits::const_iterator b, typename e_access_traits::const_iterator e) const +{ + if (empty()) + return (0); + + const E_Access_Traits& r_traits = + const_cast<PB_DS_CLASS_C_DEC* >(this)->get_e_access_traits(); + + const_node_iterator nd_it = node_begin(); + + const_node_iterator end_nd_it = node_end(); + + size_type ord = 0; + + while (true) + { + const size_type num_children = nd_it.num_children(); + + if (num_children == 0) + { + const_key_reference r_key = + base_type::extract_key(*(*nd_it)); + + typename e_access_traits::const_iterator key_b = + r_traits.begin(r_key); + + typename e_access_traits::const_iterator key_e = + r_traits.end(r_key); + + return ((base_type::less( key_b, key_e, b, e, r_traits))? + ord + 1 : + ord); + } + + const_node_iterator next_nd_it = end_nd_it; + + size_type i = num_children - 1; + + do + { + const_node_iterator child_nd_it = nd_it.get_child(i); + + if (next_nd_it != end_nd_it) + ord += child_nd_it.get_metadata(); + else if (!base_type::less( + b, e, + child_nd_it.valid_prefix().first, + child_nd_it.valid_prefix().second, + r_traits)) + next_nd_it = child_nd_it; + } + while (i-- > 0); + + if (next_nd_it == end_nd_it) + return (ord); + + nd_it = next_nd_it; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +operator()(node_iterator nd_it, const_node_iterator /*end_nd_it*/) const +{ + const size_type num_children = nd_it.num_children(); + + size_type children_rank = 0; + + for (size_type i = 0; i < num_children; ++i) + children_rank += nd_it.get_child(i).get_metadata(); + + const_cast<size_type& >(nd_it.get_metadata()) =(num_children == 0)? 1 : children_rank; +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~trie_order_statistics_node_update() +{ } diff --git a/libstdc++/include/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp b/libstdc++/include/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp new file mode 100644 index 0000000..c74290e --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp @@ -0,0 +1,157 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file prefix_search_node_update_imp.hpp + * Contains an implementation of prefix_search_node_update. + */ + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::const_iterator, + typename PB_DS_CLASS_C_DEC::const_iterator> +PB_DS_CLASS_C_DEC:: +prefix_range(const_key_reference r_key) const +{ + const e_access_traits& r_traits = get_e_access_traits(); + + return (prefix_range( + r_traits.begin(r_key), + r_traits.end(r_key))); +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::iterator, + typename PB_DS_CLASS_C_DEC::iterator> +PB_DS_CLASS_C_DEC:: +prefix_range(const_key_reference r_key) +{ + return (prefix_range( + get_e_access_traits().begin(r_key), + get_e_access_traits().end(r_key))); +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::const_iterator, + typename PB_DS_CLASS_C_DEC::const_iterator> +PB_DS_CLASS_C_DEC:: +prefix_range(typename e_access_traits::const_iterator b, typename e_access_traits::const_iterator e) const +{ + const std::pair<iterator, iterator> non_const_ret = + const_cast<PB_DS_CLASS_C_DEC* >(this)->prefix_range(b, e); + + return (std::make_pair( + const_iterator(non_const_ret.first), + const_iterator(non_const_ret.second))); +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::iterator, + typename PB_DS_CLASS_C_DEC::iterator> +PB_DS_CLASS_C_DEC:: +prefix_range(typename e_access_traits::const_iterator b, typename e_access_traits::const_iterator e) +{ + Node_Iterator nd_it = node_begin(); + Node_Iterator end_nd_it = node_end(); + + const e_access_traits& r_traits = + get_e_access_traits(); + + const size_type given_range_length = std::distance(b, e); + + while (true) + { + if (nd_it == end_nd_it) + return (std::make_pair(end(), end())); + + const size_type common_range_length = + PB_DS_BASE_C_DEC::common_prefix_len(nd_it, b, e, r_traits); + + if (common_range_length >= given_range_length) + { + iterator ret_b = leftmost_it(nd_it); + + iterator ret_e = rightmost_it(nd_it); + + return (std::make_pair(ret_b, ++ret_e)); + } + + nd_it = next_child(nd_it, b, e, end_nd_it, r_traits); + } +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +next_child(node_iterator nd_it, typename e_access_traits::const_iterator b, typename e_access_traits::const_iterator e, node_iterator end_nd_it, const e_access_traits& r_traits) +{ + const size_type num_children = nd_it.num_children(); + + node_iterator ret = end_nd_it; + + size_type max_length = 0; + + for (size_type i = 0; i < num_children; ++i) + { + node_iterator pot = nd_it.get_child(i); + + const size_type common_range_length = + PB_DS_BASE_C_DEC::common_prefix_len( pot, b, e, r_traits); + + if (common_range_length > max_length) + { + ret = pot; + + max_length = common_range_length; + } + } + + return (ret); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +operator()(node_iterator /*nd_it*/, const_node_iterator /*end_nd_it*/) const +{ } diff --git a/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_e_access_traits.hpp b/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_e_access_traits.hpp new file mode 100644 index 0000000..954f479 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_e_access_traits.hpp @@ -0,0 +1,95 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_trie_e_access_traits.hpp + * Contains a sample probe policy. + */ + +#ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP +#define PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP + +// A sample trie element-access traits. +class sample_trie_e_access_traits +{ + +public: + + // Size type. + typedef size_t size_type; + + // Key type. + typedef std::string key_type; + + // Const key reference type. + typedef + typename Allocator::template rebind< + key_type>::other::const_reference + const_key_reference; + + // Element const iterator type. + typedef std::string::const_iterator const_iterator; + + // Element type. + typedef char e_type; + + enum + { + max_size = 4 + }; + +public: + + // Returns a const_iterator to the first element of r_key. + inline static const_iterator + begin(const_key_reference r_key); + + // Returns a const_iterator to the after-last element of r_key. + inline static const_iterator + end(const_key_reference r_key); + + // Maps an element to a position. + inline static size_type + e_pos(e_type e); + +}; + +#endif // #ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hpp b/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hpp new file mode 100644 index 0000000..8a884c4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_trie_node_update.hpp + * Contains a samle node update functor. + */ + +#ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP +#define PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP + +// A sample node updator. +template<typename Const_Node_Iterator, + + class Node_Iterator, + + class E_Access_Traits, + + class Allocator + > +class sample_trie_node_update +{ + +public: + + // Metadata type. + typedef size_t metadata_type; + +protected: + + // Default constructor. + sample_trie_node_update(); + + // Updates the rank of a node through a node_iterator node_it; end_nd_it is the end node iterator. + inline void + operator()(node_iterator node_it, const_node_iterator end_nd_it) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP diff --git a/libstdc++/include/ext/pb_ds/detail/trie_policy/string_trie_e_access_traits_imp.hpp b/libstdc++/include/ext/pb_ds/detail/trie_policy/string_trie_e_access_traits_imp.hpp new file mode 100644 index 0000000..c2fe1c6 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/trie_policy/string_trie_e_access_traits_imp.hpp @@ -0,0 +1,105 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file string_trie_e_access_traits_imp.hpp + * Contains a policy for extracting character positions from + * a string for a vector-based PATRICIA tree + */ + +PB_DS_CLASS_T_DEC +detail::integral_constant<int, Reverse> PB_DS_CLASS_C_DEC::s_rev_ind; + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +e_pos(e_type e) +{ + return (static_cast<size_type>(e - min_e_val)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin(const_key_reference r_key) +{ + return (begin_imp(r_key, s_rev_ind)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end(const_key_reference r_key) +{ + return (end_imp(r_key, s_rev_ind)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin_imp(const_key_reference r_key, detail::false_type) +{ + return (r_key.begin()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin_imp(const_key_reference r_key, detail::true_type) +{ + return (r_key.rbegin()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end_imp(const_key_reference r_key, detail::false_type) +{ + return (r_key.end()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end_imp(const_key_reference r_key, detail::true_type) +{ + return (r_key.rend()); +} diff --git a/libstdc++/include/ext/pb_ds/detail/trie_policy/trie_policy_base.hpp b/libstdc++/include/ext/pb_ds/detail/trie_policy/trie_policy_base.hpp new file mode 100644 index 0000000..a8506ce --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/trie_policy/trie_policy_base.hpp @@ -0,0 +1,255 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trie_policy_base.hpp + * Contains an implementation of trie_policy_base. + */ + +#ifndef PB_DS_TRIE_POLICY_BASE_HPP +#define PB_DS_TRIE_POLICY_BASE_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template< \ + class Const_Node_Iterator, \ + class Node_Iterator, \ + class E_Access_Traits, \ + typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + trie_policy_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + E_Access_Traits, \ + Allocator> + +#define PB_DS_BASE_C_DEC \ + basic_tree_policy_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + Allocator> + + template<typename Const_Node_Iterator, + class Node_Iterator, + class E_Access_Traits, + class Allocator> + class trie_policy_base : public PB_DS_BASE_C_DEC + { + + public: + + typedef E_Access_Traits e_access_traits; + + typedef Allocator allocator; + + typedef typename allocator::size_type size_type; + + typedef null_node_metadata metadata_type; + + typedef Const_Node_Iterator const_node_iterator; + + typedef Node_Iterator node_iterator; + + typedef typename const_node_iterator::value_type const_iterator; + + typedef typename node_iterator::value_type iterator; + + public: + + typedef typename PB_DS_BASE_C_DEC::key_type key_type; + + typedef + typename PB_DS_BASE_C_DEC::const_key_reference + const_key_reference; + + protected: + + virtual const_iterator + end() const = 0; + + virtual iterator + end() = 0; + + virtual const_node_iterator + node_begin() const = 0; + + virtual node_iterator + node_begin() = 0; + + virtual const_node_iterator + node_end() const = 0; + + virtual node_iterator + node_end() = 0; + + virtual const e_access_traits& + get_e_access_traits() const = 0; + + private: + typedef + std::pair< + typename e_access_traits::const_iterator, + typename e_access_traits::const_iterator> + prefix_range_t; + + typedef PB_DS_BASE_C_DEC base_type; + + protected: + static size_type + common_prefix_len(node_iterator nd_it, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits); + + static iterator + leftmost_it(node_iterator nd_it); + + static iterator + rightmost_it(node_iterator nd_it); + + static bool + less(typename e_access_traits::const_iterator b_l, typename e_access_traits::const_iterator e_l, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits); + }; + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + common_prefix_len(node_iterator nd_it, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits) + { + prefix_range_t pref_range = nd_it.valid_prefix(); + + typename e_access_traits::const_iterator b_l = pref_range.first; + typename e_access_traits::const_iterator e_l = pref_range.second; + + const size_type range_length_l = + std::distance(b_l, e_l); + + const size_type range_length_r = + std::distance(b_r, e_r); + + if (range_length_r < range_length_l) + { + std::swap(b_l, b_r); + + std::swap(e_l, e_r); + } + + size_type ret = 0; + + while (b_l != e_l) + { + if (r_traits.e_pos(*b_l) != r_traits.e_pos(*b_r)) + return (ret); + + ++ret; + + ++b_l; + + ++b_r; + } + + return (ret); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + leftmost_it(node_iterator nd_it) + { + if (nd_it.num_children() == 0) + return (*nd_it); + + return (leftmost_it(nd_it.get_child(0))); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + rightmost_it(node_iterator nd_it) + { + const size_type num_children = nd_it.num_children(); + + if (num_children == 0) + return (*nd_it); + + return (rightmost_it(nd_it.get_child(num_children - 1))); + } + + PB_DS_CLASS_T_DEC + bool + PB_DS_CLASS_C_DEC:: + less(typename e_access_traits::const_iterator b_l, typename e_access_traits::const_iterator e_l, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits) + { + while (b_l != e_l) + { + if (b_r == e_r) + return (false); + + size_type l_pos = + r_traits.e_pos(*b_l); + size_type r_pos = + r_traits.e_pos(*b_r); + + if (l_pos != r_pos) + return (l_pos < r_pos); + + ++b_l; + ++b_r; + } + + return (b_r != e_r); + } + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_TRIE_POLICY_BASE_HPP + diff --git a/libstdc++/include/ext/pb_ds/detail/type_utils.hpp b/libstdc++/include/ext/pb_ds/detail/type_utils.hpp new file mode 100644 index 0000000..e917fac --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/type_utils.hpp @@ -0,0 +1,165 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file type_utils.hpp + * Contains utilities for handnling types. All of these classes are based on + * "Modern C++" by Andrei Alxandrescu. + */ + +#ifndef PB_DS_TYPE_UTILS_HPP +#define PB_DS_TYPE_UTILS_HPP + +#include <cstddef> +#include <utility> +#include <tr1/type_traits> +#include <ext/type_traits.h> +#include <ext/numeric_traits.h> + +namespace pb_ds +{ + namespace detail + { + using std::tr1::is_same; + using std::tr1::is_const; + using std::tr1::is_pointer; + using std::tr1::is_reference; + using std::tr1::is_fundamental; + using std::tr1::is_member_object_pointer; + using std::tr1::is_member_pointer; + using std::tr1::is_base_of; + using std::tr1::remove_const; + using std::tr1::remove_reference; + + // Need integral_const<bool, true> <-> integral_const<int, 1>, so + // because of this use the following typedefs instead of importing + // std::tr1's. + using std::tr1::integral_constant; + typedef std::tr1::integral_constant<int, 1> true_type; + typedef std::tr1::integral_constant<int, 0> false_type; + + using __gnu_cxx::__conditional_type; + using __gnu_cxx::__numeric_traits; + + template<typename T> + struct is_const_pointer + { + enum + { + value = is_const<T>::value && is_pointer<T>::value + }; + }; + + template<typename T> + struct is_const_reference + { + enum + { + value = is_const<T>::value && is_reference<T>::value + }; + }; + + template<typename T> + struct is_simple + { + enum + { + value = is_fundamental<typename remove_const<T>::type>::value + || is_pointer<typename remove_const<T>::type>::value + || is_member_pointer<T>::value + }; + }; + + template<typename T> + class is_pair + { + private: + template<typename U> + struct is_pair_imp + { + enum + { + value = 0 + }; + }; + + template<typename U, typename V> + struct is_pair_imp<std::pair<U,V> > + { + enum + { + value = 1 + }; + }; + + public: + enum + { + value = is_pair_imp<T>::value + }; + }; + + + template<bool> + struct static_assert; + + template<> + struct static_assert<true> + { }; + + template<int> + struct static_assert_dumclass + { + enum + { + v = 1 + }; + }; + + template<typename Type> + struct type_to_type + { + typedef Type type; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/types_traits.hpp b/libstdc++/include/ext/pb_ds/detail/types_traits.hpp new file mode 100644 index 0000000..8272c8a --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/types_traits.hpp @@ -0,0 +1,85 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file types_traits.hpp + * Contains a traits class of types used by containers. + */ + +#ifndef PB_DS_TYPES_TRAITS_HPP +#define PB_DS_TYPES_TRAITS_HPP + +#include <ext/pb_ds/detail/basic_types.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <utility> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, typename Mapped, typename Alloc, bool Store_Extra> + struct vt_base_selector + { + typedef value_type_base<Key, Mapped, Alloc, Store_Extra> type; + }; + + template<typename Key, typename Mapped, typename Alloc, bool Store_Extra> + struct types_traits + : public vt_base_selector<Key, Mapped, Alloc, Store_Extra>::type + { + typedef typename Alloc::template rebind<Key>::other key_allocator; + typedef typename key_allocator::value_type key_type; + typedef typename key_allocator::pointer key_pointer; + typedef typename key_allocator::const_pointer const_key_pointer; + typedef typename key_allocator::reference key_reference; + typedef typename key_allocator::const_reference const_key_reference; + typedef typename Alloc::size_type size_type; + + // Extra value (used when the extra value is stored with each value). + typedef std::pair<size_type, size_type> comp_hash; + + integral_constant<int, Store_Extra> m_store_extra_indicator; + typename no_throw_copies<Key, Mapped>::indicator m_no_throw_copies_indicator; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_iterator.hpp b/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_iterator.hpp new file mode 100644 index 0000000..84419e5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_iterator.hpp @@ -0,0 +1,135 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_iterator.hpp + * Contains an iterator class used for const ranging over the elements of the + * table. + */ + +// Const range-type iterator. +class const_iterator_ : + public const_point_iterator_ + +{ + +public: + + // Category. + typedef std::forward_iterator_tag iterator_category; + + // Difference type. + typedef typename Allocator::difference_type difference_type; + + // Iterator's value type. + typedef value_type_ value_type; + + // Iterator's pointer type. + typedef pointer_ pointer; + + // Iterator's const pointer type. + typedef const_pointer_ const_pointer; + + // Iterator's reference type. + typedef reference_ reference; + + // Iterator's const reference type. + typedef const_reference_ const_reference; + +public: + + // Default constructor. + inline + const_iterator_() + + : m_p_tbl(NULL) + { } + + // Increments. + inline const_iterator_& + operator++() + { + m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); + + return (*this); + } + + // Increments. + inline const_iterator_ + operator++(int) + { + const_iterator_ ret =* this; + + m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); + + return (ret); + } + +protected: + + typedef const_point_iterator_ base_type; + +protected: + + /** + * Constructor used by the table to initiate the generalized + * pointer and position (e.g., this is called from within a find() + * of a table. + * */ + inline + const_iterator_(const_pointer_ p_value, PB_DS_GEN_POS pos, const PB_DS_CLASS_C_DEC* p_tbl) : const_point_iterator_(p_value), + m_p_tbl(p_tbl), + m_pos(pos) + { } + +protected: + + /** + * Pointer to the table object which created the iterator (used for + * incrementing its position. + * */ + const PB_DS_CLASS_C_DEC* m_p_tbl; + + PB_DS_GEN_POS m_pos; + + friend class PB_DS_CLASS_C_DEC; +}; + diff --git a/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp b/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp new file mode 100644 index 0000000..e1e93a5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp @@ -0,0 +1,157 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_point_iterator.hpp + * Contains an iterator class returned by the tables' const find and insert + * methods. + */ + +class point_iterator_; + +// Const point-type iterator. +class const_point_iterator_ +{ + +public: + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // Iterator's value type. + typedef value_type_ value_type; + + // Iterator's pointer type. + typedef pointer_ pointer; + + // Iterator's const pointer type. + typedef const_pointer_ const_pointer; + + // Iterator's reference type. + typedef reference_ reference; + + // Iterator's const reference type. + typedef const_reference_ const_reference; + +public: + + inline + const_point_iterator_(const_pointer p_value) : m_p_value(p_value) + { } + + // Default constructor. + inline + const_point_iterator_() + + : m_p_value(NULL) + { } + + // Copy constructor. + inline + const_point_iterator_(const const_point_iterator_& other) + + : m_p_value(other.m_p_value) + { } + + // Copy constructor. + inline + const_point_iterator_(const point_iterator_& other) + + : m_p_value(other.m_p_value) + { } + + // Access. + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_value != NULL); + + return (m_p_value); + } + + // Access. + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_value != NULL); + + return (*m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator==(const point_iterator_& other) const + { + return (m_p_value == other.m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator==(const const_point_iterator_& other) const + { + return (m_p_value == other.m_p_value); + } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const point_iterator_& other) const + { + return (m_p_value != other.m_p_value); + } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const const_point_iterator_& other) const + { + return (m_p_value != other.m_p_value); + } + +protected: + const_pointer m_p_value; + + friend class point_iterator_; + + friend class PB_DS_CLASS_C_DEC; +}; + diff --git a/libstdc++/include/ext/pb_ds/detail/unordered_iterator/iterator.hpp b/libstdc++/include/ext/pb_ds/detail/unordered_iterator/iterator.hpp new file mode 100644 index 0000000..11afafb --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/unordered_iterator/iterator.hpp @@ -0,0 +1,156 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterator.hpp + * Contains an iterator_ class used for ranging over the elements of the + * table. + */ + +// Range-type iterator. +class iterator_ : + public const_iterator_ + +{ + +public: + + // Category. + typedef std::forward_iterator_tag iterator_category; + + // Difference type. + typedef typename Allocator::difference_type difference_type; + + // Iterator's value type. + typedef value_type_ value_type; + + // Iterator's pointer type. + typedef pointer_ pointer; + + // Iterator's const pointer type. + typedef const_pointer_ const_pointer; + + // Iterator's reference type. + typedef reference_ reference; + + // Iterator's const reference type. + typedef const_reference_ const_reference; + +public: + + // Default constructor. + inline + iterator_() + + : const_iterator_(NULL, PB_DS_GEN_POS(), NULL) + { } + + // Conversion to a point-type iterator. + inline + operator point_iterator_() + { + return (point_iterator_( + const_cast<pointer>(const_iterator_::m_p_value))); + } + + // Conversion to a point-type iterator. + inline + operator const point_iterator_() const + { + return (point_iterator_( + const_cast<pointer>(const_iterator_::m_p_value))); + } + + // Access. + inline pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != NULL); + + return (const_cast<pointer>(base_type::m_p_value)); + } + + // Access. + inline reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != NULL); + + return (const_cast<reference>(*base_type::m_p_value)); + } + + // Increments. + inline iterator_& + operator++() + { + base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); + + return (*this); + } + + // Increments. + inline iterator_ + operator++(int) + { + iterator_ ret =* this; + + base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); + + return (ret); + } + +protected: + typedef const_iterator_ base_type; + +protected: + + /** + * Constructor used by the table to initiate the generalized + * pointer and position (e.g., this is called from within a find() + * of a table. + * */ + inline + iterator_(pointer p_value, PB_DS_GEN_POS pos, PB_DS_CLASS_C_DEC* p_tbl) : const_iterator_(p_value, pos, p_tbl) + { } + + friend class PB_DS_CLASS_C_DEC; +}; + diff --git a/libstdc++/include/ext/pb_ds/detail/unordered_iterator/point_iterator.hpp b/libstdc++/include/ext/pb_ds/detail/unordered_iterator/point_iterator.hpp new file mode 100644 index 0000000..7b96425 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/detail/unordered_iterator/point_iterator.hpp @@ -0,0 +1,149 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file point_iterator.hpp + * Contains an iterator class returned by the tables' find and insert + * methods. + */ + +// Find type iterator. +class point_iterator_ +{ + +public: + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // Iterator's value type. + typedef value_type_ value_type; + + // Iterator's pointer type. + typedef pointer_ pointer; + + // Iterator's const pointer type. + typedef const_pointer_ const_pointer; + + // Iterator's reference type. + typedef reference_ reference; + + // Iterator's const reference type. + typedef const_reference_ const_reference; + +public: + + // Default constructor. + inline + point_iterator_() + + : m_p_value(NULL) + { } + + // Copy constructor. + inline + point_iterator_(const point_iterator_& other) + + : m_p_value(other.m_p_value) + { } + + // Access. + inline pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_value != NULL); + + return (m_p_value); + } + + // Access. + inline reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_value != NULL); + + return (*m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator==(const point_iterator_& other) const + { + return (m_p_value == other.m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator==(const const_point_iterator_& other) const + { + return (m_p_value == other.m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator!=(const point_iterator_& other) const + { + return (m_p_value != other.m_p_value); + } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const const_point_iterator_& other) const + { + return (m_p_value != other.m_p_value); + } + + inline + point_iterator_(pointer p_value) : m_p_value(p_value) + { } + +protected: + friend class const_point_iterator_; + + friend class PB_DS_CLASS_C_DEC; + +protected: + pointer m_p_value; +}; + diff --git a/libstdc++/include/ext/pb_ds/exception.hpp b/libstdc++/include/ext/pb_ds/exception.hpp new file mode 100644 index 0000000..896ff39 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/exception.hpp @@ -0,0 +1,108 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file exception.hpp + * Contains exception classes. + */ + +#ifndef PB_DS_EXCEPTION_HPP +#define PB_DS_EXCEPTION_HPP + +#include <stdexcept> + +namespace pb_ds +{ + // Base class for exceptions. + struct container_error : public std::logic_error + { + container_error() + : std::logic_error(__N("pb_ds::container_error")) { } + }; + + // An entry cannot be inserted into a container object for logical + // reasons (not, e.g., if memory is unabvailable, in which case + // the allocator's exception will be thrown). + struct insert_error : public container_error { }; + + // A join cannot be performed logical reasons (i.e., the ranges of + // the two container objects being joined overlaps. + struct join_error : public container_error { }; + + // A container cannot be resized. + struct resize_error : public container_error { }; + +#if __EXCEPTIONS + void + __throw_container_error(void) + { throw container_error(); } + + void + __throw_insert_error(void) + { throw insert_error(); } + + void + __throw_join_error(void) + { throw join_error(); } + + void + __throw_resize_error(void) + { throw resize_error(); } +#else + void + __throw_container_error(void) + { std::abort(); } + + void + __throw_insert_error(void) + { std::abort(); } + + void + __throw_join_error(void) + { std::abort(); } + + void + __throw_resize_error(void) + { std::abort(); } +#endif +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/hash_policy.hpp b/libstdc++/include/ext/pb_ds/hash_policy.hpp new file mode 100644 index 0000000..c17d978 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/hash_policy.hpp @@ -0,0 +1,610 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_policy.hpp + * Contains hash-related policies. + */ + +#ifndef PB_DS_HASH_POLICY_HPP +#define PB_DS_HASH_POLICY_HPP + +#include <algorithm> +#include <vector> +#include <cmath> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp> +#include <ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp> +#include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp> + +namespace pb_ds +{ + // A null hash function, indicating that the combining hash function + // is actually a ranged hash function. + struct null_hash_fn + { }; + + // A null probe function, indicating that the combining probe + // function is actually a ranged probe function. + struct null_probe_fn + { }; + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC linear_probe_fn<Size_Type> + + // A probe sequence policy using fixed increments. + template<typename Size_Type = size_t> + class linear_probe_fn + { + public: + typedef Size_Type size_type; + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + // Returns the i-th offset from the hash value. + inline size_type + operator()(size_type i) const; + }; + +#include <ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC quadratic_probe_fn<Size_Type> + + // A probe sequence policy using square increments. + template<typename Size_Type = size_t> + class quadratic_probe_fn + { + public: + typedef Size_Type size_type; + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + // Returns the i-th offset from the hash value. + inline size_type + operator()(size_type i) const; + }; + +#include <ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC direct_mask_range_hashing<Size_Type> + + // A mask range-hashing class (uses a bit-mask). + template<typename Size_Type = size_t> + class direct_mask_range_hashing + : public detail::mask_based_range_hashing<Size_Type> + { + private: + typedef detail::mask_based_range_hashing<Size_Type> mask_based_base; + + public: + typedef Size_Type size_type; + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + void + notify_resized(size_type size); + + // Transforms the __hash value hash into a ranged-hash value + // (using a bit-mask). + inline size_type + operator()(size_type hash) const; + }; + +#include <ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC direct_mod_range_hashing<Size_Type> + + // A mod range-hashing class (uses the modulo function). + template<typename Size_Type = size_t> + class direct_mod_range_hashing + : public detail::mod_based_range_hashing<Size_Type> + { + public: + typedef Size_Type size_type; + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + void + notify_resized(size_type size); + + // Transforms the __hash value hash into a ranged-hash value + // (using a modulo operation). + inline size_type + operator()(size_type hash) const; + + private: + typedef detail::mod_based_range_hashing<size_type> mod_based_base; + }; + +#include <ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type> +#define PB_DS_CLASS_C_DEC hash_load_check_resize_trigger<External_Load_Access, Size_Type> +#define PB_DS_SIZE_BASE_C_DEC detail::hash_load_check_resize_trigger_size_base<Size_Type, External_Load_Access> + + // A resize trigger policy based on a load check. It keeps the + // load factor between some load factors load_min and load_max. + template<bool External_Load_Access = false, typename Size_Type = size_t> + class hash_load_check_resize_trigger : private PB_DS_SIZE_BASE_C_DEC + { + public: + typedef Size_Type size_type; + + enum + { + external_load_access = External_Load_Access + }; + + // Default constructor, or constructor taking load_min and + // load_max load factors between which this policy will keep the + // actual load. + hash_load_check_resize_trigger(float load_min = 0.125, + float load_max = 0.5); + + void + swap(hash_load_check_resize_trigger& other); + + virtual + ~hash_load_check_resize_trigger(); + + // Returns a pair of the minimal and maximal loads, respectively. + inline std::pair<float, float> + get_loads() const; + + // Sets the loads through a pair of the minimal and maximal + // loads, respectively. + void + set_loads(std::pair<float, float> load_pair); + + protected: + inline void + notify_insert_search_start(); + + inline void + notify_insert_search_collision(); + + inline void + notify_insert_search_end(); + + inline void + notify_find_search_start(); + + inline void + notify_find_search_collision(); + + inline void + notify_find_search_end(); + + inline void + notify_erase_search_start(); + + inline void + notify_erase_search_collision(); + + inline void + notify_erase_search_end(); + + // Notifies an element was inserted. The total number of entries + // in the table is num_entries. + inline void + notify_inserted(size_type num_entries); + + inline void + notify_erased(size_type num_entries); + + // Notifies the table was cleared. + void + notify_cleared(); + + // Notifies the table was resized as a result of this object's + // signifying that a resize is needed. + void + notify_resized(size_type new_size); + + void + notify_externally_resized(size_type new_size); + + inline bool + is_resize_needed() const; + + inline bool + is_grow_needed(size_type size, size_type num_entries) const; + + private: + virtual void + do_resize(size_type new_size); + + typedef PB_DS_SIZE_BASE_C_DEC size_base; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + + float m_load_min; + float m_load_max; + size_type m_next_shrink_size; + size_type m_next_grow_size; + bool m_resize_needed; + }; + +#include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_SIZE_BASE_C_DEC + +#define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type> +#define PB_DS_CLASS_C_DEC cc_hash_max_collision_check_resize_trigger<External_Load_Access, Size_Type> + + // A resize trigger policy based on collision checks. It keeps the + // simulated load factor lower than some given load factor. + template<bool External_Load_Access = false, typename Size_Type = size_t> + class cc_hash_max_collision_check_resize_trigger + { + public: + typedef Size_Type size_type; + + enum + { + external_load_access = External_Load_Access + }; + + // Default constructor, or constructor taking load, a __load + // factor which it will attempt to maintain. + cc_hash_max_collision_check_resize_trigger(float load = 0.5); + + void + swap(PB_DS_CLASS_C_DEC& other); + + // Returns the current load. + inline float + get_load() const; + + // Sets the load; does not resize the container. + void + set_load(float load); + + protected: + inline void + notify_insert_search_start(); + + inline void + notify_insert_search_collision(); + + inline void + notify_insert_search_end(); + + inline void + notify_find_search_start(); + + inline void + notify_find_search_collision(); + + inline void + notify_find_search_end(); + + inline void + notify_erase_search_start(); + + inline void + notify_erase_search_collision(); + + inline void + notify_erase_search_end(); + + inline void + notify_inserted(size_type num_entries); + + inline void + notify_erased(size_type num_entries); + + void + notify_cleared(); + + // Notifies the table was resized as a result of this object's + // signifying that a resize is needed. + void + notify_resized(size_type new_size); + + void + notify_externally_resized(size_type new_size); + + inline bool + is_resize_needed() const; + + inline bool + is_grow_needed(size_type size, size_type num_entries) const; + + private: + void + calc_max_num_coll(); + + inline void + calc_resize_needed(); + + float m_load; + size_type m_size; + size_type m_num_col; + size_type m_max_col; + bool m_resize_needed; + }; + +#include <ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC hash_exponential_size_policy<Size_Type> + + // A size policy whose sequence of sizes form an exponential + // sequence (typically powers of 2. + template<typename Size_Type = size_t> + class hash_exponential_size_policy + { + public: + typedef Size_Type size_type; + + // Default constructor, or onstructor taking a start_size, or + // constructor taking a start size and grow_factor. The policy + // will use the sequence of sizes start_size, start_size* + // grow_factor, start_size* grow_factor^2, ... + hash_exponential_size_policy(size_type start_size = 8, + size_type grow_factor = 2); + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + size_type + get_nearest_larger_size(size_type size) const; + + size_type + get_nearest_smaller_size(size_type size) const; + + private: + size_type m_start_size; + size_type m_grow_factor; + }; + +#include <ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC +#define PB_DS_CLASS_C_DEC hash_prime_size_policy + + // A size policy whose sequence of sizes form a nearly-exponential + // sequence of primes. + class hash_prime_size_policy + { + public: + // Size type. + typedef size_t size_type; + + // Default constructor, or onstructor taking a start_size The + // policy will use the sequence of sizes approximately + // start_size, start_size* 2, start_size* 2^2, ... + hash_prime_size_policy(size_type start_size = 8); + + inline void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + size_type + get_nearest_larger_size(size_type size) const; + + size_type + get_nearest_smaller_size(size_type size) const; + + private: + size_type m_start_size; + }; + +#include <ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Policy, typename Trigger_Policy, bool External_Size_Access, typename Size_Type> + +#define PB_DS_CLASS_C_DEC hash_standard_resize_policy<Size_Policy, Trigger_Policy, External_Size_Access, Size_Type> + + // A resize policy which delegates operations to size and trigger policies. + template<typename Size_Policy = hash_exponential_size_policy<>, + typename Trigger_Policy = hash_load_check_resize_trigger<>, + bool External_Size_Access = false, + typename Size_Type = size_t> + class hash_standard_resize_policy + : public Size_Policy, public Trigger_Policy + { + public: + typedef Size_Type size_type; + typedef Trigger_Policy trigger_policy; + typedef Size_Policy size_policy; + + enum + { + external_size_access = External_Size_Access + }; + + // Default constructor. + hash_standard_resize_policy(); + + // constructor taking some policies r_size_policy will be copied + // by the Size_Policy object of this object. + hash_standard_resize_policy(const Size_Policy& r_size_policy); + + // constructor taking some policies. r_size_policy will be + // copied by the Size_Policy object of this + // object. r_trigger_policy will be copied by the Trigger_Policy + // object of this object. + hash_standard_resize_policy(const Size_Policy& r_size_policy, + const Trigger_Policy& r_trigger_policy); + + virtual + ~hash_standard_resize_policy(); + + inline void + swap(PB_DS_CLASS_C_DEC& other); + + // Access to the Size_Policy object used. + Size_Policy& + get_size_policy(); + + // Const access to the Size_Policy object used. + const Size_Policy& + get_size_policy() const; + + // Access to the Trigger_Policy object used. + Trigger_Policy& + get_trigger_policy(); + + // Access to the Trigger_Policy object used. + const Trigger_Policy& + get_trigger_policy() const; + + // Returns the actual size of the container. + inline size_type + get_actual_size() const; + + // Resizes the container to suggested_new_size, a suggested size + // (the actual size will be determined by the Size_Policy + // object). + void + resize(size_type suggested_new_size); + + protected: + inline void + notify_insert_search_start(); + + inline void + notify_insert_search_collision(); + + inline void + notify_insert_search_end(); + + inline void + notify_find_search_start(); + + inline void + notify_find_search_collision(); + + inline void + notify_find_search_end(); + + inline void + notify_erase_search_start(); + + inline void + notify_erase_search_collision(); + + inline void + notify_erase_search_end(); + + inline void + notify_inserted(size_type num_e); + + inline void + notify_erased(size_type num_e); + + void + notify_cleared(); + + void + notify_resized(size_type new_size); + + inline bool + is_resize_needed() const; + + // Queries what the new size should be, when the container is + // resized naturally. The current __size of the container is + // size, and the number of used entries within the container is + // num_used_e. + size_type + get_new_size(size_type size, size_type num_used_e) const; + + private: + // Resizes to new_size. + virtual void + do_resize(size_type new_size); + + typedef Trigger_Policy trigger_policy_base; + + typedef Size_Policy size_policy_base; + + size_type m_size; + }; + +#include <ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/list_update_policy.hpp b/libstdc++/include/ext/pb_ds/list_update_policy.hpp new file mode 100644 index 0000000..cfe2a2c --- /dev/null +++ b/libstdc++/include/ext/pb_ds/list_update_policy.hpp @@ -0,0 +1,141 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file list_update_policy.hpp + * Contains policies for list update containers. + */ + +#ifndef PB_DS_LU_POLICY_HPP +#define PB_DS_LU_POLICY_HPP + +#include <ext/pb_ds/detail/list_update_policy/counter_lu_metadata.hpp> + +namespace pb_ds +{ + // A null type that means that each link in a list-based container + // does not actually need metadata. + struct null_lu_metadata + { }; + +#define PB_DS_CLASS_T_DEC template<typename Allocator> +#define PB_DS_CLASS_C_DEC move_to_front_lu_policy<Allocator> + + // A list-update policy that unconditionally moves elements to the + // front of the list. + template<typename Allocator = std::allocator<char> > + class move_to_front_lu_policy + { + public: + typedef Allocator allocator; + + // Metadata on which this functor operates. + typedef null_lu_metadata metadata_type; + + // Reference to metadata on which this functor operates. + typedef typename allocator::template rebind<metadata_type>::other metadata_rebind; + typedef typename metadata_rebind::reference metadata_reference; + + // Creates a metadata object. + metadata_type + operator()() const; + + // Decides whether a metadata object should be moved to the front + // of the list. + inline bool + operator()(metadata_reference r_metadata) const; + + private: + static null_lu_metadata s_metadata; + }; + +#include <ext/pb_ds/detail/list_update_policy/mtf_lu_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<size_t Max_Count, class Allocator> +#define PB_DS_CLASS_C_DEC counter_lu_policy<Max_Count, Allocator> + + // A list-update policy that moves elements to the front of the list + // based on the counter algorithm. + template<size_t Max_Count = 5, typename Allocator = std::allocator<char> > + class counter_lu_policy + : private detail::counter_lu_policy_base<typename Allocator::size_type> + { + public: + typedef Allocator allocator; + + enum + { + max_count = Max_Count + }; + + typedef typename allocator::size_type size_type; + + // Metadata on which this functor operates. + typedef detail::counter_lu_metadata<size_type> metadata_type; + + // Reference to metadata on which this functor operates. + typedef typename Allocator::template rebind<metadata_type>::other metadata_rebind; + typedef typename metadata_rebind::reference metadata_reference; + + // Creates a metadata object. + metadata_type + operator()() const; + + // Decides whether a metadata object should be moved to the front + // of the list. + bool + operator()(metadata_reference r_metadata) const; + + private: + typedef detail::counter_lu_policy_base<typename Allocator::size_type> base_type; + }; + +#include <ext/pb_ds/detail/list_update_policy/counter_lu_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/priority_queue.hpp b/libstdc++/include/ext/pb_ds/priority_queue.hpp new file mode 100644 index 0000000..c6373c5 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/priority_queue.hpp @@ -0,0 +1,131 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file priority_queue.hpp + * Contains priority_queues. + */ + +#ifndef PB_DS_PRIORITY_QUEUE_HPP +#define PB_DS_PRIORITY_QUEUE_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/priority_queue_base_dispatch.hpp> +#include <ext/pb_ds/detail/standard_policies.hpp> + +namespace pb_ds +{ + // A priority queue. + template<typename Value_Type, + typename Cmp_Fn = std::less<Value_Type>, + typename Tag = pairing_heap_tag, + typename Allocator = std::allocator<char> > + class priority_queue + : public detail::priority_queue_base_dispatch<Value_Type,Cmp_Fn,Tag,Allocator>::type + { + private: + typedef typename detail::priority_queue_base_dispatch<Value_Type,Cmp_Fn,Tag,Allocator>::type base_type; + + public: + typedef Value_Type value_type; + typedef Cmp_Fn cmp_fn; + typedef Tag container_category; + typedef Allocator allocator; + typedef typename allocator::size_type size_type; + typedef typename allocator::difference_type difference_type; + + typedef typename allocator::template rebind<value_type>::other value_rebind; + typedef typename value_rebind::reference reference; + typedef typename value_rebind::const_reference const_reference; + typedef typename value_rebind::pointer pointer; + typedef typename value_rebind::const_pointer const_pointer; + + typedef typename base_type::const_point_iterator const_point_iterator; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::iterator iterator; + + priority_queue() { } + + // Constructor taking some policy objects. r_cmp_fn will be copied + // by the Cmp_Fn object of the container object. + priority_queue(const cmp_fn& r_cmp_fn) : base_type(r_cmp_fn) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + priority_queue(It first_it, It last_it) + { base_type::copy_from_range(first_it, last_it); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_cmp_fn + // will be copied by the cmp_fn object of the container object. + template<typename It> + priority_queue(It first_it, It last_it, const cmp_fn& r_cmp_fn) + : base_type(r_cmp_fn) + { base_type::copy_from_range(first_it, last_it); } + + priority_queue(const priority_queue& other) + : base_type((const base_type& )other) { } + + virtual + ~priority_queue() { } + + priority_queue& + operator=(const priority_queue& other) + { + if (this !=& other) + { + priority_queue tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(priority_queue& other) + { base_type::swap(other); } + }; +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/tag_and_trait.hpp b/libstdc++/include/ext/pb_ds/tag_and_trait.hpp new file mode 100644 index 0000000..94039af --- /dev/null +++ b/libstdc++/include/ext/pb_ds/tag_and_trait.hpp @@ -0,0 +1,357 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file tag_and_trait.hpp + * Contains tags and traits, e.g., ones describing underlying + * data structures. + */ + +#ifndef PB_DS_TAG_AND_TRAIT_HPP +#define PB_DS_TAG_AND_TRAIT_HPP + +#include <ext/pb_ds/detail/type_utils.hpp> + +namespace pb_ds +{ + // A trivial iterator tag. Signifies that the iterators has none of + // the STL's movement abilities. + struct trivial_iterator_tag + { }; + + // Prohibit moving trivial iterators. + typedef void trivial_iterator_difference_type; + + + // Signifies a basic invalidation guarantee that any iterator, + // pointer, or reference to a container object's mapped value type + // is valid as long as the container is not modified. + struct basic_invalidation_guarantee + { }; + + // Signifies an invalidation guarantee that includes all those of + // its base, and additionally, that any point-type iterator, + // pointer, or reference to a container object's mapped value type + // is valid as long as its corresponding entry has not be erased, + // regardless of modifications to the container object. + struct point_invalidation_guarantee : public basic_invalidation_guarantee + { }; + + // Signifies an invalidation guarantee that includes all those of + // its base, and additionally, that any range-type iterator + // (including the returns of begin() and end()) is in the correct + // relative positions to other range-type iterators as long as its + // corresponding entry has not be erased, regardless of + // modifications to the container object. + struct range_invalidation_guarantee : public point_invalidation_guarantee + { }; + + + // A mapped-policy indicating that an associative container is a set. + // XXX should this be a trait of the form is_set<T> ?? + struct null_mapped_type { }; + + + // Base data structure tag. + struct container_tag + { }; + + // Basic associative-container. + struct associative_container_tag : public container_tag { }; + + // Basic hash. + struct basic_hash_tag : public associative_container_tag { }; + + // Collision-chaining hash. + struct cc_hash_tag : public basic_hash_tag { }; + + // General-probing hash. + struct gp_hash_tag : public basic_hash_tag { }; + + // Basic tree. + struct basic_tree_tag : public associative_container_tag { }; + + // tree. + struct tree_tag : public basic_tree_tag { }; + + // Red-black tree. + struct rb_tree_tag : public tree_tag { }; + + // Splay tree. + struct splay_tree_tag : public tree_tag { }; + + // Ordered-vector tree. + struct ov_tree_tag : public tree_tag { }; + + // trie. + struct trie_tag : public basic_tree_tag { }; + + // PATRICIA trie. + struct pat_trie_tag : public trie_tag { }; + + // List-update. + struct list_update_tag : public associative_container_tag { }; + + // Basic priority-queue. + struct priority_queue_tag : public container_tag { }; + + // Pairing-heap. + struct pairing_heap_tag : public priority_queue_tag { }; + + // Binomial-heap. + struct binomial_heap_tag : public priority_queue_tag { }; + + // Redundant-counter binomial-heap. + struct rc_binomial_heap_tag : public priority_queue_tag { }; + + // Binary-heap (array-based). + struct binary_heap_tag : public priority_queue_tag { }; + + // Thin heap. + struct thin_heap_tag : public priority_queue_tag { }; + + + template<typename Tag> + struct container_traits_base; + + template<> + struct container_traits_base<cc_hash_tag> + { + typedef cc_hash_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<gp_hash_tag> + { + typedef gp_hash_tag container_category; + typedef basic_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<rb_tree_tag> + { + typedef rb_tree_tag container_category; + typedef range_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = true, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = true + }; + }; + + template<> + struct container_traits_base<splay_tree_tag> + { + typedef splay_tree_tag container_category; + typedef range_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = true, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = true + }; + }; + + template<> + struct container_traits_base<ov_tree_tag> + { + typedef ov_tree_tag container_category; + typedef basic_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = true, + erase_can_throw = true, + split_join_can_throw = true, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<pat_trie_tag> + { + typedef pat_trie_tag container_category; + typedef range_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = true, + erase_can_throw = false, + split_join_can_throw = true, + reverse_iteration = true + }; + }; + + template<> + struct container_traits_base<list_update_tag> + { + typedef list_update_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + + template<> + struct container_traits_base<pairing_heap_tag> + { + typedef pairing_heap_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<thin_heap_tag> + { + typedef thin_heap_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<binomial_heap_tag> + { + typedef binomial_heap_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<rc_binomial_heap_tag> + { + typedef rc_binomial_heap_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<binary_heap_tag> + { + typedef binary_heap_tag container_category; + typedef basic_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = true, + reverse_iteration = false + }; + }; + + + // See Matt Austern for the name, S. Meyers MEFC++ #2, others. + template<typename Cntnr> + struct container_traits + : public container_traits_base<typename Cntnr::container_category> + { + typedef Cntnr container_type; + typedef typename Cntnr::container_category container_category; + typedef container_traits_base<container_category> base_type; + typedef typename base_type::invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = base_type::order_preserving, + erase_can_throw = base_type::erase_can_throw, + split_join_can_throw = base_type::split_join_can_throw, + reverse_iteration = base_type::reverse_iteration + }; + }; +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/tree_policy.hpp b/libstdc++/include/ext/pb_ds/tree_policy.hpp new file mode 100644 index 0000000..3c80fc6 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/tree_policy.hpp @@ -0,0 +1,168 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file tree_policy.hpp + * Contains tree-related policies. + */ + +#ifndef PB_DS_TREE_POLICY_HPP +#define PB_DS_TREE_POLICY_HPP + +#include <iterator> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp> + +namespace pb_ds +{ + // A null node updator, indicating that no node updates are required. + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename Cmp_Fn, + typename Allocator> + struct null_tree_node_update + { }; + +#define PB_DS_CLASS_T_DEC \ + template<typename Const_Node_Iterator, class Node_Iterator, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + tree_order_statistics_node_update<Const_Node_Iterator, Node_Iterator, Cmp_Fn, Allocator> + +#define PB_DS_BASE_C_DEC \ + detail::basic_tree_policy_base<Const_Node_Iterator, Node_Iterator, Allocator> + + // Functor updating ranks of entrees. + template<typename Const_Node_Iterator, typename Node_Iterator, + typename Cmp_Fn, typename Allocator> + class tree_order_statistics_node_update : private PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Cmp_Fn cmp_fn; + typedef Allocator allocator; + typedef typename allocator::size_type size_type; + typedef typename base_type::key_type key_type; + typedef typename base_type::const_key_reference const_key_reference; + + typedef size_type metadata_type; + typedef Const_Node_Iterator const_node_iterator; + typedef Node_Iterator node_iterator; + typedef typename const_node_iterator::value_type const_iterator; + typedef typename node_iterator::value_type iterator; + + // Finds an entry by __order. Returns a const_iterator to the + // entry with the __order order, or a const_iterator to the + // container object's end if order is at least the size of the + // container object. + inline const_iterator + find_by_order(size_type order) const; + + // Finds an entry by __order. Returns an iterator to the entry + // with the __order order, or an iterator to the container + // object's end if order is at least the size of the container + // object. + inline iterator + find_by_order(size_type order); + + // Returns the order of a key within a sequence. For exapmle, if + // r_key is the smallest key, this method will return 0; if r_key + // is a key between the smallest and next key, this method will + // return 1; if r_key is a key larger than the largest key, this + // method will return the size of r_c. + inline size_type + order_of_key(const_key_reference r_key) const; + + private: + // Const reference to the container's value-type. + typedef typename base_type::const_reference const_reference; + + // Const pointer to the container's value-type. + typedef typename base_type::const_pointer const_pointer; + + typedef typename allocator::template rebind<metadata_type>::other metadata_rebind; + // Const metadata reference. + typedef typename metadata_rebind::const_reference const_metadata_reference; + + // Metadata reference. + typedef typename metadata_rebind::reference metadata_reference; + + // Returns the const_node_iterator associated with the tree's root node. + virtual const_node_iterator + node_begin() const = 0; + + // Returns the node_iterator associated with the tree's root node. + virtual node_iterator + node_begin() = 0; + + // Returns the const_node_iterator associated with a just-after leaf node. + virtual const_node_iterator + node_end() const = 0; + + // Returns the node_iterator associated with a just-after leaf node. + virtual node_iterator + node_end() = 0; + + // Access to the cmp_fn object. + virtual cmp_fn& + get_cmp_fn() = 0; + + protected: + // Updates the rank of a node through a node_iterator node_it; + // end_nd_it is the end node iterator. + inline void + operator()(node_iterator node_it, const_node_iterator end_nd_it) const; + + virtual + ~tree_order_statistics_node_update(); + }; + +#include <ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC + +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pb_ds/trie_policy.hpp b/libstdc++/include/ext/pb_ds/trie_policy.hpp new file mode 100644 index 0000000..d74bed4 --- /dev/null +++ b/libstdc++/include/ext/pb_ds/trie_policy.hpp @@ -0,0 +1,365 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trie_policy.hpp + * Contains trie-related policies. + */ + +#ifndef PB_DS_TRIE_POLICY_HPP +#define PB_DS_TRIE_POLICY_HPP + +#include <string> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/trie_policy/trie_policy_base.hpp> + +namespace pb_ds +{ + // A null node updator, indicating that no node updates are required. + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename E_Access_Traits, + typename Allocator> + struct null_trie_node_update + { }; + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef detail::static_assert_dumclass<sizeof(detail::static_assert<bool(E)>)> UNIQUE##_static_assert_type + +#define PB_DS_CLASS_T_DEC \ + template<typename String, typename String::value_type Min_E_Val, typename String::value_type Max_E_Val, bool Reverse, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + string_trie_e_access_traits<String, Min_E_Val,Max_E_Val,Reverse,Allocator> + + // Element access traits for string types. + template<typename String = std::string, + typename String::value_type Min_E_Val = detail::__numeric_traits<typename String::value_type>::__min, + typename String::value_type Max_E_Val = detail::__numeric_traits<typename String::value_type>::__max, + bool Reverse = false, + typename Allocator = std::allocator<char> > + struct string_trie_e_access_traits + { + public: + typedef typename Allocator::size_type size_type; + typedef String key_type; + typedef typename Allocator::template rebind<key_type>::other key_rebind; + typedef typename key_rebind::const_reference const_key_reference; + + enum + { + reverse = Reverse + }; + + // Element const iterator type. + typedef typename detail::__conditional_type<Reverse, typename String::const_reverse_iterator, typename String::const_iterator>::__type const_iterator; + + // Element type. + typedef typename std::iterator_traits<const_iterator>::value_type e_type; + + enum + { + min_e_val = Min_E_Val, + max_e_val = Max_E_Val, + max_size = max_e_val - min_e_val + 1 + }; + PB_DS_STATIC_ASSERT(min_max_size, max_size >= 2); + + // Returns a const_iterator to the first element of + // const_key_reference agumnet. + inline static const_iterator + begin(const_key_reference); + + // Returns a const_iterator to the after-last element of + // const_key_reference argument. + inline static const_iterator + end(const_key_reference); + + // Maps an element to a position. + inline static size_type + e_pos(e_type e); + + private: + + inline static const_iterator + begin_imp(const_key_reference, detail::false_type); + + inline static const_iterator + begin_imp(const_key_reference, detail::true_type); + + inline static const_iterator + end_imp(const_key_reference, detail::false_type); + + inline static const_iterator + end_imp(const_key_reference, detail::true_type); + + static detail::integral_constant<int, Reverse> s_rev_ind; + }; + +#include <ext/pb_ds/detail/trie_policy/string_trie_e_access_traits_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Const_Node_Iterator,typename Node_Iterator,class E_Access_Traits, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + trie_prefix_search_node_update<Const_Node_Iterator, Node_Iterator, E_Access_Traits,Allocator> + +#define PB_DS_BASE_C_DEC \ + detail::trie_policy_base<Const_Node_Iterator,Node_Iterator,E_Access_Traits, Allocator> + + // A node updator that allows tries to be searched for the range of + // values that match a certain prefix. + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename E_Access_Traits, + typename Allocator> + class trie_prefix_search_node_update : private PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef typename base_type::key_type key_type; + typedef typename base_type::const_key_reference const_key_reference; + + // Element access traits. + typedef E_Access_Traits e_access_traits; + + // Const element iterator. + typedef typename e_access_traits::const_iterator const_e_iterator; + + // Allocator type. + typedef Allocator allocator; + + // Size type. + typedef typename allocator::size_type size_type; + typedef detail::null_node_metadata metadata_type; + typedef Const_Node_Iterator const_node_iterator; + typedef Node_Iterator node_iterator; + typedef typename const_node_iterator::value_type const_iterator; + typedef typename node_iterator::value_type iterator; + + // Finds the const iterator range corresponding to all values + // whose prefixes match r_key. + std::pair<const_iterator, const_iterator> + prefix_range(const_key_reference) const; + + // Finds the iterator range corresponding to all values whose + // prefixes match r_key. + std::pair<iterator, iterator> + prefix_range(const_key_reference); + + // Finds the const iterator range corresponding to all values + // whose prefixes match [b, e). + std::pair<const_iterator, const_iterator> + prefix_range(const_e_iterator, const_e_iterator) const; + + // Finds the iterator range corresponding to all values whose + // prefixes match [b, e). + std::pair<iterator, iterator> + prefix_range(const_e_iterator, const_e_iterator); + + protected: + // Called to update a node's metadata. + inline void + operator()(node_iterator node_it, const_node_iterator end_nd_it) const; + + private: + // Returns the const iterator associated with the just-after last element. + virtual const_iterator + end() const = 0; + + // Returns the iterator associated with the just-after last element. + virtual iterator + end() = 0; + + // Returns the const_node_iterator associated with the trie's root node. + virtual const_node_iterator + node_begin() const = 0; + + // Returns the node_iterator associated with the trie's root node. + virtual node_iterator + node_begin() = 0; + + // Returns the const_node_iterator associated with a just-after leaf node. + virtual const_node_iterator + node_end() const = 0; + + // Returns the node_iterator associated with a just-after leaf node. + virtual node_iterator + node_end() = 0; + + // Access to the cmp_fn object. + virtual const e_access_traits& + get_e_access_traits() const = 0; + + node_iterator + next_child(node_iterator, const_e_iterator, const_e_iterator, + node_iterator, const e_access_traits&); + }; + +#include <ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp> + +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_C_DEC \ + trie_order_statistics_node_update<Const_Node_Iterator, Node_Iterator,E_Access_Traits, Allocator> + + // Functor updating ranks of entrees. + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename E_Access_Traits, + typename Allocator> + class trie_order_statistics_node_update : private PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef E_Access_Traits e_access_traits; + typedef typename e_access_traits::const_iterator const_e_iterator; + typedef Allocator allocator; + typedef typename allocator::size_type size_type; + typedef typename base_type::key_type key_type; + typedef typename base_type::const_key_reference const_key_reference; + + typedef size_type metadata_type; + typedef Const_Node_Iterator const_node_iterator; + typedef Node_Iterator node_iterator; + typedef typename const_node_iterator::value_type const_iterator; + typedef typename node_iterator::value_type iterator; + + // Finds an entry by __order. Returns a const_iterator to the + // entry with the __order order, or a const_iterator to the + // container object's end if order is at least the size of the + // container object. + inline const_iterator + find_by_order(size_type) const; + + // Finds an entry by __order. Returns an iterator to the entry + // with the __order order, or an iterator to the container + // object's end if order is at least the size of the container + // object. + inline iterator + find_by_order(size_type); + + // Returns the order of a key within a sequence. For exapmle, if + // r_key is the smallest key, this method will return 0; if r_key + // is a key between the smallest and next key, this method will + // return 1; if r_key is a key larger than the largest key, this + // method will return the size of r_c. + inline size_type + order_of_key(const_key_reference) const; + + // Returns the order of a prefix within a sequence. For exapmle, + // if [b, e] is the smallest prefix, this method will return 0; if + // r_key is a key between the smallest and next key, this method + // will return 1; if r_key is a key larger than the largest key, + // this method will return the size of r_c. + inline size_type + order_of_prefix(const_e_iterator, const_e_iterator) const; + + private: + typedef typename base_type::const_reference const_reference; + typedef typename base_type::const_pointer const_pointer; + + typedef typename Allocator::template rebind<metadata_type>::other metadata_rebind; + typedef typename metadata_rebind::const_reference const_metadata_reference; + typedef typename metadata_rebind::reference metadata_reference; + + // Returns true if the container is empty. + virtual bool + empty() const = 0; + + // Returns the iterator associated with the trie's first element. + virtual iterator + begin() = 0; + + // Returns the iterator associated with the trie's + // just-after-last element. + virtual iterator + end() = 0; + + // Returns the const_node_iterator associated with the trie's root node. + virtual const_node_iterator + node_begin() const = 0; + + // Returns the node_iterator associated with the trie's root node. + virtual node_iterator + node_begin() = 0; + + // Returns the const_node_iterator associated with a just-after + // leaf node. + virtual const_node_iterator + node_end() const = 0; + + // Returns the node_iterator associated with a just-after leaf node. + virtual node_iterator + node_end() = 0; + + // Access to the cmp_fn object. + virtual e_access_traits& + get_e_access_traits() = 0; + + protected: + // Updates the rank of a node through a node_iterator node_it; + // end_nd_it is the end node iterator. + inline void + operator()(node_iterator, const_node_iterator) const; + + // Destructor. + virtual + ~trie_order_statistics_node_update(); + }; + +#include <ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC +#undef PB_DS_STATIC_ASSERT + +} // namespace pb_ds + +#endif diff --git a/libstdc++/include/ext/pod_char_traits.h b/libstdc++/include/ext/pod_char_traits.h new file mode 100644 index 0000000..236e349 --- /dev/null +++ b/libstdc++/include/ext/pod_char_traits.h @@ -0,0 +1,187 @@ +// POD character, std::char_traits specialization -*- C++ -*- + +// 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. + +/** @file ext/pod_char_traits.h + * This file is a GNU extension to the Standard C++ Library. + */ + +// Gabriel Dos Reis <gdr@integrable-solutions.net> +// Benjamin Kosnik <bkoz@redhat.com> + +#ifndef _POD_CHAR_TRAITS_H +#define _POD_CHAR_TRAITS_H 1 + +#include <string> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // POD character abstraction. + // NB: The char_type parameter is a subset of int_type, as to allow + // int_type to properly hold the full range of char_type values as + // well as EOF. + /// @brief A POD class that serves as a character abstraction class. + template<typename V, typename I, typename S = mbstate_t> + struct character + { + typedef V value_type; + typedef I int_type; + typedef S state_type; + typedef character<V, I, S> char_type; + + value_type value; + + template<typename V2> + static char_type + from(const V2& v) + { + char_type ret = { static_cast<value_type>(v) }; + return ret; + } + + template<typename V2> + static V2 + to(const char_type& c) + { + V2 ret = { static_cast<V2>(c.value) }; + return ret; + } + + }; + + template<typename V, typename I, typename S> + inline bool + operator==(const character<V, I, S>& lhs, const character<V, I, S>& rhs) + { return lhs.value == rhs.value; } + + template<typename V, typename I, typename S> + inline bool + operator<(const character<V, I, S>& lhs, const character<V, I, S>& rhs) + { return lhs.value < rhs.value; } + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /// char_traits<__gnu_cxx::character> specialization. + template<typename V, typename I, typename S> + struct char_traits<__gnu_cxx::character<V, I, S> > + { + typedef __gnu_cxx::character<V, I, S> char_type; + typedef typename char_type::int_type int_type; + typedef typename char_type::state_type state_type; + typedef fpos<state_type> pos_type; + typedef streamoff off_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (!eq(__s1[__i], __s2[__i])) + return lt(__s1[__i], __s2[__i]) ? -1 : 1; + return 0; + } + + static size_t + length(const char_type* __s) + { + const char_type* __p = __s; + while (__p->value) + ++__p; + return (__p - __s); + } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { + for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) + if (*__p == __a) + return __p; + return 0; + } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { + return static_cast<char_type*>(std::memmove(__s1, __s2, + __n * sizeof(char_type))); + } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { + std::copy(__s2, __s2 + __n, __s1); + return __s1; + } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { + std::fill_n(__s, __n, __a); + return __s; + } + + static char_type + to_char_type(const int_type& __i) + { return char_type::template from(__i); } + + static int_type + to_int_type(const char_type& __c) + { return char_type::template to<int_type>(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() + { + int_type __r = { -1 }; + return __r; + } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? int_type() : __c; } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/pool_allocator.h b/libstdc++/include/ext/pool_allocator.h new file mode 100644 index 0000000..e78bf21 --- /dev/null +++ b/libstdc++/include/ext/pool_allocator.h @@ -0,0 +1,260 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 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. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/pool_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _POOL_ALLOCATOR_H +#define _POOL_ALLOCATOR_H 1 + +#include <bits/c++config.h> +#include <cstdlib> +#include <new> +#include <bits/functexcept.h> +#include <ext/atomicity.h> +#include <ext/concurrence.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + + /** + * @brief Base class for __pool_alloc. + * + * @if maint + * Uses various allocators to fulfill underlying requests (and makes as + * few requests as possible when in default high-speed pool mode). + * + * Important implementation properties: + * 0. If globally mandated, then allocate objects from new + * 1. If the clients request an object of size > _S_max_bytes, the resulting + * object will be obtained directly from new + * 2. In all other cases, we allocate an object of size exactly + * _S_round_up(requested_size). Thus the client has enough size + * information that we can return the object to the proper free list + * without permanently losing part of the object. + * + * @endif + */ + class __pool_alloc_base + { + protected: + + enum { _S_align = 8 }; + enum { _S_max_bytes = 128 }; + enum { _S_free_list_size = (size_t)_S_max_bytes / (size_t)_S_align }; + + union _Obj + { + union _Obj* _M_free_list_link; + char _M_client_data[1]; // The client sees this. + }; + + static _Obj* volatile _S_free_list[_S_free_list_size]; + + // Chunk allocation state. + static char* _S_start_free; + static char* _S_end_free; + static size_t _S_heap_size; + + size_t + _M_round_up(size_t __bytes) + { return ((__bytes + (size_t)_S_align - 1) & ~((size_t)_S_align - 1)); } + + _Obj* volatile* + _M_get_free_list(size_t __bytes); + + __mutex& + _M_get_mutex(); + + // Returns an object of size __n, and optionally adds to size __n + // free list. + void* + _M_refill(size_t __n); + + // Allocates a chunk for nobjs of size size. nobjs may be reduced + // if it is inconvenient to allocate the requested number. + char* + _M_allocate_chunk(size_t __n, int& __nobjs); + }; + + + /// @brief class __pool_alloc. + template<typename _Tp> + class __pool_alloc : private __pool_alloc_base + { + private: + static _Atomic_word _S_force_new; + + 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 __pool_alloc<_Tp1> other; }; + + __pool_alloc() throw() { } + + __pool_alloc(const __pool_alloc&) throw() { } + + template<typename _Tp1> + __pool_alloc(const __pool_alloc<_Tp1>&) throw() { } + + ~__pool_alloc() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + + pointer + allocate(size_type __n, const void* = 0); + + void + deallocate(pointer __p, size_type __n); + }; + + template<typename _Tp> + inline bool + operator==(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) + { return true; } + + template<typename _Tp> + inline bool + operator!=(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) + { return false; } + + template<typename _Tp> + _Atomic_word + __pool_alloc<_Tp>::_S_force_new; + + template<typename _Tp> + _Tp* + __pool_alloc<_Tp>::allocate(size_type __n, const void*) + { + pointer __ret = 0; + if (__builtin_expect(__n != 0, true)) + { + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); + + // If there is a race through here, assume answer from getenv + // will resolve in same direction. Inspired by techniques + // to efficiently support threading found in basic_string.h. + if (_S_force_new == 0) + { + if (std::getenv("GLIBCXX_FORCE_NEW")) + __atomic_add_dispatch(&_S_force_new, 1); + else + __atomic_add_dispatch(&_S_force_new, -1); + } + + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > size_t(_S_max_bytes) || _S_force_new == 1) + __ret = static_cast<_Tp*>(::operator new(__bytes)); + else + { + _Obj* volatile* __free_list = _M_get_free_list(__bytes); + + __scoped_lock sentry(_M_get_mutex()); + _Obj* __restrict__ __result = *__free_list; + if (__builtin_expect(__result == 0, 0)) + __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes))); + else + { + *__free_list = __result->_M_free_list_link; + __ret = reinterpret_cast<_Tp*>(__result); + } + if (__builtin_expect(__ret == 0, 0)) + std::__throw_bad_alloc(); + } + } + return __ret; + } + + template<typename _Tp> + void + __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n) + { + if (__builtin_expect(__n != 0 && __p != 0, true)) + { + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > static_cast<size_t>(_S_max_bytes) || _S_force_new == 1) + ::operator delete(__p); + else + { + _Obj* volatile* __free_list = _M_get_free_list(__bytes); + _Obj* __q = reinterpret_cast<_Obj*>(__p); + + __scoped_lock sentry(_M_get_mutex()); + __q ->_M_free_list_link = *__free_list; + *__free_list = __q; + } + } + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/rb_tree b/libstdc++/include/ext/rb_tree new file mode 100644 index 0000000..22dd7cd --- /dev/null +++ b/libstdc++/include/ext/rb_tree @@ -0,0 +1,98 @@ +// rb_tree extension -*- C++ -*- + +// 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/rb_tree + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _RB_TREE +#define _RB_TREE 1 + +#pragma GCC system_header + +#include <bits/stl_tree.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::_Rb_tree; + using std::allocator; + + // Class rb_tree is not part of the C++ standard. It is provided for + // compatibility with the HP STL. + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template <class _Key, class _Value, class _KeyOfValue, class _Compare, + class _Alloc = allocator<_Value> > + struct rb_tree + : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> + { + typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + + rb_tree(const _Compare& __comp = _Compare(), + const allocator_type& __a = allocator_type()) + : _Base(__comp, __a) { } + + ~rb_tree() { } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/rc_string_base.h b/libstdc++/include/ext/rc_string_base.h new file mode 100644 index 0000000..4eab4c6 --- /dev/null +++ b/libstdc++/include/ext/rc_string_base.h @@ -0,0 +1,717 @@ +// Reference-counted versatile string base -*- C++ -*- + +// Copyright (C) 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. + +/** @file ext/rc_string_base.h + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _RC_STRING_BASE_H +#define _RC_STRING_BASE_H 1 + +#include <ext/atomicity.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /** + * @if maint + * Documentation? What's that? + * Nathan Myers <ncm@cantrip.org>. + * + * A string looks like this: + * + * @code + * [_Rep] + * _M_length + * [__rc_string_base<char_type>] _M_capacity + * _M_dataplus _M_refcount + * _M_p ----------------> unnamed array of char_type + * @endcode + * + * Where the _M_p points to the first character in the string, and + * you cast it to a pointer-to-_Rep and subtract 1 to get a + * pointer to the header. + * + * This approach has the enormous advantage that a string object + * requires only one allocation. All the ugliness is confined + * within a single pair of inline functions, which each compile to + * a single "add" instruction: _Rep::_M_refdata(), and + * __rc_string_base::_M_rep(); and the allocation function which gets a + * block of raw bytes and with room enough and constructs a _Rep + * object at the front. + * + * The reason you want _M_data pointing to the character array and + * not the _Rep is so that the debugger can see the string + * contents. (Probably we should add a non-inline member to get + * the _Rep for the debugger to use, so users can check the actual + * string length.) + * + * Note that the _Rep object is a POD so that you can have a + * static "empty string" _Rep object already "constructed" before + * static constructors have run. The reference-count encoding is + * chosen so that a 0 indicates one reference, so you never try to + * destroy the empty-string _Rep object. + * + * All but the last paragraph is considered pretty conventional + * for a C++ string implementation. + * @endif + */ + template<typename _CharT, typename _Traits, typename _Alloc> + class __rc_string_base + : protected __vstring_utility<_CharT, _Traits, _Alloc> + { + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + + typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base; + typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type; + typedef typename _CharT_alloc_type::size_type size_type; + + private: + // _Rep: string representation + // Invariants: + // 1. String really contains _M_length + 1 characters: due to 21.3.4 + // must be kept null-terminated. + // 2. _M_capacity >= _M_length + // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). + // 3. _M_refcount has three states: + // -1: leaked, one reference, no ref-copies allowed, non-const. + // 0: one reference, non-const. + // n>0: n + 1 references, operations require a lock, const. + // 4. All fields == 0 is an empty string, given the extra storage + // beyond-the-end for a null terminator; thus, the shared + // empty string representation needs no constructor. + struct _Rep + { + union + { + struct + { + size_type _M_length; + size_type _M_capacity; + _Atomic_word _M_refcount; + } _M_info; + + // Only for alignment purposes. + _CharT _M_align; + }; + + typedef typename _Alloc::template rebind<_Rep>::other _Rep_alloc_type; + + _CharT* + _M_refdata() throw() + { return reinterpret_cast<_CharT*>(this + 1); } + + _CharT* + _M_refcopy() throw() + { + __atomic_add_dispatch(&_M_info._M_refcount, 1); + return _M_refdata(); + } // XXX MT + + void + _M_set_length(size_type __n) + { + _M_info._M_refcount = 0; // One reference. + _M_info._M_length = __n; + // grrr. (per 21.3.4) + // You cannot leave those LWG people alone for a second. + traits_type::assign(_M_refdata()[__n], _CharT()); + } + + // Create & Destroy + static _Rep* + _S_create(size_type, size_type, const _Alloc&); + + void + _M_destroy(const _Alloc&) throw(); + + _CharT* + _M_clone(const _Alloc&, size_type __res = 0); + }; + + struct _Rep_empty + : public _Rep + { + _CharT _M_terminal; + }; + + static _Rep_empty _S_empty_rep; + + // The maximum number of individual char_type elements of an + // individual string is determined by _S_max_size. This is the + // value that will be returned by max_size(). (Whereas npos + // is the maximum number of bytes the allocator can allocate.) + // If one was to divvy up the theoretical largest size string, + // with a terminating character and m _CharT elements, it'd + // look like this: + // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) + // + sizeof(_Rep) - 1 + // (NB: last two terms for rounding reasons, see _M_create below) + // Solving for m: + // m = ((npos - 2 * sizeof(_Rep) + 1) / sizeof(_CharT)) - 1 + // In addition, this implementation halfs this amount. + enum { _S_max_size = (((static_cast<size_type>(-1) - 2 * sizeof(_Rep) + + 1) / sizeof(_CharT)) - 1) / 2 }; + + // Data Member (private): + mutable typename _Util_Base::template _Alloc_hider<_Alloc> _M_dataplus; + + void + _M_data(_CharT* __p) + { _M_dataplus._M_p = __p; } + + _Rep* + _M_rep() const + { return &((reinterpret_cast<_Rep*>(_M_data()))[-1]); } + + _CharT* + _M_grab(const _Alloc& __alloc) const + { + return (!_M_is_leaked() && _M_get_allocator() == __alloc) + ? _M_rep()->_M_refcopy() : _M_rep()->_M_clone(__alloc); + } + + void + _M_dispose() + { + if (__exchange_and_add_dispatch(&_M_rep()->_M_info._M_refcount, + -1) <= 0) + _M_rep()->_M_destroy(_M_get_allocator()); + } // XXX MT + + bool + _M_is_leaked() const + { return _M_rep()->_M_info._M_refcount < 0; } + + void + _M_set_sharable() + { _M_rep()->_M_info._M_refcount = 0; } + + void + _M_leak_hard(); + + // _S_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIterator is an integral type + template<typename _InIterator> + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, std::__false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + return _S_construct(__beg, __end, __a, _Tag()); + } + + template<typename _InIterator> + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, std::__true_type) + { return _S_construct(static_cast<size_type>(__beg), + static_cast<value_type>(__end), __a); } + + template<typename _InIterator> + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + return _S_construct_aux(__beg, __end, __a, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template<typename _InIterator> + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + std::input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template<typename _FwdIterator> + static _CharT* + _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, + std::forward_iterator_tag); + + static _CharT* + _S_construct(size_type __req, _CharT __c, const _Alloc& __a); + + public: + size_type + _M_max_size() const + { return size_type(_S_max_size); } + + _CharT* + _M_data() const + { return _M_dataplus._M_p; } + + size_type + _M_length() const + { return _M_rep()->_M_info._M_length; } + + size_type + _M_capacity() const + { return _M_rep()->_M_info._M_capacity; } + + bool + _M_is_shared() const + { return _M_rep()->_M_info._M_refcount > 0; } + + void + _M_set_leaked() + { _M_rep()->_M_info._M_refcount = -1; } + + void + _M_leak() // for use in begin() & non-const op[] + { + if (!_M_is_leaked()) + _M_leak_hard(); + } + + void + _M_set_length(size_type __n) + { _M_rep()->_M_set_length(__n); } + + __rc_string_base() + : _M_dataplus(_Alloc(), _S_empty_rep._M_refcopy()) { } + + __rc_string_base(const _Alloc& __a); + + __rc_string_base(const __rc_string_base& __rcs); + + __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a); + + template<typename _InputIterator> + __rc_string_base(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a); + + ~__rc_string_base() + { _M_dispose(); } + + allocator_type& + _M_get_allocator() + { return _M_dataplus; } + + const allocator_type& + _M_get_allocator() const + { return _M_dataplus; } + + void + _M_swap(__rc_string_base& __rcs); + + void + _M_assign(const __rc_string_base& __rcs); + + void + _M_reserve(size_type __res); + + void + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2); + + void + _M_erase(size_type __pos, size_type __n); + + void + _M_clear() + { _M_erase(size_type(0), _M_length()); } + + bool + _M_compare(const __rc_string_base&) const + { return false; } + }; + + template<typename _CharT, typename _Traits, typename _Alloc> + typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep_empty + __rc_string_base<_CharT, _Traits, _Alloc>::_S_empty_rep; + + template<typename _CharT, typename _Traits, typename _Alloc> + typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep* + __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: + _S_create(size_type __capacity, size_type __old_capacity, + const _Alloc& __alloc) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + if (__capacity > size_type(_S_max_size)) + std::__throw_length_error(__N("__rc_string_base::_Rep::_S_create")); + + // The standard places no restriction on allocating more memory + // than is strictly needed within this layer at the moment or as + // requested by an explicit application call to reserve(). + + // Many malloc implementations perform quite poorly when an + // application attempts to allocate memory in a stepwise fashion + // growing each allocation size by only 1 char. Additionally, + // it makes little sense to allocate less linear memory than the + // natural blocking size of the malloc implementation. + // Unfortunately, we would need a somewhat low-level calculation + // with tuned parameters to get this perfect for any particular + // malloc implementation. Fortunately, generalizations about + // common features seen among implementations seems to suffice. + + // __pagesize need not match the actual VM page size for good + // results in practice, thus we pick a common value on the low + // side. __malloc_header_size is an estimate of the amount of + // overhead per memory allocation (in practice seen N * sizeof + // (void*) where N is 0, 2 or 4). According to folklore, + // picking this value on the high side is better than + // low-balling it (especially when this algorithm is used with + // malloc implementations that allocate memory blocks rounded up + // to a size which is a power of 2). + const size_type __pagesize = 4096; + const size_type __malloc_header_size = 4 * sizeof(void*); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) + { + __capacity = 2 * __old_capacity; + // Never allocate a string bigger than _S_max_size. + if (__capacity > size_type(_S_max_size)) + __capacity = size_type(_S_max_size); + } + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element, plus enough for the _Rep data structure, + // plus sizeof(_Rep) - 1 to upper round to a size multiple of + // sizeof(_Rep). + // Whew. Seemingly so needy, yet so elemental. + size_type __size = ((__capacity + 1) * sizeof(_CharT) + + 2 * sizeof(_Rep) - 1); + + const size_type __adj_size = __size + __malloc_header_size; + if (__adj_size > __pagesize && __capacity > __old_capacity) + { + const size_type __extra = __pagesize - __adj_size % __pagesize; + __capacity += __extra / sizeof(_CharT); + if (__capacity > size_type(_S_max_size)) + __capacity = size_type(_S_max_size); + __size = (__capacity + 1) * sizeof(_CharT) + 2 * sizeof(_Rep) - 1; + } + + // NB: Might throw, but no worries about a leak, mate: _Rep() + // does not throw. + _Rep* __place = _Rep_alloc_type(__alloc).allocate(__size / sizeof(_Rep)); + _Rep* __p = new (__place) _Rep; + __p->_M_info._M_capacity = __capacity; + return __p; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: + _M_destroy(const _Alloc& __a) throw () + { + const size_type __size = ((_M_info._M_capacity + 1) * sizeof(_CharT) + + 2 * sizeof(_Rep) - 1); + _Rep_alloc_type(__a).deallocate(this, __size / sizeof(_Rep)); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: + _M_clone(const _Alloc& __alloc, size_type __res) + { + // Requested capacity of the clone. + const size_type __requested_cap = _M_info._M_length + __res; + _Rep* __r = _Rep::_S_create(__requested_cap, _M_info._M_capacity, + __alloc); + + if (_M_info._M_length) + _S_copy(__r->_M_refdata(), _M_refdata(), _M_info._M_length); + + __r->_M_set_length(_M_info._M_length); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + __rc_string_base<_CharT, _Traits, _Alloc>:: + __rc_string_base(const _Alloc& __a) + : _M_dataplus(__a, _S_construct(size_type(), _CharT(), __a)) { } + + template<typename _CharT, typename _Traits, typename _Alloc> + __rc_string_base<_CharT, _Traits, _Alloc>:: + __rc_string_base(const __rc_string_base& __rcs) + : _M_dataplus(__rcs._M_get_allocator(), + __rcs._M_grab(__rcs._M_get_allocator())) { } + + template<typename _CharT, typename _Traits, typename _Alloc> + __rc_string_base<_CharT, _Traits, _Alloc>:: + __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a) + : _M_dataplus(__a, _S_construct(__n, __c, __a)) { } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InputIterator> + __rc_string_base<_CharT, _Traits, _Alloc>:: + __rc_string_base(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a) + : _M_dataplus(__a, _S_construct(__beg, __end, __a)) { } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_leak_hard() + { + if (_M_is_shared()) + _M_erase(0, 0); + _M_set_leaked(); + } + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + _CharT* + __rc_string_base<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + std::input_iterator_tag) + { + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep._M_refcopy(); + + // Avoid reallocation for common case. + _CharT __buf[128]; + size_type __len = 0; + while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) + { + __buf[__len++] = *__beg; + ++__beg; + } + _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); + _S_copy(__r->_M_refdata(), __buf, __len); + try + { + while (__beg != __end) + { + if (__len == __r->_M_info._M_capacity) + { + // Allocate more space. + _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); + _S_copy(__another->_M_refdata(), __r->_M_refdata(), __len); + __r->_M_destroy(__a); + __r = __another; + } + __r->_M_refdata()[__len++] = *__beg; + ++__beg; + } + } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_set_length(__len); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + _CharT* + __rc_string_base<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + std::forward_iterator_tag) + { + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep._M_refcopy(); + + // NB: Not required, but considered best practice. + if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0)) + std::__throw_logic_error(__N("__rc_string_base::" + "_S_construct NULL not valid")); + + const size_type __dnew = static_cast<size_type>(std::distance(__beg, + __end)); + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); + try + { _S_copy_chars(__r->_M_refdata(), __beg, __end); } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_set_length(__dnew); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + __rc_string_base<_CharT, _Traits, _Alloc>:: + _S_construct(size_type __n, _CharT __c, const _Alloc& __a) + { + if (__n == 0 && __a == _Alloc()) + return _S_empty_rep._M_refcopy(); + + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); + if (__n) + _S_assign(__r->_M_refdata(), __n, __c); + + __r->_M_set_length(__n); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_swap(__rc_string_base& __rcs) + { + if (_M_is_leaked()) + _M_set_sharable(); + if (__rcs._M_is_leaked()) + __rcs._M_set_sharable(); + + _CharT* __tmp = _M_data(); + _M_data(__rcs._M_data()); + __rcs._M_data(__tmp); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<allocator_type>::_S_do_it(_M_get_allocator(), + __rcs._M_get_allocator()); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_assign(const __rc_string_base& __rcs) + { + if (_M_rep() != __rcs._M_rep()) + { + _CharT* __tmp = __rcs._M_grab(_M_get_allocator()); + _M_dispose(); + _M_data(__tmp); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_reserve(size_type __res) + { + // Make sure we don't shrink below the current size. + if (__res < _M_length()) + __res = _M_length(); + + if (__res != _M_capacity() || _M_is_shared()) + { + _CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(), + __res - _M_length()); + _M_dispose(); + _M_data(__tmp); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2) + { + const size_type __how_much = _M_length() - __pos - __len1; + + _Rep* __r = _Rep::_S_create(_M_length() + __len2 - __len1, + _M_capacity(), _M_get_allocator()); + + if (__pos) + _S_copy(__r->_M_refdata(), _M_data(), __pos); + if (__s && __len2) + _S_copy(__r->_M_refdata() + __pos, __s, __len2); + if (__how_much) + _S_copy(__r->_M_refdata() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_dispose(); + _M_data(__r->_M_refdata()); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_erase(size_type __pos, size_type __n) + { + const size_type __new_size = _M_length() - __n; + const size_type __how_much = _M_length() - __pos - __n; + + if (_M_is_shared()) + { + // Must reallocate. + _Rep* __r = _Rep::_S_create(__new_size, _M_capacity(), + _M_get_allocator()); + + if (__pos) + _S_copy(__r->_M_refdata(), _M_data(), __pos); + if (__how_much) + _S_copy(__r->_M_refdata() + __pos, + _M_data() + __pos + __n, __how_much); + + _M_dispose(); + _M_data(__r->_M_refdata()); + } + else if (__how_much && __n) + { + // Work in-place. + _S_move(_M_data() + __pos, + _M_data() + __pos + __n, __how_much); + } + + _M_rep()->_M_set_length(__new_size); + } + + template<> + inline bool + __rc_string_base<char, std::char_traits<char>, + std::allocator<char> >:: + _M_compare(const __rc_string_base& __rcs) const + { + if (_M_rep() == __rcs._M_rep()) + return true; + return false; + } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + inline bool + __rc_string_base<wchar_t, std::char_traits<wchar_t>, + std::allocator<wchar_t> >:: + _M_compare(const __rc_string_base& __rcs) const + { + if (_M_rep() == __rcs._M_rep()) + return true; + return false; + } +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _RC_STRING_BASE_H */ diff --git a/libstdc++/include/ext/rope b/libstdc++/include/ext/rope new file mode 100644 index 0000000..0cfd21e --- /dev/null +++ b/libstdc++/include/ext/rope @@ -0,0 +1,2913 @@ +// SGI's rope class -*- C++ -*- + +// Copyright (C) 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. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/rope + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _ROPE +#define _ROPE 1 + +#include <bits/stl_algobase.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_algo.h> +#include <bits/stl_function.h> +#include <bits/stl_numeric.h> +#include <bits/allocator.h> +#include <ext/hash_fun.h> + +# ifdef __GC +# define __GC_CONST const +# else +# include <bits/gthr.h> +# define __GC_CONST // constant except for deallocation +# endif + +#include <ext/memory> // For uninitialized_copy_n + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + namespace __detail + { + enum { _S_max_rope_depth = 45 }; + enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; + } // namespace __detail + + using std::size_t; + using std::ptrdiff_t; + using std::allocator; + using std::iterator; + using std::reverse_iterator; + using std::_Destroy; + + // The _S_eos function is used for those functions that + // convert to/from C-like strings to detect the end of the string. + + // The end-of-C-string character. + // This is what the draft standard says it should be. + template <class _CharT> + inline _CharT + _S_eos(_CharT*) + { return _CharT(); } + + // Test for basic character types. + // For basic character types leaves having a trailing eos. + template <class _CharT> + inline bool + _S_is_basic_char_type(_CharT*) + { return false; } + + template <class _CharT> + inline bool + _S_is_one_byte_char_type(_CharT*) + { return false; } + + inline bool + _S_is_basic_char_type(char*) + { return true; } + + inline bool + _S_is_one_byte_char_type(char*) + { return true; } + + inline bool + _S_is_basic_char_type(wchar_t*) + { return true; } + + // Store an eos iff _CharT is a basic character type. + // Do not reference _S_eos if it isn't. + template <class _CharT> + inline void + _S_cond_store_eos(_CharT&) { } + + inline void + _S_cond_store_eos(char& __c) + { __c = 0; } + + inline void + _S_cond_store_eos(wchar_t& __c) + { __c = 0; } + + // char_producers are logically functions that generate a section of + // a string. These can be convereted to ropes. The resulting rope + // invokes the char_producer on demand. This allows, for example, + // files to be viewed as ropes without reading the entire file. + template <class _CharT> + class char_producer + { + public: + virtual ~char_producer() { }; + + virtual void + operator()(size_t __start_pos, size_t __len, + _CharT* __buffer) = 0; + // Buffer should really be an arbitrary output iterator. + // That way we could flatten directly into an ostream, etc. + // This is thoroughly impossible, since iterator types don't + // have runtime descriptions. + }; + + // Sequence buffers: + // + // Sequence must provide an append operation that appends an + // array to the sequence. Sequence buffers are useful only if + // appending an entire array is cheaper than appending element by element. + // This is true for many string representations. + // This should perhaps inherit from ostream<sequence::value_type> + // and be implemented correspondingly, so that they can be used + // for formatted. For the sake of portability, we don't do this yet. + // + // For now, sequence buffers behave as output iterators. But they also + // behave a little like basic_ostringstream<sequence::value_type> and a + // little like containers. + + template<class _Sequence, size_t _Buf_sz = 100> + class sequence_buffer + : public iterator<std::output_iterator_tag, void, void, void, void> + { + public: + typedef typename _Sequence::value_type value_type; + protected: + _Sequence* _M_prefix; + value_type _M_buffer[_Buf_sz]; + size_t _M_buf_count; + public: + + void + flush() + { + _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); + _M_buf_count = 0; + } + + ~sequence_buffer() + { flush(); } + + sequence_buffer() + : _M_prefix(0), _M_buf_count(0) { } + + sequence_buffer(const sequence_buffer& __x) + { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + } + + sequence_buffer(sequence_buffer& __x) + { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + } + + sequence_buffer(_Sequence& __s) + : _M_prefix(&__s), _M_buf_count(0) { } + + sequence_buffer& + operator=(sequence_buffer& __x) + { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + return *this; + } + + sequence_buffer& + operator=(const sequence_buffer& __x) + { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + return *this; + } + + void + push_back(value_type __x) + { + if (_M_buf_count < _Buf_sz) + { + _M_buffer[_M_buf_count] = __x; + ++_M_buf_count; + } + else + { + flush(); + _M_buffer[0] = __x; + _M_buf_count = 1; + } + } + + void + append(value_type* __s, size_t __len) + { + if (__len + _M_buf_count <= _Buf_sz) + { + size_t __i = _M_buf_count; + for (size_t __j = 0; __j < __len; __i++, __j++) + _M_buffer[__i] = __s[__j]; + _M_buf_count += __len; + } + else if (0 == _M_buf_count) + _M_prefix->append(__s, __s + __len); + else + { + flush(); + append(__s, __len); + } + } + + sequence_buffer& + write(value_type* __s, size_t __len) + { + append(__s, __len); + return *this; + } + + sequence_buffer& + put(value_type __x) + { + push_back(__x); + return *this; + } + + sequence_buffer& + operator=(const value_type& __rhs) + { + push_back(__rhs); + return *this; + } + + sequence_buffer& + operator*() + { return *this; } + + sequence_buffer& + operator++() + { return *this; } + + sequence_buffer + operator++(int) + { return *this; } + }; + + // The following should be treated as private, at least for now. + template<class _CharT> + class _Rope_char_consumer + { + public: + // If we had member templates, these should not be virtual. + // For now we need to use run-time parametrization where + // compile-time would do. Hence this should all be private + // for now. + // The symmetry with char_producer is accidental and temporary. + virtual ~_Rope_char_consumer() { }; + + virtual bool + operator()(const _CharT* __buffer, size_t __len) = 0; + }; + + // First a lot of forward declarations. The standard seems to require + // much stricter "declaration before use" than many of the implementations + // that preceded it. + template<class _CharT, class _Alloc = allocator<_CharT> > + class rope; + + template<class _CharT, class _Alloc> + struct _Rope_RopeConcatenation; + + template<class _CharT, class _Alloc> + struct _Rope_RopeLeaf; + + template<class _CharT, class _Alloc> + struct _Rope_RopeFunction; + + template<class _CharT, class _Alloc> + struct _Rope_RopeSubstring; + + template<class _CharT, class _Alloc> + class _Rope_iterator; + + template<class _CharT, class _Alloc> + class _Rope_const_iterator; + + template<class _CharT, class _Alloc> + class _Rope_char_ref_proxy; + + template<class _CharT, class _Alloc> + class _Rope_char_ptr_proxy; + + template<class _CharT, class _Alloc> + bool + operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + _Rope_const_iterator<_CharT, _Alloc> + operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, + ptrdiff_t __n); + + template<class _CharT, class _Alloc> + _Rope_const_iterator<_CharT, _Alloc> + operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, + ptrdiff_t __n); + + template<class _CharT, class _Alloc> + _Rope_const_iterator<_CharT, _Alloc> + operator+(ptrdiff_t __n, + const _Rope_const_iterator<_CharT, _Alloc>& __x); + + template<class _CharT, class _Alloc> + bool + operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + bool + operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + ptrdiff_t + operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + _Rope_iterator<_CharT, _Alloc> + operator-(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); + + template<class _CharT, class _Alloc> + _Rope_iterator<_CharT, _Alloc> + operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); + + template<class _CharT, class _Alloc> + _Rope_iterator<_CharT, _Alloc> + operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x); + + template<class _CharT, class _Alloc> + bool + operator==(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + bool + operator<(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + ptrdiff_t + operator-(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right); + + template<class _CharT, class _Alloc> + rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, const _CharT* __right); + + template<class _CharT, class _Alloc> + rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, _CharT __right); + + // Some helpers, so we can use power on ropes. + // See below for why this isn't local to the implementation. + + // This uses a nonstandard refcount convention. + // The result has refcount 0. + template<class _CharT, class _Alloc> + struct _Rope_Concat_fn + : public std::binary_function<rope<_CharT, _Alloc>, rope<_CharT, _Alloc>, + rope<_CharT, _Alloc> > + { + rope<_CharT, _Alloc> + operator()(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return __x + __y; } + }; + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc> + identity_element(_Rope_Concat_fn<_CharT, _Alloc>) + { return rope<_CharT, _Alloc>(); } + + // Class _Refcount_Base provides a type, _RC_t, a data member, + // _M_ref_count, and member functions _M_incr and _M_decr, which perform + // atomic preincrement/predecrement. The constructor initializes + // _M_ref_count. + struct _Refcount_Base + { + // The type _RC_t + typedef size_t _RC_t; + + // The data member _M_ref_count + volatile _RC_t _M_ref_count; + + // Constructor + __gthread_mutex_t _M_ref_count_lock; + + _Refcount_Base(_RC_t __n) : _M_ref_count(__n), _M_ref_count_lock() + { +#ifdef __GTHREAD_MUTEX_INIT + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + _M_ref_count_lock = __tmp; +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) + __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock); +#else +#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org. +#endif + } + + void + _M_incr() + { + __gthread_mutex_lock(&_M_ref_count_lock); + ++_M_ref_count; + __gthread_mutex_unlock(&_M_ref_count_lock); + } + + _RC_t + _M_decr() + { + __gthread_mutex_lock(&_M_ref_count_lock); + volatile _RC_t __tmp = --_M_ref_count; + __gthread_mutex_unlock(&_M_ref_count_lock); + return __tmp; + } + }; + + // + // What follows should really be local to rope. Unfortunately, + // that doesn't work, since it makes it impossible to define generic + // equality on rope iterators. According to the draft standard, the + // template parameters for such an equality operator cannot be inferred + // from the occurrence of a member class as a parameter. + // (SGI compilers in fact allow this, but the __result wouldn't be + // portable.) + // Similarly, some of the static member functions are member functions + // only to avoid polluting the global namespace, and to circumvent + // restrictions on type inference for template functions. + // + + // + // The internal data structure for representing a rope. This is + // private to the implementation. A rope is really just a pointer + // to one of these. + // + // A few basic functions for manipulating this data structure + // are members of _RopeRep. Most of the more complex algorithms + // are implemented as rope members. + // + // Some of the static member functions of _RopeRep have identically + // named functions in rope that simply invoke the _RopeRep versions. + +#define __ROPE_DEFINE_ALLOCS(__a) \ + __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ + typedef _Rope_RopeConcatenation<_CharT,__a> __C; \ + __ROPE_DEFINE_ALLOC(__C,_C) \ + typedef _Rope_RopeLeaf<_CharT,__a> __L; \ + __ROPE_DEFINE_ALLOC(__L,_L) \ + typedef _Rope_RopeFunction<_CharT,__a> __F; \ + __ROPE_DEFINE_ALLOC(__F,_F) \ + typedef _Rope_RopeSubstring<_CharT,__a> __S; \ + __ROPE_DEFINE_ALLOC(__S,_S) + + // Internal rope nodes potentially store a copy of the allocator + // instance used to allocate them. This is mostly redundant. + // But the alternative would be to pass allocator instances around + // in some form to nearly all internal functions, since any pointer + // assignment may result in a zero reference count and thus require + // deallocation. + +#define __STATIC_IF_SGI_ALLOC /* not static */ + + template <class _CharT, class _Alloc> + struct _Rope_rep_base + : public _Alloc + { + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast<const _Alloc*>(this); } + + _Rope_rep_base(size_t __size, const allocator_type&) + : _M_size(__size) { } + + size_t _M_size; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc::template rebind<_Tp>::other __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc().allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc().deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +# undef __ROPE_DEFINE_ALLOC + }; + + template<class _CharT, class _Alloc> + struct _Rope_RopeRep + : public _Rope_rep_base<_CharT, _Alloc> +# ifndef __GC + , _Refcount_Base +# endif + { + public: + __detail::_Tag _M_tag:8; + bool _M_is_balanced:8; + unsigned char _M_depth; + __GC_CONST _CharT* _M_c_string; + __gthread_mutex_t _M_c_string_lock; + /* Flattened version of string, if needed. */ + /* typically 0. */ + /* If it's not 0, then the memory is owned */ + /* by this node. */ + /* In the case of a leaf, this may point to */ + /* the same memory as the data field. */ + typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type + allocator_type; + + using _Rope_rep_base<_CharT, _Alloc>::get_allocator; + + _Rope_RopeRep(__detail::_Tag __t, int __d, bool __b, size_t __size, + allocator_type __a) + : _Rope_rep_base<_CharT, _Alloc>(__size, __a), +#ifndef __GC + _Refcount_Base(1), +#endif + _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0) +#ifdef __GTHREAD_MUTEX_INIT + { + // Do not copy a POSIX/gthr mutex once in use. However, bits are bits. + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + _M_c_string_lock = __tmp; + } +#else + { __GTHREAD_MUTEX_INIT_FUNCTION (&_M_c_string_lock); } +#endif +#ifdef __GC + void + _M_incr () { } +#endif + static void + _S_free_string(__GC_CONST _CharT*, size_t __len, + allocator_type __a); +#define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a); + // Deallocate data section of a leaf. + // This shouldn't be a member function. + // But its hard to do anything else at the + // moment, because it's templatized w.r.t. + // an allocator. + // Does nothing if __GC is defined. +#ifndef __GC + void _M_free_c_string(); + void _M_free_tree(); + // Deallocate t. Assumes t is not 0. + void + _M_unref_nonnil() + { + if (0 == _M_decr()) + _M_free_tree(); + } + + void + _M_ref_nonnil() + { _M_incr(); } + + static void + _S_unref(_Rope_RopeRep* __t) + { + if (0 != __t) + __t->_M_unref_nonnil(); + } + + static void + _S_ref(_Rope_RopeRep* __t) + { + if (0 != __t) + __t->_M_incr(); + } + + static void + _S_free_if_unref(_Rope_RopeRep* __t) + { + if (0 != __t && 0 == __t->_M_ref_count) + __t->_M_free_tree(); + } +# else /* __GC */ + void _M_unref_nonnil() { } + void _M_ref_nonnil() { } + static void _S_unref(_Rope_RopeRep*) { } + static void _S_ref(_Rope_RopeRep*) { } + static void _S_free_if_unref(_Rope_RopeRep*) { } +# endif +protected: + _Rope_RopeRep& + operator=(const _Rope_RopeRep&); + + _Rope_RopeRep(const _Rope_RopeRep&); + }; + + template<class _CharT, class _Alloc> + struct _Rope_RopeLeaf + : public _Rope_RopeRep<_CharT, _Alloc> + { + public: + // Apparently needed by VC++ + // The data fields of leaves are allocated with some + // extra space, to accommodate future growth and for basic + // character types, to hold a trailing eos character. + enum { _S_alloc_granularity = 8 }; + + static size_t + _S_rounded_up_size(size_t __n) + { + size_t __size_with_eos; + + if (_S_is_basic_char_type((_CharT*)0)) + __size_with_eos = __n + 1; + else + __size_with_eos = __n; +#ifdef __GC + return __size_with_eos; +#else + // Allow slop for in-place expansion. + return ((__size_with_eos + size_t(_S_alloc_granularity) - 1) + &~ (size_t(_S_alloc_granularity) - 1)); +#endif + } + __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */ + /* The allocated size is */ + /* _S_rounded_up_size(size), except */ + /* in the GC case, in which it */ + /* doesn't matter. */ + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + + _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, + allocator_type __a) + : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_leaf, 0, true, + __size, __a), _M_data(__d) + { + if (_S_is_basic_char_type((_CharT *)0)) + { + // already eos terminated. + this->_M_c_string = __d; + } + } + // The constructor assumes that d has been allocated with + // the proper allocator and the properly padded size. + // In contrast, the destructor deallocates the data: +#ifndef __GC + ~_Rope_RopeLeaf() throw() + { + if (_M_data != this->_M_c_string) + this->_M_free_c_string(); + + __STL_FREE_STRING(_M_data, this->_M_size, this->get_allocator()); + } +#endif +protected: + _Rope_RopeLeaf& + operator=(const _Rope_RopeLeaf&); + + _Rope_RopeLeaf(const _Rope_RopeLeaf&); + }; + + template<class _CharT, class _Alloc> + struct _Rope_RopeConcatenation + : public _Rope_RopeRep<_CharT, _Alloc> + { + public: + _Rope_RopeRep<_CharT, _Alloc>* _M_left; + _Rope_RopeRep<_CharT, _Alloc>* _M_right; + + typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type + allocator_type; + + _Rope_RopeConcatenation(_Rope_RopeRep<_CharT, _Alloc>* __l, + _Rope_RopeRep<_CharT, _Alloc>* __r, + allocator_type __a) + : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_concat, + std::max(__l->_M_depth, + __r->_M_depth) + 1, + false, + __l->_M_size + __r->_M_size, __a), + _M_left(__l), _M_right(__r) + { } +#ifndef __GC + ~_Rope_RopeConcatenation() throw() + { + this->_M_free_c_string(); + _M_left->_M_unref_nonnil(); + _M_right->_M_unref_nonnil(); + } +#endif +protected: + _Rope_RopeConcatenation& + operator=(const _Rope_RopeConcatenation&); + + _Rope_RopeConcatenation(const _Rope_RopeConcatenation&); + }; + + template<class _CharT, class _Alloc> + struct _Rope_RopeFunction + : public _Rope_RopeRep<_CharT, _Alloc> + { + public: + char_producer<_CharT>* _M_fn; +#ifndef __GC + bool _M_delete_when_done; // Char_producer is owned by the + // rope and should be explicitly + // deleted when the rope becomes + // inaccessible. +#else + // In the GC case, we either register the rope for + // finalization, or not. Thus the field is unnecessary; + // the information is stored in the collector data structures. + // We do need a finalization procedure to be invoked by the + // collector. + static void + _S_fn_finalization_proc(void * __tree, void *) + { delete ((_Rope_RopeFunction *)__tree) -> _M_fn; } +#endif + typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type + allocator_type; + + _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, + bool __d, allocator_type __a) + : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_function, 0, true, __size, __a) + , _M_fn(__f) +#ifndef __GC + , _M_delete_when_done(__d) +#endif + { +#ifdef __GC + if (__d) + { + GC_REGISTER_FINALIZER(this, _Rope_RopeFunction:: + _S_fn_finalization_proc, 0, 0, 0); + } +#endif + } +#ifndef __GC + ~_Rope_RopeFunction() throw() + { + this->_M_free_c_string(); + if (_M_delete_when_done) + delete _M_fn; + } +# endif + protected: + _Rope_RopeFunction& + operator=(const _Rope_RopeFunction&); + + _Rope_RopeFunction(const _Rope_RopeFunction&); + }; + // Substring results are usually represented using just + // concatenation nodes. But in the case of very long flat ropes + // or ropes with a functional representation that isn't practical. + // In that case, we represent the __result as a special case of + // RopeFunction, whose char_producer points back to the rope itself. + // In all cases except repeated substring operations and + // deallocation, we treat the __result as a RopeFunction. + template<class _CharT, class _Alloc> + struct _Rope_RopeSubstring + : public _Rope_RopeFunction<_CharT, _Alloc>, + public char_producer<_CharT> + { + public: + // XXX this whole class should be rewritten. + _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 + size_t _M_start; + + virtual void + operator()(size_t __start_pos, size_t __req_len, + _CharT* __buffer) + { + switch(_M_base->_M_tag) + { + case __detail::_S_function: + case __detail::_S_substringfn: + { + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; + (*__fn)(__start_pos + _M_start, __req_len, __buffer); + } + break; + case __detail::_S_leaf: + { + __GC_CONST _CharT* __s = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data; + uninitialized_copy_n(__s + __start_pos + _M_start, __req_len, + __buffer); + } + break; + default: + break; + } + } + + typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type + allocator_type; + + _Rope_RopeSubstring(_Rope_RopeRep<_CharT, _Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + : _Rope_RopeFunction<_CharT, _Alloc>(this, __l, false, __a), + char_producer<_CharT>(), _M_base(__b), _M_start(__s) + { +#ifndef __GC + _M_base->_M_ref_nonnil(); +#endif + this->_M_tag = __detail::_S_substringfn; + } + virtual ~_Rope_RopeSubstring() throw() + { +#ifndef __GC + _M_base->_M_unref_nonnil(); + // _M_free_c_string(); -- done by parent class +#endif + } + }; + + // Self-destructing pointers to Rope_rep. + // These are not conventional smart pointers. Their + // only purpose in life is to ensure that unref is called + // on the pointer either at normal exit or if an exception + // is raised. It is the caller's responsibility to + // adjust reference counts when these pointers are initialized + // or assigned to. (This convention significantly reduces + // the number of potentially expensive reference count + // updates.) +#ifndef __GC + template<class _CharT, class _Alloc> + struct _Rope_self_destruct_ptr + { + _Rope_RopeRep<_CharT, _Alloc>* _M_ptr; + + ~_Rope_self_destruct_ptr() + { _Rope_RopeRep<_CharT, _Alloc>::_S_unref(_M_ptr); } +#ifdef __EXCEPTIONS + _Rope_self_destruct_ptr() : _M_ptr(0) { }; +#else + _Rope_self_destruct_ptr() { }; +#endif + _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT, _Alloc>* __p) + : _M_ptr(__p) { } + + _Rope_RopeRep<_CharT, _Alloc>& + operator*() + { return *_M_ptr; } + + _Rope_RopeRep<_CharT, _Alloc>* + operator->() + { return _M_ptr; } + + operator _Rope_RopeRep<_CharT, _Alloc>*() + { return _M_ptr; } + + _Rope_self_destruct_ptr& + operator=(_Rope_RopeRep<_CharT, _Alloc>* __x) + { _M_ptr = __x; return *this; } + }; +#endif + + // Dereferencing a nonconst iterator has to return something + // that behaves almost like a reference. It's not possible to + // return an actual reference since assignment requires extra + // work. And we would get into the same problems as with the + // CD2 version of basic_string. + template<class _CharT, class _Alloc> + class _Rope_char_ref_proxy + { + friend class rope<_CharT, _Alloc>; + friend class _Rope_iterator<_CharT, _Alloc>; + friend class _Rope_char_ptr_proxy<_CharT, _Alloc>; +#ifdef __GC + typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr; +#else + typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr; +#endif + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + typedef rope<_CharT, _Alloc> _My_rope; + size_t _M_pos; + _CharT _M_current; + bool _M_current_valid; + _My_rope* _M_root; // The whole rope. + public: + _Rope_char_ref_proxy(_My_rope* __r, size_t __p) + : _M_pos(__p), _M_current(), _M_current_valid(false), _M_root(__r) { } + + _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) + : _M_pos(__x._M_pos), _M_current(__x._M_current), + _M_current_valid(false), _M_root(__x._M_root) { } + + // Don't preserve cache if the reference can outlive the + // expression. We claim that's not possible without calling + // a copy constructor or generating reference to a proxy + // reference. We declare the latter to have undefined semantics. + _Rope_char_ref_proxy(_My_rope* __r, size_t __p, _CharT __c) + : _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) { } + + inline operator _CharT () const; + + _Rope_char_ref_proxy& + operator=(_CharT __c); + + _Rope_char_ptr_proxy<_CharT, _Alloc> operator&() const; + + _Rope_char_ref_proxy& + operator=(const _Rope_char_ref_proxy& __c) + { return operator=((_CharT)__c); } + }; + + template<class _CharT, class __Alloc> + inline void + swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, + _Rope_char_ref_proxy <_CharT, __Alloc > __b) + { + _CharT __tmp = __a; + __a = __b; + __b = __tmp; + } + + template<class _CharT, class _Alloc> + class _Rope_char_ptr_proxy + { + // XXX this class should be rewritten. + friend class _Rope_char_ref_proxy<_CharT, _Alloc>; + size_t _M_pos; + rope<_CharT,_Alloc>* _M_root; // The whole rope. + public: + _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) { } + + _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) { } + + _Rope_char_ptr_proxy() { } + + _Rope_char_ptr_proxy(_CharT* __x) + : _M_root(0), _M_pos(0) { } + + _Rope_char_ptr_proxy& + operator=(const _Rope_char_ptr_proxy& __x) + { + _M_pos = __x._M_pos; + _M_root = __x._M_root; + return *this; + } + + template<class _CharT2, class _Alloc2> + friend bool + operator==(const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __x, + const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __y); + + _Rope_char_ref_proxy<_CharT, _Alloc> operator*() const + { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root, _M_pos); } + }; + + // Rope iterators: + // Unlike in the C version, we cache only part of the stack + // for rope iterators, since they must be efficiently copyable. + // When we run out of cache, we have to reconstruct the iterator + // value. + // Pointers from iterators are not included in reference counts. + // Iterators are assumed to be thread private. Ropes can + // be shared. + + template<class _CharT, class _Alloc> + class _Rope_iterator_base + : public iterator<std::random_access_iterator_tag, _CharT> + { + friend class rope<_CharT, _Alloc>; + public: + typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + // Borland doesn't want this to be protected. + protected: + enum { _S_path_cache_len = 4 }; // Must be <= 9. + enum { _S_iterator_buf_len = 15 }; + size_t _M_current_pos; + _RopeRep* _M_root; // The whole rope. + size_t _M_leaf_pos; // Starting position for current leaf + __GC_CONST _CharT* _M_buf_start; + // Buffer possibly + // containing current char. + __GC_CONST _CharT* _M_buf_ptr; + // Pointer to current char in buffer. + // != 0 ==> buffer valid. + __GC_CONST _CharT* _M_buf_end; + // One past __last valid char in buffer. + // What follows is the path cache. We go out of our + // way to make this compact. + // Path_end contains the bottom section of the path from + // the root to the current leaf. + const _RopeRep* _M_path_end[_S_path_cache_len]; + int _M_leaf_index; // Last valid __pos in path_end; + // _M_path_end[0] ... _M_path_end[leaf_index-1] + // point to concatenation nodes. + unsigned char _M_path_directions; + // (path_directions >> __i) & 1 is 1 + // iff we got from _M_path_end[leaf_index - __i - 1] + // to _M_path_end[leaf_index - __i] by going to the + // __right. Assumes path_cache_len <= 9. + _CharT _M_tmp_buf[_S_iterator_buf_len]; + // Short buffer for surrounding chars. + // This is useful primarily for + // RopeFunctions. We put the buffer + // here to avoid locking in the + // multithreaded case. + // The cached path is generally assumed to be valid + // only if the buffer is valid. + static void _S_setbuf(_Rope_iterator_base& __x); + // Set buffer contents given + // path cache. + static void _S_setcache(_Rope_iterator_base& __x); + // Set buffer contents and + // path cache. + static void _S_setcache_for_incr(_Rope_iterator_base& __x); + // As above, but assumes path + // cache is valid for previous posn. + _Rope_iterator_base() { } + + _Rope_iterator_base(_RopeRep* __root, size_t __pos) + : _M_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) { } + + void _M_incr(size_t __n); + void _M_decr(size_t __n); + public: + size_t + index() const + { return _M_current_pos; } + + _Rope_iterator_base(const _Rope_iterator_base& __x) + { + if (0 != __x._M_buf_ptr) + *this = __x; + else + { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + } + }; + + template<class _CharT, class _Alloc> + class _Rope_iterator; + + template<class _CharT, class _Alloc> + class _Rope_const_iterator + : public _Rope_iterator_base<_CharT, _Alloc> + { + friend class rope<_CharT, _Alloc>; + protected: + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + // The one from the base class may not be directly visible. + _Rope_const_iterator(const _RopeRep* __root, size_t __pos) + : _Rope_iterator_base<_CharT, _Alloc>(const_cast<_RopeRep*>(__root), + __pos) + // Only nonconst iterators modify root ref count + { } + public: + typedef _CharT reference; // Really a value. Returning a reference + // Would be a mess, since it would have + // to be included in refcount. + typedef const _CharT* pointer; + + public: + _Rope_const_iterator() { }; + + _Rope_const_iterator(const _Rope_const_iterator& __x) + : _Rope_iterator_base<_CharT,_Alloc>(__x) { } + + _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); + + _Rope_const_iterator(const rope<_CharT, _Alloc>& __r, size_t __pos) + : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) { } + + _Rope_const_iterator& + operator=(const _Rope_const_iterator& __x) + { + if (0 != __x._M_buf_ptr) + *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x; + else + { + this->_M_current_pos = __x._M_current_pos; + this->_M_root = __x._M_root; + this->_M_buf_ptr = 0; + } + return(*this); + } + + reference + operator*() + { + if (0 == this->_M_buf_ptr) + _S_setcache(*this); + return *this->_M_buf_ptr; + } + + // Without this const version, Rope iterators do not meet the + // requirements of an Input Iterator. + reference + operator*() const + { + return *const_cast<_Rope_const_iterator&>(*this); + } + + _Rope_const_iterator& + operator++() + { + __GC_CONST _CharT* __next; + if (0 != this->_M_buf_ptr + && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end) + { + this->_M_buf_ptr = __next; + ++this->_M_current_pos; + } + else + this->_M_incr(1); + return *this; + } + + _Rope_const_iterator& + operator+=(ptrdiff_t __n) + { + if (__n >= 0) + this->_M_incr(__n); + else + this->_M_decr(-__n); + return *this; + } + + _Rope_const_iterator& + operator--() + { + this->_M_decr(1); + return *this; + } + + _Rope_const_iterator& + operator-=(ptrdiff_t __n) + { + if (__n >= 0) + this->_M_decr(__n); + else + this->_M_incr(-__n); + return *this; + } + + _Rope_const_iterator + operator++(int) + { + size_t __old_pos = this->_M_current_pos; + this->_M_incr(1); + return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos); + // This makes a subsequent dereference expensive. + // Perhaps we should instead copy the iterator + // if it has a valid cache? + } + + _Rope_const_iterator + operator--(int) + { + size_t __old_pos = this->_M_current_pos; + this->_M_decr(1); + return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos); + } + + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2, _Alloc2> + operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + ptrdiff_t __n); + + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2, _Alloc2> + operator+(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + ptrdiff_t __n); + + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2, _Alloc2> + operator+(ptrdiff_t __n, + const _Rope_const_iterator<_CharT2, _Alloc2>& __x); + + reference + operator[](size_t __n) + { return rope<_CharT, _Alloc>::_S_fetch(this->_M_root, + this->_M_current_pos + __n); } + + template<class _CharT2, class _Alloc2> + friend bool + operator==(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + const _Rope_const_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend bool + operator<(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + const _Rope_const_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend ptrdiff_t + operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + const _Rope_const_iterator<_CharT2, _Alloc2>& __y); + }; + + template<class _CharT, class _Alloc> + class _Rope_iterator + : public _Rope_iterator_base<_CharT, _Alloc> + { + friend class rope<_CharT, _Alloc>; + protected: + typedef typename _Rope_iterator_base<_CharT, _Alloc>::_RopeRep _RopeRep; + rope<_CharT, _Alloc>* _M_root_rope; + + // root is treated as a cached version of this, and is used to + // detect changes to the underlying rope. + + // Root is included in the reference count. This is necessary + // so that we can detect changes reliably. Unfortunately, it + // requires careful bookkeeping for the nonGC case. + _Rope_iterator(rope<_CharT, _Alloc>* __r, size_t __pos) + : _Rope_iterator_base<_CharT, _Alloc>(__r->_M_tree_ptr, __pos), + _M_root_rope(__r) + { _RopeRep::_S_ref(this->_M_root); + if (!(__r -> empty())) + _S_setcache(*this); + } + + void _M_check(); + public: + typedef _Rope_char_ref_proxy<_CharT, _Alloc> reference; + typedef _Rope_char_ref_proxy<_CharT, _Alloc>* pointer; + + rope<_CharT, _Alloc>& + container() + { return *_M_root_rope; } + + _Rope_iterator() + { + this->_M_root = 0; // Needed for reference counting. + }; + + _Rope_iterator(const _Rope_iterator& __x) + : _Rope_iterator_base<_CharT, _Alloc>(__x) + { + _M_root_rope = __x._M_root_rope; + _RopeRep::_S_ref(this->_M_root); + } + + _Rope_iterator(rope<_CharT, _Alloc>& __r, size_t __pos); + + ~_Rope_iterator() + { _RopeRep::_S_unref(this->_M_root); } + + _Rope_iterator& + operator=(const _Rope_iterator& __x) + { + _RopeRep* __old = this->_M_root; + + _RopeRep::_S_ref(__x._M_root); + if (0 != __x._M_buf_ptr) + { + _M_root_rope = __x._M_root_rope; + *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x; + } + else + { + this->_M_current_pos = __x._M_current_pos; + this->_M_root = __x._M_root; + _M_root_rope = __x._M_root_rope; + this->_M_buf_ptr = 0; + } + _RopeRep::_S_unref(__old); + return(*this); + } + + reference + operator*() + { + _M_check(); + if (0 == this->_M_buf_ptr) + return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, + this->_M_current_pos); + else + return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, + this->_M_current_pos, + *this->_M_buf_ptr); + } + + // See above comment. + reference + operator*() const + { + return *const_cast<_Rope_iterator&>(*this); + } + + _Rope_iterator& + operator++() + { + this->_M_incr(1); + return *this; + } + + _Rope_iterator& + operator+=(ptrdiff_t __n) + { + if (__n >= 0) + this->_M_incr(__n); + else + this->_M_decr(-__n); + return *this; + } + + _Rope_iterator& + operator--() + { + this->_M_decr(1); + return *this; + } + + _Rope_iterator& + operator-=(ptrdiff_t __n) + { + if (__n >= 0) + this->_M_decr(__n); + else + this->_M_incr(-__n); + return *this; + } + + _Rope_iterator + operator++(int) + { + size_t __old_pos = this->_M_current_pos; + this->_M_incr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + + _Rope_iterator + operator--(int) + { + size_t __old_pos = this->_M_current_pos; + this->_M_decr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + + reference + operator[](ptrdiff_t __n) + { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, + this->_M_current_pos + + __n); } + + template<class _CharT2, class _Alloc2> + friend bool + operator==(const _Rope_iterator<_CharT2, _Alloc2>& __x, + const _Rope_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend bool + operator<(const _Rope_iterator<_CharT2, _Alloc2>& __x, + const _Rope_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend ptrdiff_t + operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x, + const _Rope_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2, _Alloc2> + operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); + + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2, _Alloc2> + operator+(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); + + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2, _Alloc2> + operator+(ptrdiff_t __n, const _Rope_iterator<_CharT2, _Alloc2>& __x); + }; + + + template <class _CharT, class _Alloc> + struct _Rope_base + : public _Alloc + { + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast<const _Alloc*>(this); } + + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + // The one in _Base may not be visible due to template rules. + + _Rope_base(_RopeRep* __t, const allocator_type&) + : _M_tree_ptr(__t) { } + + _Rope_base(const allocator_type&) { } + + // The only data member of a rope: + _RopeRep *_M_tree_ptr; + +#define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc::template rebind<_Tp>::other __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc().allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc().deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +#undef __ROPE_DEFINE_ALLOC + + protected: + _Rope_base& + operator=(const _Rope_base&); + + _Rope_base(const _Rope_base&); + }; + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template <class _CharT, class _Alloc> + class rope : public _Rope_base<_CharT, _Alloc> + { + public: + typedef _CharT value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _CharT const_reference; + typedef const _CharT* const_pointer; + typedef _Rope_iterator<_CharT, _Alloc> iterator; + typedef _Rope_const_iterator<_CharT, _Alloc> const_iterator; + typedef _Rope_char_ref_proxy<_CharT, _Alloc> reference; + typedef _Rope_char_ptr_proxy<_CharT, _Alloc> pointer; + + friend class _Rope_iterator<_CharT, _Alloc>; + friend class _Rope_const_iterator<_CharT, _Alloc>; + friend struct _Rope_RopeRep<_CharT, _Alloc>; + friend class _Rope_iterator_base<_CharT, _Alloc>; + friend class _Rope_char_ptr_proxy<_CharT, _Alloc>; + friend class _Rope_char_ref_proxy<_CharT, _Alloc>; + friend struct _Rope_RopeSubstring<_CharT, _Alloc>; + + protected: + typedef _Rope_base<_CharT, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + using _Base::_M_tree_ptr; + using _Base::get_allocator; + typedef __GC_CONST _CharT* _Cstrptr; + + static _CharT _S_empty_c_str[1]; + + static bool + _S_is0(_CharT __c) + { return __c == _S_eos((_CharT*)0); } + + enum { _S_copy_max = 23 }; + // For strings shorter than _S_copy_max, we copy to + // concatenate. + + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + typedef _Rope_RopeConcatenation<_CharT, _Alloc> _RopeConcatenation; + typedef _Rope_RopeLeaf<_CharT, _Alloc> _RopeLeaf; + typedef _Rope_RopeFunction<_CharT, _Alloc> _RopeFunction; + typedef _Rope_RopeSubstring<_CharT, _Alloc> _RopeSubstring; + + // Retrieve a character at the indicated position. + static _CharT _S_fetch(_RopeRep* __r, size_type __pos); + +#ifndef __GC + // Obtain a pointer to the character at the indicated position. + // The pointer can be used to change the character. + // If such a pointer cannot be produced, as is frequently the + // case, 0 is returned instead. + // (Returns nonzero only if all nodes in the path have a refcount + // of 1.) + static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos); +#endif + + static bool + _S_apply_to_pieces(// should be template parameter + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end); + // begin and end are assumed to be in range. + +#ifndef __GC + static void + _S_unref(_RopeRep* __t) + { _RopeRep::_S_unref(__t); } + + static void + _S_ref(_RopeRep* __t) + { _RopeRep::_S_ref(__t); } + +#else /* __GC */ + static void _S_unref(_RopeRep*) { } + static void _S_ref(_RopeRep*) { } +#endif + +#ifdef __GC + typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr; +#else + typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr; +#endif + + // _Result is counted in refcount. + static _RopeRep* _S_substring(_RopeRep* __base, + size_t __start, size_t __endp1); + + static _RopeRep* _S_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen); + // Concatenate rope and char ptr, copying __s. + // Should really take an arbitrary iterator. + // Result is counted in refcount. + static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, + size_t __slen) + // As above, but one reference to __r is about to be + // destroyed. Thus the pieces may be recycled if all + // relevant reference counts are 1. +#ifdef __GC + // We can't really do anything since refcounts are unavailable. + { return _S_concat_char_iter(__r, __iter, __slen); } +#else + ; +#endif + + static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right); + // General concatenation on _RopeRep. _Result + // has refcount of 1. Adjusts argument refcounts. + + public: + void + apply_to_pieces(size_t __begin, size_t __end, + _Rope_char_consumer<_CharT>& __c) const + { _S_apply_to_pieces(__c, this->_M_tree_ptr, __begin, __end); } + + protected: + + static size_t + _S_rounded_up_size(size_t __n) + { return _RopeLeaf::_S_rounded_up_size(__n); } + + static size_t + _S_allocated_capacity(size_t __n) + { + if (_S_is_basic_char_type((_CharT*)0)) + return _S_rounded_up_size(__n) - 1; + else + return _S_rounded_up_size(__n); + + } + + // Allocate and construct a RopeLeaf using the supplied allocator + // Takes ownership of s instead of copying. + static _RopeLeaf* + _S_new_RopeLeaf(__GC_CONST _CharT *__s, + size_t __size, allocator_type __a) + { + _RopeLeaf* __space = typename _Base::_LAlloc(__a).allocate(1); + return new(__space) _RopeLeaf(__s, __size, __a); + } + + static _RopeConcatenation* + _S_new_RopeConcatenation(_RopeRep* __left, _RopeRep* __right, + allocator_type __a) + { + _RopeConcatenation* __space = typename _Base::_CAlloc(__a).allocate(1); + return new(__space) _RopeConcatenation(__left, __right, __a); + } + + static _RopeFunction* + _S_new_RopeFunction(char_producer<_CharT>* __f, + size_t __size, bool __d, allocator_type __a) + { + _RopeFunction* __space = typename _Base::_FAlloc(__a).allocate(1); + return new(__space) _RopeFunction(__f, __size, __d, __a); + } + + static _RopeSubstring* + _S_new_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + { + _RopeSubstring* __space = typename _Base::_SAlloc(__a).allocate(1); + return new(__space) _RopeSubstring(__b, __s, __l, __a); + } + + static _RopeLeaf* + _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, + size_t __size, allocator_type __a) +#define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a) + { + if (0 == __size) + return 0; + _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); + + __uninitialized_copy_n_a(__s, __size, __buf, __a); + _S_cond_store_eos(__buf[__size]); + try + { return _S_new_RopeLeaf(__buf, __size, __a); } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__buf, __size, __a); + __throw_exception_again; + } + } + + // Concatenation of nonempty strings. + // Always builds a concatenation node. + // Rebalances if the result is too deep. + // Result has refcount 1. + // Does not increment left and right ref counts even though + // they are referenced. + static _RopeRep* + _S_tree_concat(_RopeRep* __left, _RopeRep* __right); + + // Concatenation helper functions + static _RopeLeaf* + _S_leaf_concat_char_iter(_RopeLeaf* __r, + const _CharT* __iter, size_t __slen); + // Concatenate by copying leaf. + // should take an arbitrary iterator + // result has refcount 1. +#ifndef __GC + static _RopeLeaf* + _S_destr_leaf_concat_char_iter(_RopeLeaf* __r, + const _CharT* __iter, size_t __slen); + // A version that potentially clobbers __r if __r->_M_ref_count == 1. +#endif + + private: + + static size_t _S_char_ptr_len(const _CharT* __s); + // slightly generalized strlen + + rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) + : _Base(__t, __a) { } + + + // Copy __r to the _CharT buffer. + // Returns __buffer + __r->_M_size. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer); + + // Again, with explicit starting position and length. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer); + + static const unsigned long + _S_min_len[__detail::_S_max_rope_depth + 1]; + + static bool + _S_is_balanced(_RopeRep* __r) + { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } + + static bool + _S_is_almost_balanced(_RopeRep* __r) + { return (__r->_M_depth == 0 + || __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } + + static bool + _S_is_roughly_balanced(_RopeRep* __r) + { return (__r->_M_depth <= 1 + || __r->_M_size >= _S_min_len[__r->_M_depth - 2]); } + + // Assumes the result is not empty. + static _RopeRep* + _S_concat_and_set_balanced(_RopeRep* __left, _RopeRep* __right) + { + _RopeRep* __result = _S_concat(__left, __right); + if (_S_is_balanced(__result)) + __result->_M_is_balanced = true; + return __result; + } + + // The basic rebalancing operation. Logically copies the + // rope. The result has refcount of 1. The client will + // usually decrement the reference count of __r. + // The result is within height 2 of balanced by the above + // definition. + static _RopeRep* _S_balance(_RopeRep* __r); + + // Add all unbalanced subtrees to the forest of balanceed trees. + // Used only by balance. + static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest); + + // Add __r to forest, assuming __r is already balanced. + static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest); + + // Print to stdout, exposing structure + static void _S_dump(_RopeRep* __r, int __indent = 0); + + // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. + static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); + + public: + bool + empty() const + { return 0 == this->_M_tree_ptr; } + + // Comparison member function. This is public only for those + // clients that need a ternary comparison. Others + // should use the comparison operators below. + int + compare(const rope& __y) const + { return _S_compare(this->_M_tree_ptr, __y._M_tree_ptr); } + + rope(const _CharT* __s, const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), + __a), __a) + { } + + rope(const _CharT* __s, size_t __len, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a), __a) + { } + + // Should perhaps be templatized with respect to the iterator type + // and use Sequence_buffer. (It should perhaps use sequence_buffer + // even now.) + rope(const _CharT *__s, const _CharT *__e, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a), __a) + { } + + rope(const const_iterator& __s, const const_iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(const iterator& __s, const iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(_CharT __c, const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1)); + + get_allocator().construct(__buf, __c); + try + { this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__buf, 1, __a); + __throw_exception_again; + } + } + + rope(size_t __n, _CharT __c, + const allocator_type& __a = allocator_type()); + + rope(const allocator_type& __a = allocator_type()) + : _Base(0, __a) { } + + // Construct a rope from a function that can compute its members + rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + this->_M_tree_ptr = (0 == __len) ? + 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a); + } + + rope(const rope& __x, const allocator_type& __a = allocator_type()) + : _Base(__x._M_tree_ptr, __a) + { _S_ref(this->_M_tree_ptr); } + + ~rope() throw() + { _S_unref(this->_M_tree_ptr); } + + rope& + operator=(const rope& __x) + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = __x._M_tree_ptr; + _S_ref(this->_M_tree_ptr); + _S_unref(__old); + return *this; + } + + void + clear() + { + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = 0; + } + + void + push_back(_CharT __x) + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr + = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1); + _S_unref(__old); + } + + void + pop_back() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = _S_substring(this->_M_tree_ptr, + 0, this->_M_tree_ptr->_M_size - 1); + _S_unref(__old); + } + + _CharT + back() const + { return _S_fetch(this->_M_tree_ptr, this->_M_tree_ptr->_M_size - 1); } + + void + push_front(_CharT __x) + { + _RopeRep* __old = this->_M_tree_ptr; + _RopeRep* __left = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, this->get_allocator()); + try + { + this->_M_tree_ptr = _S_concat(__left, this->_M_tree_ptr); + _S_unref(__old); + _S_unref(__left); + } + catch(...) + { + _S_unref(__left); + __throw_exception_again; + } + } + + void + pop_front() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr + = _S_substring(this->_M_tree_ptr, 1, this->_M_tree_ptr->_M_size); + _S_unref(__old); + } + + _CharT + front() const + { return _S_fetch(this->_M_tree_ptr, 0); } + + void + balance() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = _S_balance(this->_M_tree_ptr); + _S_unref(__old); + } + + void + copy(_CharT* __buffer) const + { + _Destroy(__buffer, __buffer + size(), get_allocator()); + _S_flatten(this->_M_tree_ptr, __buffer); + } + + // This is the copy function from the standard, but + // with the arguments reordered to make it consistent with the + // rest of the interface. + // Note that this guaranteed not to compile if the draft standard + // order is assumed. + size_type + copy(size_type __pos, size_type __n, _CharT* __buffer) const + { + size_t __size = size(); + size_t __len = (__pos + __n > __size? __size - __pos : __n); + + _Destroy(__buffer, __buffer + __len, get_allocator()); + _S_flatten(this->_M_tree_ptr, __pos, __len, __buffer); + return __len; + } + + // Print to stdout, exposing structure. May be useful for + // performance debugging. + void + dump() + { _S_dump(this->_M_tree_ptr); } + + // Convert to 0 terminated string in new allocated memory. + // Embedded 0s in the input do not terminate the copy. + const _CharT* c_str() const; + + // As above, but lso use the flattened representation as the + // the new rope representation. + const _CharT* replace_with_c_str(); + + // Reclaim memory for the c_str generated flattened string. + // Intentionally undocumented, since it's hard to say when this + // is safe for multiple threads. + void + delete_c_str () + { + if (0 == this->_M_tree_ptr) + return; + if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag && + ((_RopeLeaf*)this->_M_tree_ptr)->_M_data == + this->_M_tree_ptr->_M_c_string) + { + // Representation shared + return; + } +#ifndef __GC + this->_M_tree_ptr->_M_free_c_string(); +#endif + this->_M_tree_ptr->_M_c_string = 0; + } + + _CharT + operator[] (size_type __pos) const + { return _S_fetch(this->_M_tree_ptr, __pos); } + + _CharT + at(size_type __pos) const + { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + const_iterator + begin() const + { return(const_iterator(this->_M_tree_ptr, 0)); } + + // An easy way to get a const iterator from a non-const container. + const_iterator + const_begin() const + { return(const_iterator(this->_M_tree_ptr, 0)); } + + const_iterator + end() const + { return(const_iterator(this->_M_tree_ptr, size())); } + + const_iterator + const_end() const + { return(const_iterator(this->_M_tree_ptr, size())); } + + size_type + size() const + { return(0 == this->_M_tree_ptr? 0 : this->_M_tree_ptr->_M_size); } + + size_type + length() const + { return size(); } + + size_type + max_size() const + { + return _S_min_len[int(__detail::_S_max_rope_depth) - 1] - 1; + // Guarantees that the result can be sufficirntly + // balanced. Longer ropes will probably still work, + // but it's harder to make guarantees. + } + + typedef reverse_iterator<const_iterator> const_reverse_iterator; + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + const_reverse_iterator + const_rbegin() const + { return const_reverse_iterator(end()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + const_reverse_iterator + const_rend() const + { return const_reverse_iterator(begin()); } + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2, _Alloc2> + operator+(const rope<_CharT2, _Alloc2>& __left, + const rope<_CharT2, _Alloc2>& __right); + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2, _Alloc2> + operator+(const rope<_CharT2, _Alloc2>& __left, const _CharT2* __right); + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2, _Alloc2> + operator+(const rope<_CharT2, _Alloc2>& __left, _CharT2 __right); + + // The symmetric cases are intentionally omitted, since they're + // presumed to be less common, and we don't handle them as well. + + // The following should really be templatized. The first + // argument should be an input iterator or forward iterator with + // value_type _CharT. + rope& + append(const _CharT* __iter, size_t __n) + { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& + append(const _CharT* __c_string) + { + size_t __len = _S_char_ptr_len(__c_string); + append(__c_string, __len); + return(*this); + } + + rope& + append(const _CharT* __s, const _CharT* __e) + { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& + append(const_iterator __s, const_iterator __e) + { + _Self_destruct_ptr __appendee(_S_substring(__s._M_root, + __s._M_current_pos, + __e._M_current_pos)); + _RopeRep* __result = _S_concat(this->_M_tree_ptr, + (_RopeRep*)__appendee); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& + append(_CharT __c) + { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& + append() + { return append(_CharT()); } // XXX why? + + rope& + append(const rope& __y) + { + _RopeRep* __result = _S_concat(this->_M_tree_ptr, __y._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& + append(size_t __n, _CharT __c) + { + rope<_CharT,_Alloc> __last(__n, __c); + return append(__last); + } + + void + swap(rope& __b) + { + _RopeRep* __tmp = this->_M_tree_ptr; + this->_M_tree_ptr = __b._M_tree_ptr; + __b._M_tree_ptr = __tmp; + } + + protected: + // Result is included in refcount. + static _RopeRep* + replace(_RopeRep* __old, size_t __pos1, + size_t __pos2, _RopeRep* __r) + { + if (0 == __old) + { + _S_ref(__r); + return __r; + } + _Self_destruct_ptr __left(_S_substring(__old, 0, __pos1)); + _Self_destruct_ptr __right(_S_substring(__old, __pos2, __old->_M_size)); + _RopeRep* __result; + + if (0 == __r) + __result = _S_concat(__left, __right); + else + { + _Self_destruct_ptr __left_result(_S_concat(__left, __r)); + __result = _S_concat(__left_result, __right); + } + return __result; + } + + public: + void + insert(size_t __p, const rope& __r) + { + _RopeRep* __result = + replace(this->_M_tree_ptr, __p, __p, __r._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + void + insert(size_t __p, size_t __n, _CharT __c) + { + rope<_CharT,_Alloc> __r(__n,__c); + insert(__p, __r); + } + + void + insert(size_t __p, const _CharT* __i, size_t __n) + { + _Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p)); + _Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr, + __p, size())); + _Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n)); + // _S_ destr_concat_char_iter should be safe here. + // But as it stands it's probably not a win, since __left + // is likely to have additional references. + _RopeRep* __result = _S_concat(__left_result, __right); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + void + insert(size_t __p, const _CharT* __c_string) + { insert(__p, __c_string, _S_char_ptr_len(__c_string)); } + + void + insert(size_t __p, _CharT __c) + { insert(__p, &__c, 1); } + + void + insert(size_t __p) + { + _CharT __c = _CharT(); + insert(__p, &__c, 1); + } + + void + insert(size_t __p, const _CharT* __i, const _CharT* __j) + { + rope __r(__i, __j); + insert(__p, __r); + } + + void + insert(size_t __p, const const_iterator& __i, + const const_iterator& __j) + { + rope __r(__i, __j); + insert(__p, __r); + } + + void + insert(size_t __p, const iterator& __i, + const iterator& __j) + { + rope __r(__i, __j); + insert(__p, __r); + } + + // (position, length) versions of replace operations: + + void + replace(size_t __p, size_t __n, const rope& __r) + { + _RopeRep* __result = + replace(this->_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + void + replace(size_t __p, size_t __n, + const _CharT* __i, size_t __i_len) + { + rope __r(__i, __i_len); + replace(__p, __n, __r); + } + + void + replace(size_t __p, size_t __n, _CharT __c) + { + rope __r(__c); + replace(__p, __n, __r); + } + + void + replace(size_t __p, size_t __n, const _CharT* __c_string) + { + rope __r(__c_string); + replace(__p, __n, __r); + } + + void + replace(size_t __p, size_t __n, + const _CharT* __i, const _CharT* __j) + { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void + replace(size_t __p, size_t __n, + const const_iterator& __i, const const_iterator& __j) + { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void + replace(size_t __p, size_t __n, + const iterator& __i, const iterator& __j) + { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + // Single character variants: + void + replace(size_t __p, _CharT __c) + { + iterator __i(this, __p); + *__i = __c; + } + + void + replace(size_t __p, const rope& __r) + { replace(__p, 1, __r); } + + void + replace(size_t __p, const _CharT* __i, size_t __i_len) + { replace(__p, 1, __i, __i_len); } + + void + replace(size_t __p, const _CharT* __c_string) + { replace(__p, 1, __c_string); } + + void + replace(size_t __p, const _CharT* __i, const _CharT* __j) + { replace(__p, 1, __i, __j); } + + void + replace(size_t __p, const const_iterator& __i, + const const_iterator& __j) + { replace(__p, 1, __i, __j); } + + void + replace(size_t __p, const iterator& __i, + const iterator& __j) + { replace(__p, 1, __i, __j); } + + // Erase, (position, size) variant. + void + erase(size_t __p, size_t __n) + { + _RopeRep* __result = replace(this->_M_tree_ptr, __p, + __p + __n, 0); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + // Erase, single character + void + erase(size_t __p) + { erase(__p, __p + 1); } + + // Insert, iterator variants. + iterator + insert(const iterator& __p, const rope& __r) + { + insert(__p.index(), __r); + return __p; + } + + iterator + insert(const iterator& __p, size_t __n, _CharT __c) + { + insert(__p.index(), __n, __c); + return __p; + } + + iterator insert(const iterator& __p, _CharT __c) + { + insert(__p.index(), __c); + return __p; + } + + iterator + insert(const iterator& __p ) + { + insert(__p.index()); + return __p; + } + + iterator + insert(const iterator& __p, const _CharT* c_string) + { + insert(__p.index(), c_string); + return __p; + } + + iterator + insert(const iterator& __p, const _CharT* __i, size_t __n) + { + insert(__p.index(), __i, __n); + return __p; + } + + iterator + insert(const iterator& __p, const _CharT* __i, + const _CharT* __j) + { + insert(__p.index(), __i, __j); + return __p; + } + + iterator + insert(const iterator& __p, + const const_iterator& __i, const const_iterator& __j) + { + insert(__p.index(), __i, __j); + return __p; + } + + iterator + insert(const iterator& __p, + const iterator& __i, const iterator& __j) + { + insert(__p.index(), __i, __j); + return __p; + } + + // Replace, range variants. + void + replace(const iterator& __p, const iterator& __q, const rope& __r) + { replace(__p.index(), __q.index() - __p.index(), __r); } + + void + replace(const iterator& __p, const iterator& __q, _CharT __c) + { replace(__p.index(), __q.index() - __p.index(), __c); } + + void + replace(const iterator& __p, const iterator& __q, + const _CharT* __c_string) + { replace(__p.index(), __q.index() - __p.index(), __c_string); } + + void + replace(const iterator& __p, const iterator& __q, + const _CharT* __i, size_t __n) + { replace(__p.index(), __q.index() - __p.index(), __i, __n); } + + void + replace(const iterator& __p, const iterator& __q, + const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + + void + replace(const iterator& __p, const iterator& __q, + const const_iterator& __i, const const_iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + + void + replace(const iterator& __p, const iterator& __q, + const iterator& __i, const iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + + // Replace, iterator variants. + void + replace(const iterator& __p, const rope& __r) + { replace(__p.index(), __r); } + + void + replace(const iterator& __p, _CharT __c) + { replace(__p.index(), __c); } + + void + replace(const iterator& __p, const _CharT* __c_string) + { replace(__p.index(), __c_string); } + + void + replace(const iterator& __p, const _CharT* __i, size_t __n) + { replace(__p.index(), __i, __n); } + + void + replace(const iterator& __p, const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __i, __j); } + + void + replace(const iterator& __p, const_iterator __i, const_iterator __j) + { replace(__p.index(), __i, __j); } + + void + replace(const iterator& __p, iterator __i, iterator __j) + { replace(__p.index(), __i, __j); } + + // Iterator and range variants of erase + iterator + erase(const iterator& __p, const iterator& __q) + { + size_t __p_index = __p.index(); + erase(__p_index, __q.index() - __p_index); + return iterator(this, __p_index); + } + + iterator + erase(const iterator& __p) + { + size_t __p_index = __p.index(); + erase(__p_index, 1); + return iterator(this, __p_index); + } + + rope + substr(size_t __start, size_t __len = 1) const + { + return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, + __start, + __start + __len)); + } + + rope + substr(iterator __start, iterator __end) const + { + return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, + __start.index(), + __end.index())); + } + + rope + substr(iterator __start) const + { + size_t __pos = __start.index(); + return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, + __pos, __pos + 1)); + } + + rope + substr(const_iterator __start, const_iterator __end) const + { + // This might eventually take advantage of the cache in the + // iterator. + return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, + __start.index(), + __end.index())); + } + + rope<_CharT, _Alloc> + substr(const_iterator __start) + { + size_t __pos = __start.index(); + return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, + __pos, __pos + 1)); + } + + static const size_type npos; + + size_type find(_CharT __c, size_type __pos = 0) const; + + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + size_type __result_pos; + const_iterator __result = + std::search(const_begin() + __pos, const_end(), + __s, __s + _S_char_ptr_len(__s)); + __result_pos = __result.index(); +#ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) + __result_pos = npos; +#endif + return __result_pos; + } + + iterator + mutable_begin() + { return(iterator(this, 0)); } + + iterator + mutable_end() + { return(iterator(this, size())); } + + typedef reverse_iterator<iterator> reverse_iterator; + + reverse_iterator + mutable_rbegin() + { return reverse_iterator(mutable_end()); } + + reverse_iterator + mutable_rend() + { return reverse_iterator(mutable_begin()); } + + reference + mutable_reference_at(size_type __pos) + { return reference(this, __pos); } + +#ifdef __STD_STUFF + reference + operator[] (size_type __pos) + { return _char_ref_proxy(this, __pos); } + + reference + at(size_type __pos) + { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + void resize(size_type __n, _CharT __c) { } + void resize(size_type __n) { } + void reserve(size_type __res_arg = 0) { } + + size_type + capacity() const + { return max_size(); } + + // Stuff below this line is dangerous because it's error prone. + // I would really like to get rid of it. + // copy function with funny arg ordering. + size_type + copy(_CharT* __buffer, size_type __n, + size_type __pos = 0) const + { return copy(__pos, __n, __buffer); } + + iterator + end() + { return mutable_end(); } + + iterator + begin() + { return mutable_begin(); } + + reverse_iterator + rend() + { return mutable_rend(); } + + reverse_iterator + rbegin() + { return mutable_rbegin(); } + +#else + const_iterator + end() + { return const_end(); } + + const_iterator + begin() + { return const_begin(); } + + const_reverse_iterator + rend() + { return const_rend(); } + + const_reverse_iterator + rbegin() + { return const_rbegin(); } + +#endif + }; + + template <class _CharT, class _Alloc> + const typename rope<_CharT, _Alloc>::size_type + rope<_CharT, _Alloc>::npos = (size_type)(-1); + + template <class _CharT, class _Alloc> + inline bool operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return (__x._M_current_pos == __y._M_current_pos + && __x._M_root == __y._M_root); } + + template <class _CharT, class _Alloc> + inline bool operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return (__x._M_current_pos < __y._M_current_pos); } + + template <class _CharT, class _Alloc> + inline bool operator!=(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return !(__x == __y); } + + template <class _CharT, class _Alloc> + inline bool operator>(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return __y < __x; } + + template <class _CharT, class _Alloc> + inline bool + operator<=(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return !(__y < __x); } + + template <class _CharT, class _Alloc> + inline bool + operator>=(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return !(__x < __y); } + + template <class _CharT, class _Alloc> + inline ptrdiff_t + operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; } + + template <class _CharT, class _Alloc> + inline _Rope_const_iterator<_CharT, _Alloc> + operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) + { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, + __x._M_current_pos - __n); } + + template <class _CharT, class _Alloc> + inline _Rope_const_iterator<_CharT, _Alloc> + operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) + { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, + __x._M_current_pos + __n); } + + template <class _CharT, class _Alloc> + inline _Rope_const_iterator<_CharT, _Alloc> + operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT, _Alloc>& __x) + { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, + __x._M_current_pos + __n); } + + template <class _CharT, class _Alloc> + inline bool + operator==(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + {return (__x._M_current_pos == __y._M_current_pos + && __x._M_root_rope == __y._M_root_rope); } + + template <class _CharT, class _Alloc> + inline bool + operator<(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return (__x._M_current_pos < __y._M_current_pos); } + + template <class _CharT, class _Alloc> + inline bool + operator!=(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return !(__x == __y); } + + template <class _CharT, class _Alloc> + inline bool + operator>(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return __y < __x; } + + template <class _CharT, class _Alloc> + inline bool + operator<=(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return !(__y < __x); } + + template <class _CharT, class _Alloc> + inline bool + operator>=(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return !(__x < __y); } + + template <class _CharT, class _Alloc> + inline ptrdiff_t + operator-(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return ((ptrdiff_t)__x._M_current_pos + - (ptrdiff_t)__y._M_current_pos); } + + template <class _CharT, class _Alloc> + inline _Rope_iterator<_CharT, _Alloc> + operator-(const _Rope_iterator<_CharT, _Alloc>& __x, + ptrdiff_t __n) + { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, + __x._M_current_pos - __n); } + + template <class _CharT, class _Alloc> + inline _Rope_iterator<_CharT, _Alloc> + operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) + { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, + __x._M_current_pos + __n); } + + template <class _CharT, class _Alloc> + inline _Rope_iterator<_CharT, _Alloc> + operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x) + { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, + __x._M_current_pos + __n); } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right) + { + // Inlining this should make it possible to keep __left and + // __right in registers. + typedef rope<_CharT, _Alloc> rope_type; + return rope_type(rope_type::_S_concat(__left._M_tree_ptr, + __right._M_tree_ptr)); + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc>& + operator+=(rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right) + { + __left.append(__right); + return __left; + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, + const _CharT* __right) + { + typedef rope<_CharT, _Alloc> rope_type; + size_t __rlen = rope_type::_S_char_ptr_len(__right); + return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr, + __right, __rlen)); + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc>& + operator+=(rope<_CharT, _Alloc>& __left, + const _CharT* __right) + { + __left.append(__right); + return __left; + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, _CharT __right) + { + typedef rope<_CharT, _Alloc> rope_type; + return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr, + &__right, 1)); + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc>& + operator+=(rope<_CharT, _Alloc>& __left, _CharT __right) + { + __left.append(__right); + return __left; + } + + template <class _CharT, class _Alloc> + bool + operator<(const rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right) + { return __left.compare(__right) < 0; } + + template <class _CharT, class _Alloc> + bool + operator==(const rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right) + { return __left.compare(__right) == 0; } + + template <class _CharT, class _Alloc> + inline bool + operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y) + { return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); } + + template <class _CharT, class _Alloc> + inline bool + operator!=(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return !(__x == __y); } + + template <class _CharT, class _Alloc> + inline bool + operator>(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return __y < __x; } + + template <class _CharT, class _Alloc> + inline bool + operator<=(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return !(__y < __x); } + + template <class _CharT, class _Alloc> + inline bool + operator>=(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return !(__x < __y); } + + template <class _CharT, class _Alloc> + inline bool + operator!=(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y) + { return !(__x == __y); } + + template<class _CharT, class _Traits, class _Alloc> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r); + + typedef rope<char> crope; + typedef rope<wchar_t> wrope; + + inline crope::reference + __mutable_reference_at(crope& __c, size_t __i) + { return __c.mutable_reference_at(__i); } + + inline wrope::reference + __mutable_reference_at(wrope& __c, size_t __i) + { return __c.mutable_reference_at(__i); } + + template <class _CharT, class _Alloc> + inline void + swap(rope<_CharT, _Alloc>& __x, rope<_CharT, _Alloc>& __y) + { __x.swap(__y); } + + // Hash functions should probably be revisited later: + template<> + struct hash<crope> + { + size_t + operator()(const crope& __str) const + { + size_t __size = __str.size(); + if (0 == __size) + return 0; + return 13 * __str[0] + 5 * __str[__size - 1] + __size; + } + }; + + + template<> + struct hash<wrope> + { + size_t + operator()(const wrope& __str) const + { + size_t __size = __str.size(); + if (0 == __size) + return 0; + return 13 * __str[0] + 5 * __str[__size - 1] + __size; + } + }; + +_GLIBCXX_END_NAMESPACE + +# include <ext/ropeimpl.h> + +#endif diff --git a/libstdc++/include/ext/ropeimpl.h b/libstdc++/include/ext/ropeimpl.h new file mode 100644 index 0000000..bbe6b99 --- /dev/null +++ b/libstdc++/include/ext/ropeimpl.h @@ -0,0 +1,1702 @@ +// SGI's rope class implementation -*- C++ -*- + +// Copyright (C) 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. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ropeimpl.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#include <cstdio> +#include <ostream> +#include <bits/functexcept.h> + +#include <ext/algorithm> // For copy_n and lexicographical_compare_3way +#include <ext/memory> // For uninitialized_copy_n +#include <ext/numeric> // For power + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::printf; + using std::basic_ostream; + using std::__throw_length_error; + using std::_Destroy; + using std::uninitialized_fill_n; + + // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf + // if necessary. Assumes _M_path_end[leaf_index] and leaf_pos are correct. + // Results in a valid buf_ptr if the iterator can be legitimately + // dereferenced. + template <class _CharT, class _Alloc> + void + _Rope_iterator_base<_CharT, _Alloc>:: + _S_setbuf(_Rope_iterator_base<_CharT, _Alloc>& __x) + { + const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index]; + size_t __leaf_pos = __x._M_leaf_pos; + size_t __pos = __x._M_current_pos; + + switch(__leaf->_M_tag) + { + case __detail::_S_leaf: + __x._M_buf_start = ((_Rope_RopeLeaf<_CharT, _Alloc>*)__leaf)->_M_data; + __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos); + __x._M_buf_end = __x._M_buf_start + __leaf->_M_size; + break; + case __detail::_S_function: + case __detail::_S_substringfn: + { + size_t __len = _S_iterator_buf_len; + size_t __buf_start_pos = __leaf_pos; + size_t __leaf_end = __leaf_pos + __leaf->_M_size; + char_producer<_CharT>* __fn = ((_Rope_RopeFunction<_CharT, + _Alloc>*)__leaf)->_M_fn; + if (__buf_start_pos + __len <= __pos) + { + __buf_start_pos = __pos - __len / 4; + if (__buf_start_pos + __len > __leaf_end) + __buf_start_pos = __leaf_end - __len; + } + if (__buf_start_pos + __len > __leaf_end) + __len = __leaf_end - __buf_start_pos; + (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf); + __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos); + __x._M_buf_start = __x._M_tmp_buf; + __x._M_buf_end = __x._M_tmp_buf + __len; + } + break; + default: + break; + } + } + + // Set path and buffer inside a rope iterator. We assume that + // pos and root are already set. + template <class _CharT, class _Alloc> + void + _Rope_iterator_base<_CharT, _Alloc>:: + _S_setcache(_Rope_iterator_base<_CharT, _Alloc>& __x) + { + const _RopeRep* __path[int(__detail::_S_max_rope_depth) + 1]; + const _RopeRep* __curr_rope; + int __curr_depth = -1; /* index into path */ + size_t __curr_start_pos = 0; + size_t __pos = __x._M_current_pos; + unsigned char __dirns = 0; // Bit vector marking right turns in the path + + if (__pos >= __x._M_root->_M_size) + { + __x._M_buf_ptr = 0; + return; + } + __curr_rope = __x._M_root; + if (0 != __curr_rope->_M_c_string) + { + /* Treat the root as a leaf. */ + __x._M_buf_start = __curr_rope->_M_c_string; + __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size; + __x._M_buf_ptr = __curr_rope->_M_c_string + __pos; + __x._M_path_end[0] = __curr_rope; + __x._M_leaf_index = 0; + __x._M_leaf_pos = 0; + return; + } + for(;;) + { + ++__curr_depth; + __path[__curr_depth] = __curr_rope; + switch(__curr_rope->_M_tag) + { + case __detail::_S_leaf: + case __detail::_S_function: + case __detail::_S_substringfn: + __x._M_leaf_pos = __curr_start_pos; + goto done; + case __detail::_S_concat: + { + _Rope_RopeConcatenation<_CharT, _Alloc>* __c = + (_Rope_RopeConcatenation<_CharT, _Alloc>*)__curr_rope; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + __dirns <<= 1; + if (__pos >= __curr_start_pos + __left_len) + { + __dirns |= 1; + __curr_rope = __c->_M_right; + __curr_start_pos += __left_len; + } + else + __curr_rope = __left; + } + break; + } + } + done: + // Copy last section of path into _M_path_end. + { + int __i = -1; + int __j = __curr_depth + 1 - int(_S_path_cache_len); + + if (__j < 0) __j = 0; + while (__j <= __curr_depth) + __x._M_path_end[++__i] = __path[__j++]; + __x._M_leaf_index = __i; + } + __x._M_path_directions = __dirns; + _S_setbuf(__x); + } + + // Specialized version of the above. Assumes that + // the path cache is valid for the previous position. + template <class _CharT, class _Alloc> + void + _Rope_iterator_base<_CharT, _Alloc>:: + _S_setcache_for_incr(_Rope_iterator_base<_CharT, _Alloc>& __x) + { + int __current_index = __x._M_leaf_index; + const _RopeRep* __current_node = __x._M_path_end[__current_index]; + size_t __len = __current_node->_M_size; + size_t __node_start_pos = __x._M_leaf_pos; + unsigned char __dirns = __x._M_path_directions; + _Rope_RopeConcatenation<_CharT, _Alloc>* __c; + + if (__x._M_current_pos - __node_start_pos < __len) + { + /* More stuff in this leaf, we just didn't cache it. */ + _S_setbuf(__x); + return; + } + // node_start_pos is starting position of last_node. + while (--__current_index >= 0) + { + if (!(__dirns & 1) /* Path turned left */) + break; + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node; + // Otherwise we were in the right child. Thus we should pop + // the concatenation node. + __node_start_pos -= __c->_M_left->_M_size; + __dirns >>= 1; + } + if (__current_index < 0) + { + // We underflowed the cache. Punt. + _S_setcache(__x); + return; + } + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node; + // current_node is a concatenation node. We are positioned on the first + // character in its right child. + // node_start_pos is starting position of current_node. + __node_start_pos += __c->_M_left->_M_size; + __current_node = __c->_M_right; + __x._M_path_end[++__current_index] = __current_node; + __dirns |= 1; + while (__detail::_S_concat == __current_node->_M_tag) + { + ++__current_index; + if (int(_S_path_cache_len) == __current_index) + { + int __i; + for (__i = 0; __i < int(_S_path_cache_len) - 1; __i++) + __x._M_path_end[__i] = __x._M_path_end[__i+1]; + --__current_index; + } + __current_node = + ((_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node)->_M_left; + __x._M_path_end[__current_index] = __current_node; + __dirns <<= 1; + // node_start_pos is unchanged. + } + __x._M_leaf_index = __current_index; + __x._M_leaf_pos = __node_start_pos; + __x._M_path_directions = __dirns; + _S_setbuf(__x); + } + + template <class _CharT, class _Alloc> + void + _Rope_iterator_base<_CharT, _Alloc>:: + _M_incr(size_t __n) + { + _M_current_pos += __n; + if (0 != _M_buf_ptr) + { + size_t __chars_left = _M_buf_end - _M_buf_ptr; + if (__chars_left > __n) + _M_buf_ptr += __n; + else if (__chars_left == __n) + { + _M_buf_ptr += __n; + _S_setcache_for_incr(*this); + } + else + _M_buf_ptr = 0; + } + } + + template <class _CharT, class _Alloc> + void + _Rope_iterator_base<_CharT, _Alloc>:: + _M_decr(size_t __n) + { + if (0 != _M_buf_ptr) + { + size_t __chars_left = _M_buf_ptr - _M_buf_start; + if (__chars_left >= __n) + _M_buf_ptr -= __n; + else + _M_buf_ptr = 0; + } + _M_current_pos -= __n; + } + + template <class _CharT, class _Alloc> + void + _Rope_iterator<_CharT, _Alloc>:: + _M_check() + { + if (_M_root_rope->_M_tree_ptr != this->_M_root) + { + // _Rope was modified. Get things fixed up. + _RopeRep::_S_unref(this->_M_root); + this->_M_root = _M_root_rope->_M_tree_ptr; + _RopeRep::_S_ref(this->_M_root); + this->_M_buf_ptr = 0; + } + } + + template <class _CharT, class _Alloc> + inline + _Rope_const_iterator<_CharT, _Alloc>:: + _Rope_const_iterator(const _Rope_iterator<_CharT, _Alloc>& __x) + : _Rope_iterator_base<_CharT, _Alloc>(__x) + { } + + template <class _CharT, class _Alloc> + inline + _Rope_iterator<_CharT, _Alloc>:: + _Rope_iterator(rope<_CharT, _Alloc>& __r, size_t __pos) + : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos), + _M_root_rope(&__r) + { _RopeRep::_S_ref(this->_M_root); } + + template <class _CharT, class _Alloc> + inline size_t + rope<_CharT, _Alloc>:: + _S_char_ptr_len(const _CharT* __s) + { + const _CharT* __p = __s; + + while (!_S_is0(*__p)) + ++__p; + return (__p - __s); + } + + +#ifndef __GC + + template <class _CharT, class _Alloc> + inline void + _Rope_RopeRep<_CharT, _Alloc>:: + _M_free_c_string() + { + _CharT* __cstr = _M_c_string; + if (0 != __cstr) + { + size_t __size = this->_M_size + 1; + _Destroy(__cstr, __cstr + __size, get_allocator()); + this->_Data_deallocate(__cstr, __size); + } + } + + template <class _CharT, class _Alloc> + inline void + _Rope_RopeRep<_CharT, _Alloc>:: + _S_free_string(_CharT* __s, size_t __n, allocator_type __a) + { + if (!_S_is_basic_char_type((_CharT*)0)) + _Destroy(__s, __s + __n, __a); + + // This has to be a static member, so this gets a bit messy + __a.deallocate(__s, + _Rope_RopeLeaf<_CharT, _Alloc>::_S_rounded_up_size(__n)); + } + + // There are several reasons for not doing this with virtual destructors + // and a class specific delete operator: + // - A class specific delete operator can't easily get access to + // allocator instances if we need them. + // - Any virtual function would need a 4 or byte vtable pointer; + // this only requires a one byte tag per object. + template <class _CharT, class _Alloc> + void + _Rope_RopeRep<_CharT, _Alloc>:: + _M_free_tree() + { + switch(_M_tag) + { + case __detail::_S_leaf: + { + _Rope_RopeLeaf<_CharT, _Alloc>* __l + = (_Rope_RopeLeaf<_CharT, _Alloc>*)this; + __l->_Rope_RopeLeaf<_CharT, _Alloc>::~_Rope_RopeLeaf(); + _L_deallocate(__l, 1); + break; + } + case __detail::_S_concat: + { + _Rope_RopeConcatenation<_CharT,_Alloc>* __c + = (_Rope_RopeConcatenation<_CharT, _Alloc>*)this; + __c->_Rope_RopeConcatenation<_CharT, _Alloc>:: + ~_Rope_RopeConcatenation(); + _C_deallocate(__c, 1); + break; + } + case __detail::_S_function: + { + _Rope_RopeFunction<_CharT, _Alloc>* __f + = (_Rope_RopeFunction<_CharT, _Alloc>*)this; + __f->_Rope_RopeFunction<_CharT, _Alloc>::~_Rope_RopeFunction(); + _F_deallocate(__f, 1); + break; + } + case __detail::_S_substringfn: + { + _Rope_RopeSubstring<_CharT, _Alloc>* __ss = + (_Rope_RopeSubstring<_CharT, _Alloc>*)this; + __ss->_Rope_RopeSubstring<_CharT, _Alloc>:: + ~_Rope_RopeSubstring(); + _S_deallocate(__ss, 1); + break; + } + } + } +#else + + template <class _CharT, class _Alloc> + inline void + _Rope_RopeRep<_CharT, _Alloc>:: + _S_free_string(const _CharT*, size_t, allocator_type) + { } + +#endif + + // Concatenate a C string onto a leaf rope by copying the rope data. + // Used for short ropes. + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeLeaf* + rope<_CharT, _Alloc>:: + _S_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, size_t __len) + { + size_t __old_len = __r->_M_size; + _CharT* __new_data = (_CharT*) + _Data_allocate(_S_rounded_up_size(__old_len + __len)); + _RopeLeaf* __result; + + uninitialized_copy_n(__r->_M_data, __old_len, __new_data); + uninitialized_copy_n(__iter, __len, __new_data + __old_len); + _S_cond_store_eos(__new_data[__old_len + __len]); + try + { + __result = _S_new_RopeLeaf(__new_data, __old_len + __len, + __r->get_allocator()); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, + __r->get_allocator()); + __throw_exception_again; + } + return __result; + } + +#ifndef __GC + // As above, but it's OK to clobber original if refcount is 1 + template <class _CharT, class _Alloc> + typename rope<_CharT,_Alloc>::_RopeLeaf* + rope<_CharT, _Alloc>:: + _S_destr_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, + size_t __len) + { + if (__r->_M_ref_count > 1) + return _S_leaf_concat_char_iter(__r, __iter, __len); + size_t __old_len = __r->_M_size; + if (_S_allocated_capacity(__old_len) >= __old_len + __len) + { + // The space has been partially initialized for the standard + // character types. But that doesn't matter for those types. + uninitialized_copy_n(__iter, __len, __r->_M_data + __old_len); + if (_S_is_basic_char_type((_CharT*)0)) + _S_cond_store_eos(__r->_M_data[__old_len + __len]); + else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) + { + __r->_M_free_c_string(); + __r->_M_c_string = 0; + } + __r->_M_size = __old_len + __len; + __r->_M_ref_count = 2; + return __r; + } + else + { + _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); + return __result; + } + } +#endif + + // Assumes left and right are not 0. + // Does not increment (nor decrement on exception) child reference counts. + // Result has ref count 1. + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeRep* + rope<_CharT, _Alloc>:: + _S_tree_concat(_RopeRep* __left, _RopeRep* __right) + { + _RopeConcatenation* __result = _S_new_RopeConcatenation(__left, __right, + __left-> + get_allocator()); + size_t __depth = __result->_M_depth; + + if (__depth > 20 + && (__result->_M_size < 1000 + || __depth > size_t(__detail::_S_max_rope_depth))) + { + _RopeRep* __balanced; + + try + { + __balanced = _S_balance(__result); + __result->_M_unref_nonnil(); + } + catch(...) + { + _C_deallocate(__result,1); + __throw_exception_again; + } + // In case of exception, we need to deallocate + // otherwise dangling result node. But caller + // still owns its children. Thus unref is + // inappropriate. + return __balanced; + } + else + return __result; + } + + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeRep* + rope<_CharT, _Alloc>:: + _S_concat_char_iter(_RopeRep* __r, const _CharT*__s, size_t __slen) + { + _RopeRep* __result; + if (0 == __slen) + { + _S_ref(__r); + return __r; + } + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + if (__r->_M_tag == __detail::_S_leaf + && __r->_M_size + __slen <= size_t(_S_copy_max)) + { + __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); + return __result; + } + if (__detail::_S_concat == __r->_M_tag + && __detail::_S_leaf == ((_RopeConcatenation*) __r)->_M_right->_M_tag) + { + _RopeLeaf* __right = + (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); + if (__right->_M_size + __slen <= size_t(_S_copy_max)) + { + _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; + _RopeRep* __nright = + _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); + __left->_M_ref_nonnil(); + try + { __result = _S_tree_concat(__left, __nright); } + catch(...) + { + _S_unref(__left); + _S_unref(__nright); + __throw_exception_again; + } + return __result; + } + } + _RopeRep* __nright = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + try + { + __r->_M_ref_nonnil(); + __result = _S_tree_concat(__r, __nright); + } + catch(...) + { + _S_unref(__r); + _S_unref(__nright); + __throw_exception_again; + } + return __result; + } + +#ifndef __GC + template <class _CharT, class _Alloc> + typename rope<_CharT,_Alloc>::_RopeRep* + rope<_CharT,_Alloc>:: + _S_destr_concat_char_iter(_RopeRep* __r, const _CharT* __s, size_t __slen) + { + _RopeRep* __result; + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + size_t __count = __r->_M_ref_count; + size_t __orig_size = __r->_M_size; + if (__count > 1) + return _S_concat_char_iter(__r, __s, __slen); + if (0 == __slen) + { + __r->_M_ref_count = 2; // One more than before + return __r; + } + if (__orig_size + __slen <= size_t(_S_copy_max) + && __detail::_S_leaf == __r->_M_tag) + { + __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, + __slen); + return __result; + } + if (__detail::_S_concat == __r->_M_tag) + { + _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*) + __r)->_M_right); + if (__detail::_S_leaf == __right->_M_tag + && __right->_M_size + __slen <= size_t(_S_copy_max)) + { + _RopeRep* __new_right = + _S_destr_leaf_concat_char_iter(__right, __s, __slen); + if (__right == __new_right) + __new_right->_M_ref_count = 1; + else + __right->_M_unref_nonnil(); + __r->_M_ref_count = 2; // One more than before. + ((_RopeConcatenation*)__r)->_M_right = __new_right; + __r->_M_size = __orig_size + __slen; + if (0 != __r->_M_c_string) + { + __r->_M_free_c_string(); + __r->_M_c_string = 0; + } + return __r; + } + } + _RopeRep* __right = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + __r->_M_ref_nonnil(); + try + { __result = _S_tree_concat(__r, __right); } + catch(...) + { + _S_unref(__r); + _S_unref(__right); + __throw_exception_again; + } + return __result; + } +#endif /* !__GC */ + + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeRep* + rope<_CharT, _Alloc>:: + _S_concat(_RopeRep* __left, _RopeRep* __right) + { + if (0 == __left) + { + _S_ref(__right); + return __right; + } + if (0 == __right) + { + __left->_M_ref_nonnil(); + return __left; + } + if (__detail::_S_leaf == __right->_M_tag) + { + if (__detail::_S_leaf == __left->_M_tag) + { + if (__right->_M_size + __left->_M_size <= size_t(_S_copy_max)) + return _S_leaf_concat_char_iter((_RopeLeaf*)__left, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + } + else if (__detail::_S_concat == __left->_M_tag + && __detail::_S_leaf == ((_RopeConcatenation*) + __left)->_M_right->_M_tag) + { + _RopeLeaf* __leftright = + (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); + if (__leftright->_M_size + + __right->_M_size <= size_t(_S_copy_max)) + { + _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left; + _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright, + ((_RopeLeaf*) + __right)-> + _M_data, + __right->_M_size); + __leftleft->_M_ref_nonnil(); + try + { return(_S_tree_concat(__leftleft, __rest)); } + catch(...) + { + _S_unref(__leftleft); + _S_unref(__rest); + __throw_exception_again; + } + } + } + } + __left->_M_ref_nonnil(); + __right->_M_ref_nonnil(); + try + { return(_S_tree_concat(__left, __right)); } + catch(...) + { + _S_unref(__left); + _S_unref(__right); + __throw_exception_again; + } + } + + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeRep* + rope<_CharT, _Alloc>:: + _S_substring(_RopeRep* __base, size_t __start, size_t __endp1) + { + if (0 == __base) + return 0; + size_t __len = __base->_M_size; + size_t __adj_endp1; + const size_t __lazy_threshold = 128; + + if (__endp1 >= __len) + { + if (0 == __start) + { + __base->_M_ref_nonnil(); + return __base; + } + else + __adj_endp1 = __len; + + } + else + __adj_endp1 = __endp1; + + switch(__base->_M_tag) + { + case __detail::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__base; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + size_t __left_len = __left->_M_size; + _RopeRep* __result; + + if (__adj_endp1 <= __left_len) + return _S_substring(__left, __start, __endp1); + else if (__start >= __left_len) + return _S_substring(__right, __start - __left_len, + __adj_endp1 - __left_len); + _Self_destruct_ptr __left_result(_S_substring(__left, + __start, + __left_len)); + _Self_destruct_ptr __right_result(_S_substring(__right, 0, + __endp1 + - __left_len)); + __result = _S_concat(__left_result, __right_result); + return __result; + } + case __detail::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__base; + _RopeLeaf* __result; + size_t __result_len; + if (__start >= __adj_endp1) + return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) + goto lazy; +#ifdef __GC + const _CharT* __section = __l->_M_data + __start; + __result = _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + __result->_M_c_string = 0; // Not eos terminated. +#else + // We should sometimes create substring node instead. + __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__l->_M_data + __start, + __result_len, + __base-> + get_allocator()); +#endif + return __result; + } + case __detail::_S_substringfn: + // Avoid introducing multiple layers of substring nodes. + { + _RopeSubstring* __old = (_RopeSubstring*)__base; + size_t __result_len; + if (__start >= __adj_endp1) + return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) + { + _RopeSubstring* __result = + _S_new_RopeSubstring(__old->_M_base, + __start + __old->_M_start, + __adj_endp1 - __start, + __base->get_allocator()); + return __result; + + } // *** else fall through: *** + } + case __detail::_S_function: + { + _RopeFunction* __f = (_RopeFunction*)__base; + _CharT* __section; + size_t __result_len; + if (__start >= __adj_endp1) + return 0; + __result_len = __adj_endp1 - __start; + + if (__result_len > __lazy_threshold) + goto lazy; + __section = (_CharT*) + _Data_allocate(_S_rounded_up_size(__result_len)); + try + { (*(__f->_M_fn))(__start, __result_len, __section); } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__section, __result_len, + __base->get_allocator()); + __throw_exception_again; + } + _S_cond_store_eos(__section[__result_len]); + return _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + } + } + lazy: + { + // Create substring node. + return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start, + __base->get_allocator()); + } + } + + template<class _CharT> + class _Rope_flatten_char_consumer + : public _Rope_char_consumer<_CharT> + { + private: + _CharT* _M_buf_ptr; + public: + + _Rope_flatten_char_consumer(_CharT* __buffer) + { _M_buf_ptr = __buffer; }; + + ~_Rope_flatten_char_consumer() {} + + bool + operator()(const _CharT* __leaf, size_t __n) + { + uninitialized_copy_n(__leaf, __n, _M_buf_ptr); + _M_buf_ptr += __n; + return true; + } + }; + + template<class _CharT> + class _Rope_find_char_char_consumer + : public _Rope_char_consumer<_CharT> + { + private: + _CharT _M_pattern; + public: + size_t _M_count; // Number of nonmatching characters + + _Rope_find_char_char_consumer(_CharT __p) + : _M_pattern(__p), _M_count(0) {} + + ~_Rope_find_char_char_consumer() {} + + bool + operator()(const _CharT* __leaf, size_t __n) + { + size_t __i; + for (__i = 0; __i < __n; __i++) + { + if (__leaf[__i] == _M_pattern) + { + _M_count += __i; + return false; + } + } + _M_count += __n; return true; + } + }; + + template<class _CharT, class _Traits> + // Here _CharT is both the stream and rope character type. + class _Rope_insert_char_consumer + : public _Rope_char_consumer<_CharT> + { + private: + typedef basic_ostream<_CharT,_Traits> _Insert_ostream; + _Insert_ostream& _M_o; + public: + _Rope_insert_char_consumer(_Insert_ostream& __writer) + : _M_o(__writer) {}; + ~_Rope_insert_char_consumer() { }; + // Caller is presumed to own the ostream + bool operator() (const _CharT* __leaf, size_t __n); + // Returns true to continue traversal. + }; + + template<class _CharT, class _Traits> + bool + _Rope_insert_char_consumer<_CharT, _Traits>:: + operator()(const _CharT* __leaf, size_t __n) + { + size_t __i; + // We assume that formatting is set up correctly for each element. + for (__i = 0; __i < __n; __i++) + _M_o.put(__leaf[__i]); + return true; + } + + template <class _CharT, class _Alloc> + bool + rope<_CharT, _Alloc>:: + _S_apply_to_pieces(_Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, size_t __begin, size_t __end) + { + if (0 == __r) + return true; + switch(__r->_M_tag) + { + case __detail::_S_concat: + { + _RopeConcatenation* __conc = (_RopeConcatenation*)__r; + _RopeRep* __left = __conc->_M_left; + size_t __left_len = __left->_M_size; + if (__begin < __left_len) + { + size_t __left_end = std::min(__left_len, __end); + if (!_S_apply_to_pieces(__c, __left, __begin, __left_end)) + return false; + } + if (__end > __left_len) + { + _RopeRep* __right = __conc->_M_right; + size_t __right_start = std::max(__left_len, __begin); + if (!_S_apply_to_pieces(__c, __right, + __right_start - __left_len, + __end - __left_len)) + return false; + } + } + return true; + case __detail::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __c(__l->_M_data + __begin, __end - __begin); + } + case __detail::_S_function: + case __detail::_S_substringfn: + { + _RopeFunction* __f = (_RopeFunction*)__r; + size_t __len = __end - __begin; + bool __result; + _CharT* __buffer = + (_CharT*)_Alloc().allocate(__len * sizeof(_CharT)); + try + { + (*(__f->_M_fn))(__begin, __len, __buffer); + __result = __c(__buffer, __len); + _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); + } + catch(...) + { + _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); + __throw_exception_again; + } + return __result; + } + default: + return false; + } + } + + template<class _CharT, class _Traits> + inline void + _Rope_fill(basic_ostream<_CharT, _Traits>& __o, size_t __n) + { + char __f = __o.fill(); + size_t __i; + + for (__i = 0; __i < __n; __i++) + __o.put(__f); + } + + + template <class _CharT> + inline bool + _Rope_is_simple(_CharT*) + { return false; } + + inline bool + _Rope_is_simple(char*) + { return true; } + + inline bool + _Rope_is_simple(wchar_t*) + { return true; } + + template<class _CharT, class _Traits, class _Alloc> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r) + { + size_t __w = __o.width(); + bool __left = bool(__o.flags() & std::ios::left); + size_t __pad_len; + size_t __rope_len = __r.size(); + _Rope_insert_char_consumer<_CharT, _Traits> __c(__o); + bool __is_simple = _Rope_is_simple((_CharT*)0); + + if (__rope_len < __w) + __pad_len = __w - __rope_len; + else + __pad_len = 0; + + if (!__is_simple) + __o.width(__w / __rope_len); + try + { + if (__is_simple && !__left && __pad_len > 0) + _Rope_fill(__o, __pad_len); + __r.apply_to_pieces(0, __r.size(), __c); + if (__is_simple && __left && __pad_len > 0) + _Rope_fill(__o, __pad_len); + if (!__is_simple) + __o.width(__w); + } + catch(...) + { + if (!__is_simple) + __o.width(__w); + __throw_exception_again; + } + return __o; + } + + template <class _CharT, class _Alloc> + _CharT* + rope<_CharT, _Alloc>:: + _S_flatten(_RopeRep* __r, size_t __start, size_t __len, + _CharT* __buffer) + { + _Rope_flatten_char_consumer<_CharT> __c(__buffer); + _S_apply_to_pieces(__c, __r, __start, __start + __len); + return(__buffer + __len); + } + + template <class _CharT, class _Alloc> + size_t + rope<_CharT, _Alloc>:: + find(_CharT __pattern, size_t __start) const + { + _Rope_find_char_char_consumer<_CharT> __c(__pattern); + _S_apply_to_pieces(__c, this->_M_tree_ptr, __start, size()); + size_type __result_pos = __start + __c._M_count; +#ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) + __result_pos = npos; +#endif + return __result_pos; + } + + template <class _CharT, class _Alloc> + _CharT* + rope<_CharT, _Alloc>:: + _S_flatten(_RopeRep* __r, _CharT* __buffer) + { + if (0 == __r) + return __buffer; + switch(__r->_M_tag) + { + case __detail::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + _CharT* __rest = _S_flatten(__left, __buffer); + return _S_flatten(__right, __rest); + } + case __detail::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return copy_n(__l->_M_data, __l->_M_size, __buffer).second; + } + case __detail::_S_function: + case __detail::_S_substringfn: + // We don't yet do anything with substring nodes. + // This needs to be fixed before ropefiles will work well. + { + _RopeFunction* __f = (_RopeFunction*)__r; + (*(__f->_M_fn))(0, __f->_M_size, __buffer); + return __buffer + __f->_M_size; + } + default: + return 0; + } + } + + // This needs work for _CharT != char + template <class _CharT, class _Alloc> + void + rope<_CharT, _Alloc>:: + _S_dump(_RopeRep* __r, int __indent) + { + for (int __i = 0; __i < __indent; __i++) + putchar(' '); + if (0 == __r) + { + printf("NULL\n"); + return; + } + if (_S_concat == __r->_M_tag) + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + +#ifdef __GC + printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n", + __r, __r->_M_depth, __r->_M_size, + __r->_M_is_balanced? "" : "not"); +#else + printf("Concatenation %p (rc = %ld, depth = %d, " + "len = %ld, %s balanced)\n", + __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size, + __r->_M_is_balanced? "" : "not"); +#endif + _S_dump(__left, __indent + 2); + _S_dump(__right, __indent + 2); + return; + } + else + { + char* __kind; + + switch (__r->_M_tag) + { + case __detail::_S_leaf: + __kind = "Leaf"; + break; + case __detail::_S_function: + __kind = "Function"; + break; + case __detail::_S_substringfn: + __kind = "Function representing substring"; + break; + default: + __kind = "(corrupted kind field!)"; + } +#ifdef __GC + printf("%s %p (depth = %d, len = %ld) ", + __kind, __r, __r->_M_depth, __r->_M_size); +#else + printf("%s %p (rc = %ld, depth = %d, len = %ld) ", + __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size); +#endif + if (_S_is_one_byte_char_type((_CharT*)0)) + { + const int __max_len = 40; + _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len)); + _CharT __buffer[__max_len + 1]; + bool __too_big = __r->_M_size > __prefix->_M_size; + + _S_flatten(__prefix, __buffer); + __buffer[__prefix->_M_size] = _S_eos((_CharT*)0); + printf("%s%s\n", (char*)__buffer, + __too_big? "...\n" : "\n"); + } + else + printf("\n"); + } + } + + template <class _CharT, class _Alloc> + const unsigned long + rope<_CharT, _Alloc>:: + _S_min_len[int(__detail::_S_max_rope_depth) + 1] = { + /* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21, + /* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377, + /* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181, + /* 18 */6765, /* 19 */10946, /* 20 */17711, /* 21 */28657, /* 22 */46368, + /* 23 */75025, /* 24 */121393, /* 25 */196418, /* 26 */317811, + /* 27 */514229, /* 28 */832040, /* 29 */1346269, /* 30 */2178309, + /* 31 */3524578, /* 32 */5702887, /* 33 */9227465, /* 34 */14930352, + /* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155, + /* 39 */165580141, /* 40 */267914296, /* 41 */433494437, + /* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903, + /* 45 */2971215073u }; + // These are Fibonacci numbers < 2**32. + + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeRep* + rope<_CharT, _Alloc>:: + _S_balance(_RopeRep* __r) + { + _RopeRep* __forest[int(__detail::_S_max_rope_depth) + 1]; + _RopeRep* __result = 0; + int __i; + // Invariant: + // The concatenation of forest in descending order is equal to __r. + // __forest[__i]._M_size >= _S_min_len[__i] + // __forest[__i]._M_depth = __i + // References from forest are included in refcount. + + for (__i = 0; __i <= int(__detail::_S_max_rope_depth); ++__i) + __forest[__i] = 0; + try + { + _S_add_to_forest(__r, __forest); + for (__i = 0; __i <= int(__detail::_S_max_rope_depth); ++__i) + if (0 != __forest[__i]) + { +#ifndef __GC + _Self_destruct_ptr __old(__result); +#endif + __result = _S_concat(__forest[__i], __result); + __forest[__i]->_M_unref_nonnil(); +#if !defined(__GC) && defined(__EXCEPTIONS) + __forest[__i] = 0; +#endif + } + } + catch(...) + { + for(__i = 0; __i <= int(__detail::_S_max_rope_depth); __i++) + _S_unref(__forest[__i]); + __throw_exception_again; + } + + if (__result->_M_depth > int(__detail::_S_max_rope_depth)) + __throw_length_error(__N("rope::_S_balance")); + return(__result); + } + + template <class _CharT, class _Alloc> + void + rope<_CharT, _Alloc>:: + _S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) + { + if (__r->_M_is_balanced) + { + _S_add_leaf_to_forest(__r, __forest); + return; + } + + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + + _S_add_to_forest(__c->_M_left, __forest); + _S_add_to_forest(__c->_M_right, __forest); + } + } + + + template <class _CharT, class _Alloc> + void + rope<_CharT, _Alloc>:: + _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) + { + _RopeRep* __insertee; // included in refcount + _RopeRep* __too_tiny = 0; // included in refcount + int __i; // forest[0..__i-1] is empty + size_t __s = __r->_M_size; + + for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) + { + if (0 != __forest[__i]) + { +#ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +#endif + __too_tiny = _S_concat_and_set_balanced(__forest[__i], + __too_tiny); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + } + } + { +#ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +#endif + __insertee = _S_concat_and_set_balanced(__too_tiny, __r); + } + // Too_tiny dead, and no longer included in refcount. + // Insertee is live and included. + for (;; ++__i) + { + if (0 != __forest[__i]) + { +#ifndef __GC + _Self_destruct_ptr __old(__insertee); +#endif + __insertee = _S_concat_and_set_balanced(__forest[__i], + __insertee); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + } + if (__i == int(__detail::_S_max_rope_depth) + || __insertee->_M_size < _S_min_len[__i+1]) + { + __forest[__i] = __insertee; + // refcount is OK since __insertee is now dead. + return; + } + } + } + + template <class _CharT, class _Alloc> + _CharT + rope<_CharT, _Alloc>:: + _S_fetch(_RopeRep* __r, size_type __i) + { + __GC_CONST _CharT* __cstr = __r->_M_c_string; + + if (0 != __cstr) + return __cstr[__i]; + for(;;) + { + switch(__r->_M_tag) + { + case __detail::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__i >= __left_len) + { + __i -= __left_len; + __r = __c->_M_right; + } + else + __r = __left; + } + break; + case __detail::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __l->_M_data[__i]; + } + case __detail::_S_function: + case __detail::_S_substringfn: + { + _RopeFunction* __f = (_RopeFunction*)__r; + _CharT __result; + + (*(__f->_M_fn))(__i, 1, &__result); + return __result; + } + } + } + } + +#ifndef __GC + // Return a uniquely referenced character slot for the given + // position, or 0 if that's not possible. + template <class _CharT, class _Alloc> + _CharT* + rope<_CharT, _Alloc>:: + _S_fetch_ptr(_RopeRep* __r, size_type __i) + { + _RopeRep* __clrstack[__detail::_S_max_rope_depth]; + size_t __csptr = 0; + + for(;;) + { + if (__r->_M_ref_count > 1) + return 0; + switch(__r->_M_tag) + { + case __detail::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__c->_M_c_string != 0) + __clrstack[__csptr++] = __c; + if (__i >= __left_len) + { + __i -= __left_len; + __r = __c->_M_right; + } + else + __r = __left; + } + break; + case __detail::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0) + __clrstack[__csptr++] = __l; + while (__csptr > 0) + { + -- __csptr; + _RopeRep* __d = __clrstack[__csptr]; + __d->_M_free_c_string(); + __d->_M_c_string = 0; + } + return __l->_M_data + __i; + } + case __detail::_S_function: + case __detail::_S_substringfn: + return 0; + } + } + } +#endif /* __GC */ + + // The following could be implemented trivially using + // lexicographical_compare_3way. + // We do a little more work to avoid dealing with rope iterators for + // flat strings. + template <class _CharT, class _Alloc> + int + rope<_CharT, _Alloc>:: + _S_compare (const _RopeRep* __left, const _RopeRep* __right) + { + size_t __left_len; + size_t __right_len; + + if (0 == __right) + return 0 != __left; + if (0 == __left) + return -1; + __left_len = __left->_M_size; + __right_len = __right->_M_size; + if (__detail::_S_leaf == __left->_M_tag) + { + _RopeLeaf* __l = (_RopeLeaf*) __left; + if (__detail::_S_leaf == __right->_M_tag) + { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way(__l->_M_data, + __l->_M_data + __left_len, + __r->_M_data, __r->_M_data + + __right_len); + } + else + { + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); + return lexicographical_compare_3way(__l->_M_data, __l->_M_data + + __left_len, + __rstart, __rend); + } + } + else + { + const_iterator __lstart(__left, 0); + const_iterator __lend(__left, __left_len); + if (__detail::_S_leaf == __right->_M_tag) + { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way(__lstart, __lend, + __r->_M_data, __r->_M_data + + __right_len); + } + else + { + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); + return lexicographical_compare_3way(__lstart, __lend, + __rstart, __rend); + } + } + } + + // Assignment to reference proxies. + template <class _CharT, class _Alloc> + _Rope_char_ref_proxy<_CharT, _Alloc>& + _Rope_char_ref_proxy<_CharT, _Alloc>:: + operator=(_CharT __c) + { + _RopeRep* __old = _M_root->_M_tree_ptr; +#ifndef __GC + // First check for the case in which everything is uniquely + // referenced. In that case we can do this destructively. + _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); + if (0 != __ptr) + { + *__ptr = __c; + return *this; + } +#endif + _Self_destruct_ptr __left(_My_rope::_S_substring(__old, 0, _M_pos)); + _Self_destruct_ptr __right(_My_rope::_S_substring(__old, _M_pos + 1, + __old->_M_size)); + _Self_destruct_ptr __result_left(_My_rope:: + _S_destr_concat_char_iter(__left, + &__c, 1)); + + _RopeRep* __result = _My_rope::_S_concat(__result_left, __right); +#ifndef __GC + _RopeRep::_S_unref(__old); +#endif + _M_root->_M_tree_ptr = __result; + return *this; + } + + template <class _CharT, class _Alloc> + inline _Rope_char_ref_proxy<_CharT, _Alloc>:: + operator _CharT() const + { + if (_M_current_valid) + return _M_current; + else + return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); + } + + template <class _CharT, class _Alloc> + _Rope_char_ptr_proxy<_CharT, _Alloc> + _Rope_char_ref_proxy<_CharT, _Alloc>:: + operator&() const + { return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); } + + template <class _CharT, class _Alloc> + rope<_CharT, _Alloc>:: + rope(size_t __n, _CharT __c, const allocator_type& __a) + : _Base(__a) + { + rope<_CharT,_Alloc> __result; + const size_t __exponentiate_threshold = 32; + size_t __exponent; + size_t __rest; + _CharT* __rest_buffer; + _RopeRep* __remainder; + rope<_CharT, _Alloc> __remainder_rope; + + if (0 == __n) + return; + + __exponent = __n / __exponentiate_threshold; + __rest = __n % __exponentiate_threshold; + if (0 == __rest) + __remainder = 0; + else + { + __rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest)); + __uninitialized_fill_n_a(__rest_buffer, __rest, __c, + get_allocator()); + _S_cond_store_eos(__rest_buffer[__rest]); + try + { __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a); + __throw_exception_again; + } + } + __remainder_rope._M_tree_ptr = __remainder; + if (__exponent != 0) + { + _CharT* __base_buffer = + this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); + _RopeLeaf* __base_leaf; + rope __base_rope; + __uninitialized_fill_n_a(__base_buffer, __exponentiate_threshold, __c, + get_allocator()); + _S_cond_store_eos(__base_buffer[__exponentiate_threshold]); + try + { + __base_leaf = _S_new_RopeLeaf(__base_buffer, + __exponentiate_threshold, __a); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__base_buffer, + __exponentiate_threshold, __a); + __throw_exception_again; + } + __base_rope._M_tree_ptr = __base_leaf; + if (1 == __exponent) + __result = __base_rope; + else + __result = power(__base_rope, __exponent, + _Rope_Concat_fn<_CharT, _Alloc>()); + + if (0 != __remainder) + __result += __remainder_rope; + } + else + __result = __remainder_rope; + + this->_M_tree_ptr = __result._M_tree_ptr; + this->_M_tree_ptr->_M_ref_nonnil(); + } + + template<class _CharT, class _Alloc> + _CharT + rope<_CharT, _Alloc>::_S_empty_c_str[1]; + + template<class _CharT, class _Alloc> + const _CharT* + rope<_CharT, _Alloc>:: + c_str() const + { + if (0 == this->_M_tree_ptr) + { + _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, + // but probably fast. + return _S_empty_c_str; + } + __gthread_mutex_lock (&this->_M_tree_ptr->_M_c_string_lock); + __GC_CONST _CharT* __result = this->_M_tree_ptr->_M_c_string; + if (0 == __result) + { + size_t __s = size(); + __result = this->_Data_allocate(__s + 1); + _S_flatten(this->_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + this->_M_tree_ptr->_M_c_string = __result; + } + __gthread_mutex_unlock (&this->_M_tree_ptr->_M_c_string_lock); + return(__result); + } + + template<class _CharT, class _Alloc> + const _CharT* rope<_CharT, _Alloc>:: + replace_with_c_str() + { + if (0 == this->_M_tree_ptr) + { + _S_empty_c_str[0] = _S_eos((_CharT*)0); + return _S_empty_c_str; + } + __GC_CONST _CharT* __old_c_string = this->_M_tree_ptr->_M_c_string; + if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag + && 0 != __old_c_string) + return(__old_c_string); + size_t __s = size(); + _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s)); + _S_flatten(this->_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + this->_M_tree_ptr->_M_unref_nonnil(); + this->_M_tree_ptr = _S_new_RopeLeaf(__result, __s, + this->get_allocator()); + return(__result); + } + + // Algorithm specializations. More should be added. + + template<class _Rope_iterator> // was templated on CharT and Alloc + void // VC++ workaround + _Rope_rotate(_Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) + { + typedef typename _Rope_iterator::value_type _CharT; + typedef typename _Rope_iterator::_allocator_type _Alloc; + + rope<_CharT, _Alloc>& __r(__first.container()); + rope<_CharT, _Alloc> __prefix = __r.substr(0, __first.index()); + rope<_CharT, _Alloc> __suffix = + __r.substr(__last.index(), __r.size() - __last.index()); + rope<_CharT, _Alloc> __part1 = + __r.substr(__middle.index(), __last.index() - __middle.index()); + rope<_CharT, _Alloc> __part2 = + __r.substr(__first.index(), __middle.index() - __first.index()); + __r = __prefix; + __r += __part1; + __r += __part2; + __r += __suffix; + } + +#if !defined(__GNUC__) + // Appears to confuse g++ + inline void + rotate(_Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __first, + _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __middle, + _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __last) + { _Rope_rotate(__first, __middle, __last); } +#endif + +# if 0 + // Probably not useful for several reasons: + // - for SGIs 7.1 compiler and probably some others, + // this forces lots of rope<wchar_t, ...> instantiations, creating a + // code bloat and compile time problem. (Fixed in 7.2.) + // - wchar_t is 4 bytes wide on most UNIX platforms, making it + // unattractive for unicode strings. Unsigned short may be a better + // character type. + inline void + rotate(_Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __first, + _Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __middle, + _Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __last) + { _Rope_rotate(__first, __middle, __last); } +# endif + +_GLIBCXX_END_NAMESPACE diff --git a/libstdc++/include/ext/slist b/libstdc++/include/ext/slist new file mode 100644 index 0000000..328a52e --- /dev/null +++ b/libstdc++/include/ext/slist @@ -0,0 +1,1081 @@ +// Singly-linked list implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/slist + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). + */ + +#ifndef _SLIST +#define _SLIST 1 + +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/concept_check.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + using std::_Construct; + using std::_Destroy; + using std::allocator; + using std::__true_type; + using std::__false_type; + + struct _Slist_node_base + { + _Slist_node_base* _M_next; + }; + + inline _Slist_node_base* + __slist_make_link(_Slist_node_base* __prev_node, + _Slist_node_base* __new_node) + { + __new_node->_M_next = __prev_node->_M_next; + __prev_node->_M_next = __new_node; + return __new_node; + } + + inline _Slist_node_base* + __slist_previous(_Slist_node_base* __head, + const _Slist_node_base* __node) + { + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; + } + + inline const _Slist_node_base* + __slist_previous(const _Slist_node_base* __head, + const _Slist_node_base* __node) + { + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; + } + + inline void + __slist_splice_after(_Slist_node_base* __pos, + _Slist_node_base* __before_first, + _Slist_node_base* __before_last) + { + if (__pos != __before_first && __pos != __before_last) + { + _Slist_node_base* __first = __before_first->_M_next; + _Slist_node_base* __after = __pos->_M_next; + __before_first->_M_next = __before_last->_M_next; + __pos->_M_next = __first; + __before_last->_M_next = __after; + } + } + + inline void + __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head) + { + _Slist_node_base* __before_last = __slist_previous(__head, 0); + if (__before_last != __head) + { + _Slist_node_base* __after = __pos->_M_next; + __pos->_M_next = __head->_M_next; + __head->_M_next = 0; + __before_last->_M_next = __after; + } + } + + inline _Slist_node_base* + __slist_reverse(_Slist_node_base* __node) + { + _Slist_node_base* __result = __node; + __node = __node->_M_next; + __result->_M_next = 0; + while(__node) + { + _Slist_node_base* __next = __node->_M_next; + __node->_M_next = __result; + __result = __node; + __node = __next; + } + return __result; + } + + inline size_t + __slist_size(_Slist_node_base* __node) + { + size_t __result = 0; + for (; __node != 0; __node = __node->_M_next) + ++__result; + return __result; + } + + template <class _Tp> + struct _Slist_node : public _Slist_node_base + { + _Tp _M_data; + }; + + struct _Slist_iterator_base + { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Slist_node_base* _M_node; + + _Slist_iterator_base(_Slist_node_base* __x) + : _M_node(__x) {} + + void + _M_incr() + { _M_node = _M_node->_M_next; } + + bool + operator==(const _Slist_iterator_base& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Slist_iterator_base& __x) const + { return _M_node != __x._M_node; } + }; + + template <class _Tp, class _Ref, class _Ptr> + struct _Slist_iterator : public _Slist_iterator_base + { + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + typedef _Slist_iterator<_Tp, _Ref, _Ptr> _Self; + + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _Slist_node<_Tp> _Node; + + explicit + _Slist_iterator(_Node* __x) + : _Slist_iterator_base(__x) {} + + _Slist_iterator() + : _Slist_iterator_base(0) {} + + _Slist_iterator(const iterator& __x) + : _Slist_iterator_base(__x._M_node) {} + + reference + operator*() const + { return ((_Node*) _M_node)->_M_data; } + + pointer + operator->() const + { return &(operator*()); } + + _Self& + operator++() + { + _M_incr(); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_incr(); + return __tmp; + } + }; + + template <class _Tp, class _Alloc> + struct _Slist_base + : public _Alloc::template rebind<_Slist_node<_Tp> >::other + { + typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other + _Node_alloc; + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast<const _Node_alloc*>(this); } + + _Slist_base(const allocator_type& __a) + : _Node_alloc(__a) + { this->_M_head._M_next = 0; } + + ~_Slist_base() + { _M_erase_after(&this->_M_head, 0); } + + protected: + _Slist_node_base _M_head; + + _Slist_node<_Tp>* + _M_get_node() + { return _Node_alloc::allocate(1); } + + void + _M_put_node(_Slist_node<_Tp>* __p) + { _Node_alloc::deallocate(__p, 1); } + + protected: + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + get_allocator().destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); + }; + + template <class _Tp, class _Alloc> + _Slist_node_base* + _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first, + _Slist_node_base* __last_node) + { + _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next); + while (__cur != __last_node) + { + _Slist_node<_Tp>* __tmp = __cur; + __cur = (_Slist_node<_Tp>*) __cur->_M_next; + get_allocator().destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + __before_first->_M_next = __last_node; + return __last_node; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template <class _Tp, class _Alloc = allocator<_Tp> > + class slist : private _Slist_base<_Tp,_Alloc> + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + private: + typedef _Slist_base<_Tp,_Alloc> _Base; + + public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + private: + typedef _Slist_node<_Tp> _Node; + typedef _Slist_node_base _Node_base; + typedef _Slist_iterator_base _Iterator_base; + + _Node* + _M_create_node(const value_type& __x) + { + _Node* __node = this->_M_get_node(); + try + { + get_allocator().construct(&__node->_M_data, __x); + __node->_M_next = 0; + } + catch(...) + { + this->_M_put_node(__node); + __throw_exception_again; + } + return __node; + } + + _Node* + _M_create_node() + { + _Node* __node = this->_M_get_node(); + try + { + get_allocator().construct(&__node->_M_data, value_type()); + __node->_M_next = 0; + } + catch(...) + { + this->_M_put_node(__node); + __throw_exception_again; + } + return __node; + } + + public: + explicit + slist(const allocator_type& __a = allocator_type()) + : _Base(__a) {} + + slist(size_type __n, const value_type& __x, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { _M_insert_after_fill(&this->_M_head, __n, __x); } + + explicit + slist(size_type __n) + : _Base(allocator_type()) + { _M_insert_after_fill(&this->_M_head, __n, value_type()); } + + // We don't need any dispatching tricks here, because + // _M_insert_after_range already does them. + template <class _InputIterator> + slist(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { _M_insert_after_range(&this->_M_head, __first, __last); } + + slist(const slist& __x) + : _Base(__x.get_allocator()) + { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); } + + slist& + operator= (const slist& __x); + + ~slist() {} + + public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void + assign(size_type __n, const _Tp& __val) + { _M_fill_assign(__n, __val); } + + void + _M_fill_assign(size_type __n, const _Tp& __val); + + template <class _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template <class _Integer> + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template <class _InputIterator> + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + + public: + + iterator + begin() + { return iterator((_Node*)this->_M_head._M_next); } + + const_iterator + begin() const + { return const_iterator((_Node*)this->_M_head._M_next);} + + iterator + end() + { return iterator(0); } + + const_iterator + end() const + { return const_iterator(0); } + + // Experimental new feature: before_begin() returns a + // non-dereferenceable iterator that, when incremented, yields + // begin(). This iterator may be used as the argument to + // insert_after, erase_after, etc. Note that even for an empty + // slist, before_begin() is not the same iterator as end(). It + // is always necessary to increment before_begin() at least once to + // obtain end(). + iterator + before_begin() + { return iterator((_Node*) &this->_M_head); } + + const_iterator + before_begin() const + { return const_iterator((_Node*) &this->_M_head); } + + size_type + size() const + { return __slist_size(this->_M_head._M_next); } + + size_type + max_size() const + { return size_type(-1); } + + bool + empty() const + { return this->_M_head._M_next == 0; } + + void + swap(slist& __x) + { std::swap(this->_M_head._M_next, __x._M_head._M_next); } + + public: + + reference + front() + { return ((_Node*) this->_M_head._M_next)->_M_data; } + + const_reference + front() const + { return ((_Node*) this->_M_head._M_next)->_M_data; } + + void + push_front(const value_type& __x) + { __slist_make_link(&this->_M_head, _M_create_node(__x)); } + + void + push_front() + { __slist_make_link(&this->_M_head, _M_create_node()); } + + void + pop_front() + { + _Node* __node = (_Node*) this->_M_head._M_next; + this->_M_head._M_next = __node->_M_next; + get_allocator().destroy(&__node->_M_data); + this->_M_put_node(__node); + } + + iterator + previous(const_iterator __pos) + { return iterator((_Node*) __slist_previous(&this->_M_head, + __pos._M_node)); } + + const_iterator + previous(const_iterator __pos) const + { return const_iterator((_Node*) __slist_previous(&this->_M_head, + __pos._M_node)); } + + private: + _Node* + _M_insert_after(_Node_base* __pos, const value_type& __x) + { return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); } + + _Node* + _M_insert_after(_Node_base* __pos) + { return (_Node*) (__slist_make_link(__pos, _M_create_node())); } + + void + _M_insert_after_fill(_Node_base* __pos, + size_type __n, const value_type& __x) + { + for (size_type __i = 0; __i < __n; ++__i) + __pos = __slist_make_link(__pos, _M_create_node(__x)); + } + + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InIterator> + void + _M_insert_after_range(_Node_base* __pos, + _InIterator __first, _InIterator __last) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + _M_insert_after_range(__pos, __first, __last, _Integral()); + } + + template <class _Integer> + void + _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + __true_type) + { _M_insert_after_fill(__pos, __n, __x); } + + template <class _InIterator> + void + _M_insert_after_range(_Node_base* __pos, + _InIterator __first, _InIterator __last, + __false_type) + { + while (__first != __last) + { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + + public: + iterator + insert_after(iterator __pos, const value_type& __x) + { return iterator(_M_insert_after(__pos._M_node, __x)); } + + iterator + insert_after(iterator __pos) + { return insert_after(__pos, value_type()); } + + void + insert_after(iterator __pos, size_type __n, const value_type& __x) + { _M_insert_after_fill(__pos._M_node, __n, __x); } + + // We don't need any dispatching tricks here, because + // _M_insert_after_range already does them. + template <class _InIterator> + void + insert_after(iterator __pos, _InIterator __first, _InIterator __last) + { _M_insert_after_range(__pos._M_node, __first, __last); } + + iterator + insert(iterator __pos, const value_type& __x) + { return iterator(_M_insert_after(__slist_previous(&this->_M_head, + __pos._M_node), + __x)); } + + iterator + insert(iterator __pos) + { return iterator(_M_insert_after(__slist_previous(&this->_M_head, + __pos._M_node), + value_type())); } + + void + insert(iterator __pos, size_type __n, const value_type& __x) + { _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node), + __n, __x); } + + // We don't need any dispatching tricks here, because + // _M_insert_after_range already does them. + template <class _InIterator> + void + insert(iterator __pos, _InIterator __first, _InIterator __last) + { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), + __first, __last); } + + public: + iterator + erase_after(iterator __pos) + { return iterator((_Node*) this->_M_erase_after(__pos._M_node)); } + + iterator + erase_after(iterator __before_first, iterator __last) + { + return iterator((_Node*) this->_M_erase_after(__before_first._M_node, + __last._M_node)); + } + + iterator + erase(iterator __pos) + { + return iterator((_Node*) this->_M_erase_after + (__slist_previous(&this->_M_head, __pos._M_node))); + } + + iterator + erase(iterator __first, iterator __last) + { + return iterator((_Node*) this->_M_erase_after + (__slist_previous(&this->_M_head, __first._M_node), + __last._M_node)); + } + + void + resize(size_type new_size, const _Tp& __x); + + void + resize(size_type new_size) + { resize(new_size, _Tp()); } + + void + clear() + { this->_M_erase_after(&this->_M_head, 0); } + + public: + // Moves the range [__before_first + 1, __before_last + 1) to *this, + // inserting it immediately after __pos. This is constant time. + void + splice_after(iterator __pos, + iterator __before_first, iterator __before_last) + { + if (__before_first != __before_last) + __slist_splice_after(__pos._M_node, __before_first._M_node, + __before_last._M_node); + } + + // Moves the element that follows __prev to *this, inserting it + // immediately after __pos. This is constant time. + void + splice_after(iterator __pos, iterator __prev) + { __slist_splice_after(__pos._M_node, + __prev._M_node, __prev._M_node->_M_next); } + + // Removes all of the elements from the list __x to *this, inserting + // them immediately after __pos. __x must not be *this. Complexity: + // linear in __x.size(). + void + splice_after(iterator __pos, slist& __x) + { __slist_splice_after(__pos._M_node, &__x._M_head); } + + // Linear in distance(begin(), __pos), and linear in __x.size(). + void + splice(iterator __pos, slist& __x) + { + if (__x._M_head._M_next) + __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + &__x._M_head, + __slist_previous(&__x._M_head, 0)); } + + // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i). + void + splice(iterator __pos, slist& __x, iterator __i) + { __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __i._M_node), + __i._M_node); } + + // Linear in distance(begin(), __pos), in distance(__x.begin(), __first), + // and in distance(__first, __last). + void + splice(iterator __pos, slist& __x, iterator __first, iterator __last) + { + if (__first != __last) + __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __first._M_node), + __slist_previous(__first._M_node, + __last._M_node)); + } + + public: + void + reverse() + { + if (this->_M_head._M_next) + this->_M_head._M_next = __slist_reverse(this->_M_head._M_next); + } + + void + remove(const _Tp& __val); + + void + unique(); + + void + merge(slist& __x); + + void + sort(); + + template <class _Predicate> + void + remove_if(_Predicate __pred); + + template <class _BinaryPredicate> + void + unique(_BinaryPredicate __pred); + + template <class _StrictWeakOrdering> + void + merge(slist&, _StrictWeakOrdering); + + template <class _StrictWeakOrdering> + void + sort(_StrictWeakOrdering __comp); + }; + + template <class _Tp, class _Alloc> + slist<_Tp, _Alloc>& + slist<_Tp, _Alloc>::operator=(const slist<_Tp, _Alloc>& __x) + { + if (&__x != this) + { + _Node_base* __p1 = &this->_M_head; + _Node* __n1 = (_Node*) this->_M_head._M_next; + const _Node* __n2 = (const _Node*) __x._M_head._M_next; + while (__n1 && __n2) + { + __n1->_M_data = __n2->_M_data; + __p1 = __n1; + __n1 = (_Node*) __n1->_M_next; + __n2 = (const _Node*) __n2->_M_next; + } + if (__n2 == 0) + this->_M_erase_after(__p1, 0); + else + _M_insert_after_range(__p1, const_iterator((_Node*)__n2), + const_iterator(0)); + } + return *this; + } + + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) + { + _Node_base* __prev = &this->_M_head; + _Node* __node = (_Node*) this->_M_head._M_next; + for (; __node != 0 && __n > 0; --__n) + { + __node->_M_data = __val; + __prev = __node; + __node = (_Node*) __node->_M_next; + } + if (__n > 0) + _M_insert_after_fill(__prev, __n, __val); + else + this->_M_erase_after(__prev, 0); + } + + template <class _Tp, class _Alloc> + template <class _InputIterator> + void + slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first, + _InputIterator __last, + __false_type) + { + _Node_base* __prev = &this->_M_head; + _Node* __node = (_Node*) this->_M_head._M_next; + while (__node != 0 && __first != __last) + { + __node->_M_data = *__first; + __prev = __node; + __node = (_Node*) __node->_M_next; + ++__first; + } + if (__first != __last) + _M_insert_after_range(__prev, __first, __last); + else + this->_M_erase_after(__prev, 0); + } + + template <class _Tp, class _Alloc> + inline bool + operator==(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { + typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = _SL1.end(); + const_iterator __end2 = _SL2.end(); + + const_iterator __i1 = _SL1.begin(); + const_iterator __i2 = _SL2.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) + { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; + } + + + template <class _Tp, class _Alloc> + inline bool + operator<(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return std::lexicographical_compare(_SL1.begin(), _SL1.end(), + _SL2.begin(), _SL2.end()); } + + template <class _Tp, class _Alloc> + inline bool + operator!=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return !(_SL1 == _SL2); } + + template <class _Tp, class _Alloc> + inline bool + operator>(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return _SL2 < _SL1; } + + template <class _Tp, class _Alloc> + inline bool + operator<=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return !(_SL2 < _SL1); } + + template <class _Tp, class _Alloc> + inline bool + operator>=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return !(_SL1 < _SL2); } + + template <class _Tp, class _Alloc> + inline void + swap(slist<_Tp, _Alloc>& __x, slist<_Tp, _Alloc>& __y) + { __x.swap(__y); } + + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::resize(size_type __len, const _Tp& __x) + { + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next != 0 && __len > 0) + { + --__len; + __cur = __cur->_M_next; + } + if (__cur->_M_next) + this->_M_erase_after(__cur, 0); + else + _M_insert_after_fill(__cur, __len, __x); + } + + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::remove(const _Tp& __val) + { + _Node_base* __cur = &this->_M_head; + while (__cur && __cur->_M_next) + { + if (((_Node*) __cur->_M_next)->_M_data == __val) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } + + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::unique() + { + _Node_base* __cur = this->_M_head._M_next; + if (__cur) + { + while (__cur->_M_next) + { + if (((_Node*)__cur)->_M_data + == ((_Node*)(__cur->_M_next))->_M_data) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } + } + + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x) + { + _Node_base* __n1 = &this->_M_head; + while (__n1->_M_next && __x._M_head._M_next) + { + if (((_Node*) __x._M_head._M_next)->_M_data + < ((_Node*) __n1->_M_next)->_M_data) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) + { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } + } + + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::sort() + { + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) + { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) + { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) + { + __counter[__i].merge(__carry); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + this->swap(__counter[__fill-1]); + } + } + + template <class _Tp, class _Alloc> + template <class _Predicate> + void slist<_Tp, _Alloc>::remove_if(_Predicate __pred) + { + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next) + { + if (__pred(((_Node*) __cur->_M_next)->_M_data)) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } + + template <class _Tp, class _Alloc> + template <class _BinaryPredicate> + void + slist<_Tp, _Alloc>::unique(_BinaryPredicate __pred) + { + _Node* __cur = (_Node*) this->_M_head._M_next; + if (__cur) + { + while (__cur->_M_next) + { + if (__pred(((_Node*)__cur)->_M_data, + ((_Node*)(__cur->_M_next))->_M_data)) + this->_M_erase_after(__cur); + else + __cur = (_Node*) __cur->_M_next; + } + } + } + + template <class _Tp, class _Alloc> + template <class _StrictWeakOrdering> + void + slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x, + _StrictWeakOrdering __comp) + { + _Node_base* __n1 = &this->_M_head; + while (__n1->_M_next && __x._M_head._M_next) + { + if (__comp(((_Node*) __x._M_head._M_next)->_M_data, + ((_Node*) __n1->_M_next)->_M_data)) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) + { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } + } + + template <class _Tp, class _Alloc> + template <class _StrictWeakOrdering> + void + slist<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) + { + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) + { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) + { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) + { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + this->swap(__counter[__fill-1]); + } + } + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Specialization of insert_iterator so that insertions will be constant + // time rather than linear time. + template <class _Tp, class _Alloc> + class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> > + { + protected: + typedef __gnu_cxx::slist<_Tp, _Alloc> _Container; + _Container* container; + typename _Container::iterator iter; + + public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x) + { + if (__i == __x.begin()) + iter = __x.before_begin(); + else + iter = __x.previous(__i); + } + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + iter = container->insert_after(iter, __value); + return *this; + } + + insert_iterator<_Container>& + operator*() + { return *this; } + + insert_iterator<_Container>& + operator++() + { return *this; } + + insert_iterator<_Container>& + operator++(int) + { return *this; } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/sso_string_base.h b/libstdc++/include/ext/sso_string_base.h new file mode 100644 index 0000000..c95b48e --- /dev/null +++ b/libstdc++/include/ext/sso_string_base.h @@ -0,0 +1,569 @@ +// Short-string-optimized versatile string base -*- C++ -*- + +// Copyright (C) 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. + +/** @file ext/sso_string_base.h + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _SSO_STRING_BASE_H +#define _SSO_STRING_BASE_H 1 + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _CharT, typename _Traits, typename _Alloc> + class __sso_string_base + : protected __vstring_utility<_CharT, _Traits, _Alloc> + { + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + + typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base; + typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type; + typedef typename _CharT_alloc_type::size_type size_type; + + private: + // Data Members: + typename _Util_Base::template _Alloc_hider<_CharT_alloc_type> + _M_dataplus; + size_type _M_string_length; + + enum { _S_local_capacity = 15 }; + + union + { + _CharT _M_local_data[_S_local_capacity + 1]; + size_type _M_allocated_capacity; + }; + + void + _M_data(_CharT* __p) + { _M_dataplus._M_p = __p; } + + void + _M_length(size_type __length) + { _M_string_length = __length; } + + void + _M_capacity(size_type __capacity) + { _M_allocated_capacity = __capacity; } + + bool + _M_is_local() const + { return _M_data() == _M_local_data; } + + // Create & Destroy + _CharT* + _M_create(size_type&, size_type); + + void + _M_dispose() + { + if (!_M_is_local()) + _M_destroy(_M_allocated_capacity); + } + + void + _M_destroy(size_type __size) throw() + { _M_get_allocator().deallocate(_M_data(), __size + 1); } + + // _M_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIterator is an integral type + template<typename _InIterator> + void + _M_construct_aux(_InIterator __beg, _InIterator __end, + std::__false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + _M_construct(__beg, __end, _Tag()); + } + + template<typename _InIterator> + void + _M_construct_aux(_InIterator __beg, _InIterator __end, + std::__true_type) + { _M_construct(static_cast<size_type>(__beg), + static_cast<value_type>(__end)); } + + template<typename _InIterator> + void + _M_construct(_InIterator __beg, _InIterator __end) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + _M_construct_aux(__beg, __end, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template<typename _InIterator> + void + _M_construct(_InIterator __beg, _InIterator __end, + std::input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template<typename _FwdIterator> + void + _M_construct(_FwdIterator __beg, _FwdIterator __end, + std::forward_iterator_tag); + + void + _M_construct(size_type __req, _CharT __c); + + public: + size_type + _M_max_size() const + { return (_M_get_allocator().max_size() - 1) / 2; } + + _CharT* + _M_data() const + { return _M_dataplus._M_p; } + + size_type + _M_length() const + { return _M_string_length; } + + size_type + _M_capacity() const + { + return _M_is_local() ? size_type(_S_local_capacity) + : _M_allocated_capacity; + } + + bool + _M_is_shared() const + { return false; } + + void + _M_set_leaked() { } + + void + _M_leak() { } + + void + _M_set_length(size_type __n) + { + _M_length(__n); + traits_type::assign(_M_data()[__n], _CharT()); + } + + __sso_string_base() + : _M_dataplus(_Alloc(), _M_local_data) + { _M_set_length(0); } + + __sso_string_base(const _Alloc& __a); + + __sso_string_base(const __sso_string_base& __rcs); + + __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a); + + template<typename _InputIterator> + __sso_string_base(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a); + + ~__sso_string_base() + { _M_dispose(); } + + _CharT_alloc_type& + _M_get_allocator() + { return _M_dataplus; } + + const _CharT_alloc_type& + _M_get_allocator() const + { return _M_dataplus; } + + void + _M_swap(__sso_string_base& __rcs); + + void + _M_assign(const __sso_string_base& __rcs); + + void + _M_reserve(size_type __res); + + void + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2); + + void + _M_erase(size_type __pos, size_type __n); + + void + _M_clear() + { _M_set_length(0); } + + bool + _M_compare(const __sso_string_base&) const + { return false; } + }; + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_swap(__sso_string_base& __rcs) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<_CharT_alloc_type>::_S_do_it(_M_get_allocator(), + __rcs._M_get_allocator()); + + if (_M_is_local()) + if (__rcs._M_is_local()) + { + if (_M_length() && __rcs._M_length()) + { + _CharT __tmp_data[_S_local_capacity + 1]; + traits_type::copy(__tmp_data, __rcs._M_local_data, + _S_local_capacity + 1); + traits_type::copy(__rcs._M_local_data, _M_local_data, + _S_local_capacity + 1); + traits_type::copy(_M_local_data, __tmp_data, + _S_local_capacity + 1); + } + else if (__rcs._M_length()) + { + traits_type::copy(_M_local_data, __rcs._M_local_data, + _S_local_capacity + 1); + _M_length(__rcs._M_length()); + __rcs._M_set_length(0); + return; + } + else if (_M_length()) + { + traits_type::copy(__rcs._M_local_data, _M_local_data, + _S_local_capacity + 1); + __rcs._M_length(_M_length()); + _M_set_length(0); + return; + } + } + else + { + const size_type __tmp_capacity = __rcs._M_allocated_capacity; + traits_type::copy(__rcs._M_local_data, _M_local_data, + _S_local_capacity + 1); + _M_data(__rcs._M_data()); + __rcs._M_data(__rcs._M_local_data); + _M_capacity(__tmp_capacity); + } + else + { + const size_type __tmp_capacity = _M_allocated_capacity; + if (__rcs._M_is_local()) + { + traits_type::copy(_M_local_data, __rcs._M_local_data, + _S_local_capacity + 1); + __rcs._M_data(_M_data()); + _M_data(_M_local_data); + } + else + { + _CharT* __tmp_ptr = _M_data(); + _M_data(__rcs._M_data()); + __rcs._M_data(__tmp_ptr); + _M_capacity(__rcs._M_allocated_capacity); + } + __rcs._M_capacity(__tmp_capacity); + } + + const size_type __tmp_length = _M_length(); + _M_length(__rcs._M_length()); + __rcs._M_length(__tmp_length); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_create(size_type& __capacity, size_type __old_capacity) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + if (__capacity > _M_max_size()) + std::__throw_length_error(__N("__sso_string_base::_M_create")); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) + { + __capacity = 2 * __old_capacity; + // Never allocate a string bigger than max_size. + if (__capacity > _M_max_size()) + __capacity = _M_max_size(); + } + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element. + return _M_get_allocator().allocate(__capacity + 1); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + __sso_string_base<_CharT, _Traits, _Alloc>:: + __sso_string_base(const _Alloc& __a) + : _M_dataplus(__a, _M_local_data) + { _M_set_length(0); } + + template<typename _CharT, typename _Traits, typename _Alloc> + __sso_string_base<_CharT, _Traits, _Alloc>:: + __sso_string_base(const __sso_string_base& __rcs) + : _M_dataplus(__rcs._M_get_allocator(), _M_local_data) + { _M_construct(__rcs._M_data(), __rcs._M_data() + __rcs._M_length()); } + + template<typename _CharT, typename _Traits, typename _Alloc> + __sso_string_base<_CharT, _Traits, _Alloc>:: + __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a) + : _M_dataplus(__a, _M_local_data) + { _M_construct(__n, __c); } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InputIterator> + __sso_string_base<_CharT, _Traits, _Alloc>:: + __sso_string_base(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a) + : _M_dataplus(__a, _M_local_data) + { _M_construct(__beg, __end); } + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_construct(_InIterator __beg, _InIterator __end, + std::input_iterator_tag) + { + size_type __len = 0; + size_type __capacity = size_type(_S_local_capacity); + + while (__beg != __end && __len < __capacity) + { + _M_data()[__len++] = *__beg; + ++__beg; + } + + try + { + while (__beg != __end) + { + if (__len == __capacity) + { + // Allocate more space. + __capacity = __len + 1; + _CharT* __another = _M_create(__capacity, __len); + _S_copy(__another, _M_data(), __len); + _M_dispose(); + _M_data(__another); + _M_capacity(__capacity); + } + _M_data()[__len++] = *__beg; + ++__beg; + } + } + catch(...) + { + _M_dispose(); + __throw_exception_again; + } + + _M_set_length(__len); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_construct(_InIterator __beg, _InIterator __end, + std::forward_iterator_tag) + { + // NB: Not required, but considered best practice. + if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0)) + std::__throw_logic_error(__N("__sso_string_base::" + "_M_construct NULL not valid")); + + size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); + + if (__dnew > size_type(_S_local_capacity)) + { + _M_data(_M_create(__dnew, size_type(0))); + _M_capacity(__dnew); + } + + // Check for out_of_range and length_error exceptions. + try + { _S_copy_chars(_M_data(), __beg, __end); } + catch(...) + { + _M_dispose(); + __throw_exception_again; + } + + _M_set_length(__dnew); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_construct(size_type __n, _CharT __c) + { + if (__n > size_type(_S_local_capacity)) + { + _M_data(_M_create(__n, size_type(0))); + _M_capacity(__n); + } + + if (__n) + _S_assign(_M_data(), __n, __c); + + _M_set_length(__n); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_assign(const __sso_string_base& __rcs) + { + if (this != &__rcs) + { + const size_type __rsize = __rcs._M_length(); + const size_type __capacity = _M_capacity(); + + if (__rsize > __capacity) + { + size_type __new_capacity = __rsize; + _CharT* __tmp = _M_create(__new_capacity, __capacity); + _M_dispose(); + _M_data(__tmp); + _M_capacity(__new_capacity); + } + + if (__rsize) + _S_copy(_M_data(), __rcs._M_data(), __rsize); + + _M_set_length(__rsize); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_reserve(size_type __res) + { + // Make sure we don't shrink below the current size. + if (__res < _M_length()) + __res = _M_length(); + + const size_type __capacity = _M_capacity(); + if (__res != __capacity) + { + if (__res > __capacity + || __res > size_type(_S_local_capacity)) + { + _CharT* __tmp = _M_create(__res, __capacity); + _S_copy(__tmp, _M_data(), _M_length() + 1); + _M_dispose(); + _M_data(__tmp); + _M_capacity(__res); + } + else if (!_M_is_local()) + { + _S_copy(_M_local_data, _M_data(), _M_length() + 1); + _M_destroy(__capacity); + _M_data(_M_local_data); + } + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2) + { + const size_type __how_much = _M_length() - __pos - __len1; + + size_type __new_capacity = _M_length() + __len2 - __len1; + _CharT* __r = _M_create(__new_capacity, _M_capacity()); + + if (__pos) + _S_copy(__r, _M_data(), __pos); + if (__s && __len2) + _S_copy(__r + __pos, __s, __len2); + if (__how_much) + _S_copy(__r + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_dispose(); + _M_data(__r); + _M_capacity(__new_capacity); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_erase(size_type __pos, size_type __n) + { + const size_type __how_much = _M_length() - __pos - __n; + + if (__how_much && __n) + _S_move(_M_data() + __pos, _M_data() + __pos + __n, + __how_much); + + _M_set_length(_M_length() - __n); + } + + template<> + inline bool + __sso_string_base<char, std::char_traits<char>, + std::allocator<char> >:: + _M_compare(const __sso_string_base& __rcs) const + { + if (this == &__rcs) + return true; + return false; + } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + inline bool + __sso_string_base<wchar_t, std::char_traits<wchar_t>, + std::allocator<wchar_t> >:: + _M_compare(const __sso_string_base& __rcs) const + { + if (this == &__rcs) + return true; + return false; + } +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _SSO_STRING_BASE_H */ diff --git a/libstdc++/include/ext/stdio_filebuf.h b/libstdc++/include/ext/stdio_filebuf.h new file mode 100644 index 0000000..312a217 --- /dev/null +++ b/libstdc++/include/ext/stdio_filebuf.h @@ -0,0 +1,162 @@ +// File descriptor layer for filebuf -*- C++ -*- + +// 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. + +/** @file ext/stdio_filebuf.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _STDIO_FILEBUF_H +#define _STDIO_FILEBUF_H 1 + +#pragma GCC system_header + +#include <fstream> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /** + * @brief Provides a layer of compatibility for C/POSIX. + * + * This GNU extension provides extensions for working with standard C + * FILE*'s and POSIX file descriptors. It must be instantiated by the + * user with the type of character used in the file stream, e.g., + * stdio_filebuf<char>. + */ + template<typename _CharT, typename _Traits = std::char_traits<_CharT> > + class stdio_filebuf : public std::basic_filebuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + typedef std::size_t size_t; + + public: + /** + * deferred initialization + */ + stdio_filebuf() : std::basic_filebuf<_CharT, _Traits>() {} + + /** + * @param fd An open file descriptor. + * @param mode Same meaning as in a standard filebuf. + * @param size Optimal or preferred size of internal buffer, in chars. + * + * This constructor associates a file stream buffer with an open + * POSIX file descriptor. The file descriptor will be automatically + * closed when the stdio_filebuf is closed/destroyed. + */ + stdio_filebuf(int __fd, std::ios_base::openmode __mode, + size_t __size = static_cast<size_t>(BUFSIZ)); + + /** + * @param f An open @c FILE*. + * @param mode Same meaning as in a standard filebuf. + * @param size Optimal or preferred size of internal buffer, in chars. + * Defaults to system's @c BUFSIZ. + * + * This constructor associates a file stream buffer with an open + * C @c FILE*. The @c FILE* will not be automatically closed when the + * stdio_filebuf is closed/destroyed. + */ + stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, + size_t __size = static_cast<size_t>(BUFSIZ)); + + /** + * Closes the external data stream if the file descriptor constructor + * was used. + */ + virtual + ~stdio_filebuf(); + + /** + * @return The underlying file descriptor. + * + * Once associated with an external data stream, this function can be + * used to access the underlying POSIX file descriptor. Note that + * there is no way for the library to track what you do with the + * descriptor, so be careful. + */ + int + fd() { return this->_M_file.fd(); } + + /** + * @return The underlying FILE*. + * + * This function can be used to access the underlying "C" file pointer. + * Note that there is no way for the library to track what you do + * with the file, so be careful. + */ + std::__c_file* + file() { return this->_M_file.file(); } + }; + + template<typename _CharT, typename _Traits> + stdio_filebuf<_CharT, _Traits>::~stdio_filebuf() + { } + + template<typename _CharT, typename _Traits> + stdio_filebuf<_CharT, _Traits>:: + stdio_filebuf(int __fd, std::ios_base::openmode __mode, size_t __size) + { + this->_M_file.sys_open(__fd, __mode); + if (this->is_open()) + { + this->_M_mode = __mode; + this->_M_buf_size = __size; + this->_M_allocate_internal_buffer(); + this->_M_reading = false; + this->_M_writing = false; + this->_M_set_buffer(-1); + } + } + + template<typename _CharT, typename _Traits> + stdio_filebuf<_CharT, _Traits>:: + stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, + size_t __size) + { + this->_M_file.sys_open(__f, __mode); + if (this->is_open()) + { + this->_M_mode = __mode; + this->_M_buf_size = __size; + this->_M_allocate_internal_buffer(); + this->_M_reading = false; + this->_M_writing = false; + this->_M_set_buffer(-1); + } + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/stdio_sync_filebuf.h b/libstdc++/include/ext/stdio_sync_filebuf.h new file mode 100644 index 0000000..f0ec12c --- /dev/null +++ b/libstdc++/include/ext/stdio_sync_filebuf.h @@ -0,0 +1,283 @@ +// Iostreams wrapper for stdio FILE* -*- C++ -*- + +// 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. + +/** @file ext/stdio_sync_filebuf.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _STDIO_SYNC_FILEBUF_H +#define _STDIO_SYNC_FILEBUF_H 1 + +#pragma GCC system_header + +#include <streambuf> +#include <unistd.h> +#include <cstdio> + +#ifdef _GLIBCXX_USE_WCHAR_T +#include <cwchar> +#endif + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /// @brief class stdio_sync_filebuf. + template<typename _CharT, typename _Traits = std::char_traits<_CharT> > + class stdio_sync_filebuf : public std::basic_streambuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + private: + // Underlying stdio FILE + std::__c_file* const _M_file; + + // Last character gotten. This is used when pbackfail is + // called from basic_streambuf::sungetc() + int_type _M_unget_buf; + + public: + explicit + stdio_sync_filebuf(std::__c_file* __f) + : _M_file(__f), _M_unget_buf(traits_type::eof()) + { } + + /** + * @return The underlying FILE*. + * + * This function can be used to access the underlying "C" file pointer. + * Note that there is no way for the library to track what you do + * with the file, so be careful. + */ + std::__c_file* const + file() { return this->_M_file; } + + protected: + int_type + syncgetc(); + + int_type + syncungetc(int_type __c); + + int_type + syncputc(int_type __c); + + virtual int_type + underflow() + { + int_type __c = this->syncgetc(); + return this->syncungetc(__c); + } + + virtual int_type + uflow() + { + // Store the gotten character in case we need to unget it. + _M_unget_buf = this->syncgetc(); + return _M_unget_buf; + } + + virtual int_type + pbackfail(int_type __c = traits_type::eof()) + { + int_type __ret; + const int_type __eof = traits_type::eof(); + + // Check if the unget or putback was requested + if (traits_type::eq_int_type(__c, __eof)) // unget + { + if (!traits_type::eq_int_type(_M_unget_buf, __eof)) + __ret = this->syncungetc(_M_unget_buf); + else // buffer invalid, fail. + __ret = __eof; + } + else // putback + __ret = this->syncungetc(__c); + + // The buffered character is no longer valid, discard it. + _M_unget_buf = __eof; + return __ret; + } + + virtual std::streamsize + xsgetn(char_type* __s, std::streamsize __n); + + virtual int_type + overflow(int_type __c = traits_type::eof()) + { + int_type __ret; + if (traits_type::eq_int_type(__c, traits_type::eof())) + { + if (std::fflush(_M_file)) + __ret = traits_type::eof(); + else + __ret = traits_type::not_eof(__c); + } + else + __ret = this->syncputc(__c); + return __ret; + } + + virtual std::streamsize + xsputn(const char_type* __s, std::streamsize __n); + + virtual int + sync() + { return std::fflush(_M_file); } + + virtual std::streampos + seekoff(std::streamoff __off, std::ios_base::seekdir __dir, + std::ios_base::openmode = std::ios_base::in | std::ios_base::out) + { + std::streampos __ret(std::streamoff(-1)); + int __whence; + if (__dir == std::ios_base::beg) + __whence = SEEK_SET; + else if (__dir == std::ios_base::cur) + __whence = SEEK_CUR; + else + __whence = SEEK_END; +#ifdef _GLIBCXX_USE_LFS + if (!fseeko64(_M_file, __off, __whence)) + __ret = std::streampos(ftello64(_M_file)); +#else + if (!fseek(_M_file, __off, __whence)) + __ret = std::streampos(std::ftell(_M_file)); +#endif + return __ret; + } + + virtual std::streampos + seekpos(std::streampos __pos, + std::ios_base::openmode __mode = + std::ios_base::in | std::ios_base::out) + { return seekoff(std::streamoff(__pos), std::ios_base::beg, __mode); } + }; + + template<> + inline stdio_sync_filebuf<char>::int_type + stdio_sync_filebuf<char>::syncgetc() + { return std::getc(_M_file); } + + template<> + inline stdio_sync_filebuf<char>::int_type + stdio_sync_filebuf<char>::syncungetc(int_type __c) + { return std::ungetc(__c, _M_file); } + + template<> + inline stdio_sync_filebuf<char>::int_type + stdio_sync_filebuf<char>::syncputc(int_type __c) + { return std::putc(__c, _M_file); } + + template<> + inline std::streamsize + stdio_sync_filebuf<char>::xsgetn(char* __s, std::streamsize __n) + { + std::streamsize __ret = std::fread(__s, 1, __n, _M_file); + if (__ret > 0) + _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); + else + _M_unget_buf = traits_type::eof(); + return __ret; + } + + template<> + inline std::streamsize + stdio_sync_filebuf<char>::xsputn(const char* __s, std::streamsize __n) + { return std::fwrite(__s, 1, __n, _M_file); } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + inline stdio_sync_filebuf<wchar_t>::int_type + stdio_sync_filebuf<wchar_t>::syncgetc() + { return std::getwc(_M_file); } + + template<> + inline stdio_sync_filebuf<wchar_t>::int_type + stdio_sync_filebuf<wchar_t>::syncungetc(int_type __c) + { return std::ungetwc(__c, _M_file); } + + template<> + inline stdio_sync_filebuf<wchar_t>::int_type + stdio_sync_filebuf<wchar_t>::syncputc(int_type __c) + { return std::putwc(__c, _M_file); } + + template<> + inline std::streamsize + stdio_sync_filebuf<wchar_t>::xsgetn(wchar_t* __s, std::streamsize __n) + { + std::streamsize __ret = 0; + const int_type __eof = traits_type::eof(); + while (__n--) + { + int_type __c = this->syncgetc(); + if (traits_type::eq_int_type(__c, __eof)) + break; + __s[__ret] = traits_type::to_char_type(__c); + ++__ret; + } + + if (__ret > 0) + _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); + else + _M_unget_buf = traits_type::eof(); + return __ret; + } + + template<> + inline std::streamsize + stdio_sync_filebuf<wchar_t>::xsputn(const wchar_t* __s, + std::streamsize __n) + { + std::streamsize __ret = 0; + const int_type __eof = traits_type::eof(); + while (__n--) + { + if (traits_type::eq_int_type(this->syncputc(*__s++), __eof)) + break; + ++__ret; + } + return __ret; + } +#endif + +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class stdio_sync_filebuf<char>; +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class stdio_sync_filebuf<wchar_t>; +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/throw_allocator.h b/libstdc++/include/ext/throw_allocator.h new file mode 100644 index 0000000..5886afc --- /dev/null +++ b/libstdc++/include/ext/throw_allocator.h @@ -0,0 +1,437 @@ +// -*- C++ -*- + +// Copyright (C) 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, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** @file ext/vstring.h + * This file is a GNU extension to the Standard C++ Library. + * + * Contains an exception-throwing allocator, useful for testing + * exception safety. In addition, allocation addresses are stored and + * sanity checked. + */ + +/** + * @file throw_allocator.h + */ + +#ifndef _THROW_ALLOCATOR_H +#define _THROW_ALLOCATOR_H 1 + +#include <cmath> +#include <map> +#include <set> +#include <string> +#include <ostream> +#include <stdexcept> +#include <utility> +#include <tr1/random> +#include <bits/functexcept.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + class twister_rand_gen + { + public: + twister_rand_gen(unsigned int seed = + static_cast<unsigned int>(std::time(0))); + + void + init(unsigned int); + + double + get_prob(); + + private: + std::tr1::mt19937 _M_generator; + }; + + struct forced_exception_error : public std::exception + { }; + + // Substitute for concurrence_error object in the case of -fno-exceptions. + inline void + __throw_forced_exception_error() + { +#if __EXCEPTIONS + throw forced_exception_error(); +#else + __builtin_abort(); +#endif + } + + class throw_allocator_base + { + public: + void + init(unsigned long seed); + + static void + set_throw_prob(double throw_prob); + + static double + get_throw_prob(); + + static void + set_label(size_t l); + + static bool + empty(); + + struct group_throw_prob_adjustor + { + group_throw_prob_adjustor(size_t size) + : _M_throw_prob_orig(_S_throw_prob) + { + _S_throw_prob = + 1 - ::pow(double(1 - _S_throw_prob), double(0.5 / (size + 1))); + } + + ~group_throw_prob_adjustor() + { _S_throw_prob = _M_throw_prob_orig; } + + private: + const double _M_throw_prob_orig; + }; + + struct zero_throw_prob_adjustor + { + zero_throw_prob_adjustor() : _M_throw_prob_orig(_S_throw_prob) + { _S_throw_prob = 0; } + + ~zero_throw_prob_adjustor() + { _S_throw_prob = _M_throw_prob_orig; } + + private: + const double _M_throw_prob_orig; + }; + + protected: + static void + insert(void*, size_t); + + static void + erase(void*, size_t); + + static void + throw_conditionally(); + + // See if a particular address and size has been allocated by this + // allocator. + static void + check_allocated(void*, size_t); + + // See if a given label has been allocated by this allocator. + static void + check_allocated(size_t); + + private: + typedef std::pair<size_t, size_t> alloc_data_type; + typedef std::map<void*, alloc_data_type> map_type; + typedef map_type::value_type entry_type; + typedef map_type::const_iterator const_iterator; + typedef map_type::const_reference const_reference; + + friend std::ostream& + operator<<(std::ostream&, const throw_allocator_base&); + + static entry_type + make_entry(void*, size_t); + + static void + print_to_string(std::string&); + + static void + print_to_string(std::string&, const_reference); + + static twister_rand_gen _S_g; + static map_type _S_map; + static double _S_throw_prob; + static size_t _S_label; + }; + + + template<typename T> + class throw_allocator : public throw_allocator_base + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + + template<typename U> + struct rebind + { + typedef throw_allocator<U> other; + }; + + throw_allocator() throw() { } + + throw_allocator(const throw_allocator&) throw() { } + + template<typename U> + throw_allocator(const throw_allocator<U>&) throw() { } + + ~throw_allocator() throw() { } + + size_type + max_size() const throw() + { return std::allocator<value_type>().max_size(); } + + pointer + allocate(size_type num, std::allocator<void>::const_pointer hint = 0) + { + throw_conditionally(); + value_type* const a = std::allocator<value_type>().allocate(num, hint); + insert(a, sizeof(value_type) * num); + return a; + } + + void + construct(pointer p, const T& val) + { return std::allocator<value_type>().construct(p, val); } + + void + destroy(pointer p) + { std::allocator<value_type>().destroy(p); } + + void + deallocate(pointer p, size_type num) + { + erase(p, sizeof(value_type) * num); + std::allocator<value_type>().deallocate(p, num); + } + + void + check_allocated(pointer p, size_type num) + { throw_allocator_base::check_allocated(p, sizeof(value_type) * num); } + + void + check_allocated(size_type label) + { throw_allocator_base::check_allocated(label); } + }; + + template<typename T> + inline bool + operator==(const throw_allocator<T>&, const throw_allocator<T>&) + { return true; } + + template<typename T> + inline bool + operator!=(const throw_allocator<T>&, const throw_allocator<T>&) + { return false; } + + std::ostream& + operator<<(std::ostream& os, const throw_allocator_base& alloc) + { + std::string error; + throw_allocator_base::print_to_string(error); + os << error; + return os; + } + + // XXX Should be in .cc. + twister_rand_gen:: + twister_rand_gen(unsigned int seed) : _M_generator(seed) { } + + void + twister_rand_gen:: + init(unsigned int seed) + { _M_generator.seed(seed); } + + double + twister_rand_gen:: + get_prob() + { + const double eng_min = _M_generator.min(); + const double eng_range = + static_cast<const double>(_M_generator.max() - eng_min); + + const double eng_res = + static_cast<const double>(_M_generator() - eng_min); + + const double ret = eng_res / eng_range; + _GLIBCXX_DEBUG_ASSERT(ret >= 0 && ret <= 1); + return ret; + } + + twister_rand_gen throw_allocator_base::_S_g; + + throw_allocator_base::map_type + throw_allocator_base::_S_map; + + double throw_allocator_base::_S_throw_prob; + + size_t throw_allocator_base::_S_label = 0; + + throw_allocator_base::entry_type + throw_allocator_base::make_entry(void* p, size_t size) + { return std::make_pair(p, alloc_data_type(_S_label, size)); } + + void + throw_allocator_base::init(unsigned long seed) + { _S_g.init(seed); } + + void + throw_allocator_base::set_throw_prob(double throw_prob) + { _S_throw_prob = throw_prob; } + + double + throw_allocator_base::get_throw_prob() + { return _S_throw_prob; } + + void + throw_allocator_base::set_label(size_t l) + { _S_label = l; } + + void + throw_allocator_base::insert(void* p, size_t size) + { + const_iterator found_it = _S_map.find(p); + if (found_it != _S_map.end()) + { + std::string error("throw_allocator_base::insert"); + error += "double insert!"; + error += '\n'; + print_to_string(error, make_entry(p, size)); + print_to_string(error, *found_it); + std::__throw_logic_error(error.c_str()); + } + _S_map.insert(make_entry(p, size)); + } + + bool + throw_allocator_base::empty() + { return _S_map.empty(); } + + void + throw_allocator_base::erase(void* p, size_t size) + { + check_allocated(p, size); + _S_map.erase(p); + } + + void + throw_allocator_base::check_allocated(void* p, size_t size) + { + const_iterator found_it = _S_map.find(p); + if (found_it == _S_map.end()) + { + std::string error("throw_allocator_base::check_allocated by value "); + error += "null erase!"; + error += '\n'; + print_to_string(error, make_entry(p, size)); + std::__throw_logic_error(error.c_str()); + } + + if (found_it->second.second != size) + { + std::string error("throw_allocator_base::check_allocated by value "); + error += "wrong-size erase!"; + error += '\n'; + print_to_string(error, make_entry(p, size)); + print_to_string(error, *found_it); + std::__throw_logic_error(error.c_str()); + } + } + + void + throw_allocator_base::check_allocated(size_t label) + { + std::string found; + const_iterator it = _S_map.begin(); + while (it != _S_map.end()) + { + if (it->second.first == label) + print_to_string(found, *it); + ++it; + } + + if (!found.empty()) + { + std::string error("throw_allocator_base::check_allocated by label "); + error += '\n'; + error += found; + std::__throw_logic_error(error.c_str()); + } + } + + void + throw_allocator_base::throw_conditionally() + { + if (_S_g.get_prob() < _S_throw_prob) + __throw_forced_exception_error(); + } + + void + throw_allocator_base::print_to_string(std::string& s) + { + const_iterator begin = throw_allocator_base::_S_map.begin(); + const_iterator end = throw_allocator_base::_S_map.end(); + for (; begin != end; ++begin) + print_to_string(s, *begin); + } + + void + throw_allocator_base::print_to_string(std::string& s, const_reference ref) + { + char buf[40]; + const char tab('\t'); + s += "address: "; + sprintf(buf, "%p", ref.first); + s += buf; + s += tab; + s += "label: "; + sprintf(buf, "%u", ref.second.first); + s += buf; + s += tab; + s += "size: "; + sprintf(buf, "%u", ref.second.second); + s += buf; + s += '\n'; + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/type_traits.h b/libstdc++/include/ext/type_traits.h new file mode 100644 index 0000000..31a7e9b --- /dev/null +++ b/libstdc++/include/ext/type_traits.h @@ -0,0 +1,153 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 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. + +/** @file ext/type_traits.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _EXT_TYPE_TRAITS +#define _EXT_TYPE_TRAITS 1 + +#pragma GCC system_header + +#include <cstddef> +#include <utility> +#include <bits/cpp_type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // Define a nested type if some predicate holds. + template<bool, typename> + struct __enable_if + { }; + + template<typename _Tp> + struct __enable_if<true, _Tp> + { typedef _Tp __type; }; + + + // Conditional expression for types. If true, first, if false, second. + template<bool _Cond, typename _Iftrue, typename _Iffalse> + struct __conditional_type + { typedef _Iftrue __type; }; + + template<typename _Iftrue, typename _Iffalse> + struct __conditional_type<false, _Iftrue, _Iffalse> + { typedef _Iffalse __type; }; + + + // Given an integral builtin type, return the corresponding unsigned type. + template<typename _Tp> + struct __add_unsigned + { + private: + typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; + + public: + typedef typename __if_type::__type __type; + }; + + template<> + struct __add_unsigned<char> + { typedef unsigned char __type; }; + + template<> + struct __add_unsigned<signed char> + { typedef unsigned char __type; }; + + template<> + struct __add_unsigned<short> + { typedef unsigned short __type; }; + + template<> + struct __add_unsigned<int> + { typedef unsigned int __type; }; + + template<> + struct __add_unsigned<long> + { typedef unsigned long __type; }; + + template<> + struct __add_unsigned<long long> + { typedef unsigned long long __type; }; + + // Declare but don't define. + template<> + struct __add_unsigned<bool>; + + template<> + struct __add_unsigned<wchar_t>; + + + // Given an integral builtin type, return the corresponding signed type. + template<typename _Tp> + struct __remove_unsigned + { + private: + typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; + + public: + typedef typename __if_type::__type __type; + }; + + template<> + struct __remove_unsigned<char> + { typedef signed char __type; }; + + template<> + struct __remove_unsigned<unsigned char> + { typedef signed char __type; }; + + template<> + struct __remove_unsigned<unsigned short> + { typedef short __type; }; + + template<> + struct __remove_unsigned<unsigned int> + { typedef int __type; }; + + template<> + struct __remove_unsigned<unsigned long> + { typedef long __type; }; + + template<> + struct __remove_unsigned<unsigned long long> + { typedef long long __type; }; + + // Declare but don't define. + template<> + struct __remove_unsigned<bool>; + + template<> + struct __remove_unsigned<wchar_t>; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++/include/ext/typelist.h b/libstdc++/include/ext/typelist.h new file mode 100644 index 0000000..1c99783 --- /dev/null +++ b/libstdc++/include/ext/typelist.h @@ -0,0 +1,473 @@ +// -*- C++ -*- + +// Copyright (C) 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. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice and +// this permission notice appear in supporting documentation. None of +// the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. + +/** + * @file typelist.h + * Contains typelist_chain definitions. + * Typelists are an idea by Andrei Alexandrescu. + */ + +#ifndef _TYPELIST_H +#define _TYPELIST_H 1 + +#include <ext/type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +namespace typelist +{ + struct null_type { }; + + template<typename Root> + struct node + { + typedef Root root; + }; + + // Forward declarations of functors. + template<typename Hd, typename Typelist> + struct chain + { + typedef Hd head; + typedef Typelist tail; + }; + + template<typename Fn, class Typelist> + void + apply(Fn&, Typelist); + + template<typename Typelist0, typename Typelist1> + struct append; + + template<typename Typelist_Typelist> + struct append_typelist; + + template<typename Typelist, typename T> + struct contains; + + template<typename Typelist, template<typename T> class Pred> + struct filter; + + template<typename Typelist, int i> + struct at_index; + + template<typename Typelist, template<typename T> class Transform> + struct transform; + + template<typename Typelist_Typelist> + struct flatten; + + template<typename Typelist> + struct from_first; + + template<typename T1> + struct create1; + + template<typename T1, typename T2> + struct create2; + + template<typename T1, typename T2, typename T3> + struct create3; + + template<typename T1, typename T2, typename T3, typename T4> + struct create4; + + template<typename T1, typename T2, typename T3, typename T4, typename T5> + struct create5; + + template<typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6> + struct create6; +} // namespace typelist + +_GLIBCXX_END_NAMESPACE + + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +namespace typelist +{ +namespace detail +{ + template<typename Fn, typename Typelist_Chain> + struct apply_; + + template<typename Fn, typename Hd, typename Tl> + struct apply_<Fn, chain<Hd, Tl> > + { + void + operator() (Fn& f) + { + f.operator()(Hd()); + apply_<Fn, Tl> next; + next(f); + } + }; + + template<typename Fn> + struct apply_<Fn, null_type> + { + void + operator()(Fn&) { } + }; + + template<typename Typelist_Chain0, typename Typelist_Chain1> + struct append_; + + template<typename Hd, typename Tl, typename Typelist_Chain> + struct append_<chain<Hd, Tl>, Typelist_Chain> + { + private: + typedef append_<Tl, Typelist_Chain> append_type; + + public: + typedef chain<Hd, typename append_type::type> type; + }; + + template<typename Typelist_Chain> + struct append_<null_type, Typelist_Chain> + { + typedef Typelist_Chain type; + }; + + template<typename Typelist_Chain> + struct append_<Typelist_Chain, null_type> + { + typedef Typelist_Chain type; + }; + + template<> + struct append_<null_type, null_type> + { + typedef null_type type; + }; + + template<typename Typelist_Typelist_Chain> + struct append_typelist_; + + template<typename Hd> + struct append_typelist_<chain<Hd, null_type> > + { + typedef chain<Hd, null_type> type; + }; + + template<typename Hd, typename Tl> + struct append_typelist_<chain< Hd, Tl> > + { + private: + typedef typename append_typelist_<Tl>::type rest_type; + + public: + typedef typename append<Hd, node<rest_type> >::type::root type; + }; + + template<typename Typelist_Chain, typename T> + struct contains_; + + template<typename T> + struct contains_<null_type, T> + { + enum + { + value = false + }; + }; + + template<typename Hd, typename Tl, typename T> + struct contains_<chain<Hd, Tl>, T> + { + enum + { + value = contains_<Tl, T>::value + }; + }; + + template<typename Tl, typename T> + struct contains_<chain<T, Tl>, T> + { + enum + { + value = true + }; + }; + + template<typename Typelist_Chain, template<typename T> class Pred> + struct chain_filter_; + + template<template<typename T> class Pred> + struct chain_filter_<null_type, Pred> + { + typedef null_type type; + }; + + template<typename Hd, typename Tl, template<typename T> class Pred> + struct chain_filter_<chain<Hd, Tl>, Pred> + { + private: + enum + { + include_hd = Pred<Hd>::value + }; + + typedef typename chain_filter_<Tl, Pred>::type rest_type; + typedef chain<Hd, rest_type> chain_type; + + public: + typedef typename __conditional_type<include_hd, chain_type, rest_type>::__type type; + }; + + template<typename Typelist_Chain, int i> + struct chain_at_index_; + + template<typename Hd, typename Tl> + struct chain_at_index_<chain<Hd, Tl>, 0> + { + typedef Hd type; + }; + + template<typename Hd, typename Tl, int i> + struct chain_at_index_<chain<Hd, Tl>, i> + { + typedef typename chain_at_index_<Tl, i - 1>::type type; + }; + + template<class Typelist_Chain, template<typename T> class Transform> + struct chain_transform_; + + template<template<typename T> class Transform> + struct chain_transform_<null_type, Transform> + { + typedef null_type type; + }; + + template<class Hd, class Tl, template<typename T> class Transform> + struct chain_transform_<chain<Hd, Tl>, Transform> + { + private: + typedef typename chain_transform_<Tl, Transform>::type rest_type; + typedef typename Transform<Hd>::type transform_type; + + public: + typedef chain<transform_type, rest_type> type; + }; + + template<typename Typelist_Typelist_Chain> + struct chain_flatten_; + + template<typename Hd_Tl> + struct chain_flatten_<chain<Hd_Tl, null_type> > + { + typedef typename Hd_Tl::root type; + }; + + template<typename Hd_Typelist, class Tl_Typelist> + struct chain_flatten_<chain<Hd_Typelist, Tl_Typelist> > + { + private: + typedef typename chain_flatten_<Tl_Typelist>::type rest_type; + typedef append<Hd_Typelist, node<rest_type> > append_type; + public: + typedef typename append_type::type::root type; + }; +} // namespace detail +} // namespace typelist + +_GLIBCXX_END_NAMESPACE + +#define _GLIBCXX_TYPELIST_CHAIN1(X0) __gnu_cxx::typelist::chain<X0, __gnu_cxx::typelist::null_type> +#define _GLIBCXX_TYPELIST_CHAIN2(X0, X1) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN1(X1) > +#define _GLIBCXX_TYPELIST_CHAIN3(X0, X1, X2) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN2(X1, X2) > +#define _GLIBCXX_TYPELIST_CHAIN4(X0, X1, X2, X3) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN3(X1, X2, X3) > +#define _GLIBCXX_TYPELIST_CHAIN5(X0, X1, X2, X3, X4) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN4(X1, X2, X3, X4) > +#define _GLIBCXX_TYPELIST_CHAIN6(X0, X1, X2, X3, X4, X5) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN5(X1, X2, X3, X4, X5) > +#define _GLIBCXX_TYPELIST_CHAIN7(X0, X1, X2, X3, X4, X5, X6) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN6(X1, X2, X3, X4, X5, X6) > +#define _GLIBCXX_TYPELIST_CHAIN8(X0, X1, X2, X3, X4, X5, X6, X7) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN7(X1, X2, X3, X4, X5, X6, X7) > +#define _GLIBCXX_TYPELIST_CHAIN9(X0, X1, X2, X3, X4, X5, X6, X7, X8) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN8(X1, X2, X3, X4, X5, X6, X7, X8) > +#define _GLIBCXX_TYPELIST_CHAIN10(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN9(X1, X2, X3, X4, X5, X6, X7, X8, X9) > +#define _GLIBCXX_TYPELIST_CHAIN11(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN10(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) > +#define _GLIBCXX_TYPELIST_CHAIN12(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN11(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) > +#define _GLIBCXX_TYPELIST_CHAIN13(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN12(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) > +#define _GLIBCXX_TYPELIST_CHAIN14(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN13(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) > +#define _GLIBCXX_TYPELIST_CHAIN15(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN14(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) > + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +namespace typelist +{ + template<typename Fn, class Typelist> + void + apply(Fn& fn, Typelist) + { + detail::apply_<Fn, typename Typelist::root> a; + a(fn); + } + + template<typename Typelist0, typename Typelist1> + struct append + { + private: + typedef typename Typelist0::root root0_type; + typedef typename Typelist1::root root1_type; + typedef detail::append_<root0_type, root1_type> append_type; + + public: + typedef node<typename append_type::type> type; + }; + + template<typename Typelist_Typelist> + struct append_typelist + { + private: + typedef typename Typelist_Typelist::root root_type; + typedef detail::append_typelist_<root_type> append_type; + + public: + typedef node<typename append_type::type> type; + }; + + template<typename Typelist, typename T> + struct contains + { + private: + typedef typename Typelist::root root_type; + + public: + enum + { + value = detail::contains_<root_type, T>::value + }; + }; + + template<typename Typelist, template<typename T> class Pred> + struct filter + { + private: + typedef typename Typelist::root root_type; + typedef detail::chain_filter_<root_type, Pred> filter_type; + + public: + typedef node<typename filter_type::type> type; + }; + + template<typename Typelist, int i> + struct at_index + { + private: + typedef typename Typelist::root root_type; + typedef detail::chain_at_index_<root_type, i> index_type; + + public: + typedef typename index_type::type type; + }; + + template<typename Typelist, template<typename T> class Transform> + struct transform + { + private: + typedef typename Typelist::root root_type; + typedef detail::chain_transform_<root_type, Transform> transform_type; + + public: + typedef node<typename transform_type::type> type; + }; + + template<typename Typelist_Typelist> + struct flatten + { + private: + typedef typename Typelist_Typelist::root root_type; + typedef typename detail::chain_flatten_<root_type>::type flatten_type; + + public: + typedef node<flatten_type> type; + }; + + template<typename Typelist> + struct from_first + { + private: + typedef typename at_index<Typelist, 0>::type first_type; + + public: + typedef node<chain<first_type, null_type> > type; + }; + + template<typename T1> + struct create1 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN1(T1)> type; + }; + + template<typename T1, typename T2> + struct create2 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN2(T1,T2)> type; + }; + + template<typename T1, typename T2, typename T3> + struct create3 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN3(T1,T2,T3)> type; + }; + + template<typename T1, typename T2, typename T3, typename T4> + struct create4 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN4(T1,T2,T3,T4)> type; + }; + + template<typename T1, typename T2, typename T3, + typename T4, typename T5> + struct create5 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN5(T1,T2,T3,T4,T5)> type; + }; + + template<typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6> + struct create6 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN6(T1,T2,T3,T4,T5,T6)> type; + }; +} // namespace typelist +_GLIBCXX_END_NAMESPACE + + +#endif + diff --git a/libstdc++/include/ext/vstring.h b/libstdc++/include/ext/vstring.h new file mode 100644 index 0000000..79265b9 --- /dev/null +++ b/libstdc++/include/ext/vstring.h @@ -0,0 +1,2198 @@ +// Versatile string -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 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. + +/** @file ext/vstring.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _VSTRING_H +#define _VSTRING_H 1 + +#pragma GCC system_header + +#include <ext/vstring_util.h> +#include <ext/rc_string_base.h> +#include <ext/sso_string_base.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /** + * @class __versa_string vstring.h + * @brief Managing sequences of characters and character-like objects. + */ + + // Template class __versa_string + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + class __versa_string + : private _Base<_CharT, _Traits, _Alloc> + { + typedef _Base<_CharT, _Traits, _Alloc> __vstring_base; + typedef typename __vstring_base::_CharT_alloc_type _CharT_alloc_type; + + // Types: + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + typedef typename _CharT_alloc_type::size_type size_type; + typedef typename _CharT_alloc_type::difference_type difference_type; + typedef typename _CharT_alloc_type::reference reference; + typedef typename _CharT_alloc_type::const_reference const_reference; + typedef typename _CharT_alloc_type::pointer pointer; + typedef typename _CharT_alloc_type::const_pointer const_pointer; + typedef __gnu_cxx::__normal_iterator<pointer, __versa_string> iterator; + typedef __gnu_cxx::__normal_iterator<const_pointer, __versa_string> + const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + + // Data Member (public): + /// Value returned by various member functions when they fail. + static const size_type npos = static_cast<size_type>(-1); + + private: + size_type + _M_check(size_type __pos, const char* __s) const + { + if (__pos > this->size()) + std::__throw_out_of_range(__N(__s)); + return __pos; + } + + void + _M_check_length(size_type __n1, size_type __n2, const char* __s) const + { + if (this->max_size() - (this->size() - __n1) < __n2) + std::__throw_length_error(__N(__s)); + } + + // NB: _M_limit doesn't check for a bad __pos value. + size_type + _M_limit(size_type __pos, size_type __off) const + { + const bool __testoff = __off < this->size() - __pos; + return __testoff ? __off : this->size() - __pos; + } + + // True if _Rep and source do not overlap. + bool + _M_disjunct(const _CharT* __s) const + { + return (std::less<const _CharT*>()(__s, this->_M_data()) + || std::less<const _CharT*>()(this->_M_data() + + this->size(), __s)); + } + + // For the internal use we have functions similar to `begin'/`end' + // but they do not call _M_leak. + iterator + _M_ibegin() const + { return iterator(this->_M_data()); } + + iterator + _M_iend() const + { return iterator(this->_M_data() + this->_M_length()); } + + public: + // Construct/copy/destroy: + // NB: We overload ctors in some cases instead of using default + // arguments, per 17.4.4.4 para. 2 item 2. + + /** + * @brief Default constructor creates an empty string. + */ + __versa_string() + : __vstring_base() { } + + /** + * @brief Construct an empty string using allocator @a a. + */ + explicit + __versa_string(const _Alloc& __a) + : __vstring_base(__a) { } + + // NB: per LWG issue 42, semantics different from IS: + /** + * @brief Construct string with copy of value of @a str. + * @param str Source string. + */ + __versa_string(const __versa_string& __str) + : __vstring_base(__str) { } + + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy (default remainder). + */ + __versa_string(const __versa_string& __str, size_type __pos, + size_type __n = npos) + : __vstring_base(__str._M_data() + + __str._M_check(__pos, + "__versa_string::__versa_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, _Alloc()) { } + + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy. + * @param a Allocator to use. + */ + __versa_string(const __versa_string& __str, size_type __pos, + size_type __n, const _Alloc& __a) + : __vstring_base(__str._M_data() + + __str._M_check(__pos, + "__versa_string::__versa_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, __a) { } + + /** + * @brief Construct string initialized by a character array. + * @param s Source character array. + * @param n Number of characters to copy. + * @param a Allocator to use (default is default allocator). + * + * NB: @a s must have at least @a n characters, '\0' has no special + * meaning. + */ + __versa_string(const _CharT* __s, size_type __n, + const _Alloc& __a = _Alloc()) + : __vstring_base(__s, __s + __n, __a) { } + + /** + * @brief Construct string as copy of a C string. + * @param s Source C string. + * @param a Allocator to use (default is default allocator). + */ + __versa_string(const _CharT* __s, const _Alloc& __a = _Alloc()) + : __vstring_base(__s, __s ? __s + traits_type::length(__s) : + __s + npos, __a) { } + + /** + * @brief Construct string as multiple characters. + * @param n Number of characters. + * @param c Character to use. + * @param a Allocator to use (default is default allocator). + */ + __versa_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()) + : __vstring_base(__n, __c, __a) { } + + /** + * @brief Construct string as copy of a range. + * @param beg Start of range. + * @param end End of range. + * @param a Allocator to use (default is default allocator). + */ + template<class _InputIterator> + __versa_string(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a = _Alloc()) + : __vstring_base(__beg, __end, __a) { } + + /** + * @brief Destroy the string instance. + */ + ~__versa_string() { } + + /** + * @brief Assign the value of @a str to this string. + * @param str Source string. + */ + __versa_string& + operator=(const __versa_string& __str) + { return this->assign(__str); } + + /** + * @brief Copy contents of @a s into this string. + * @param s Source null-terminated string. + */ + __versa_string& + operator=(const _CharT* __s) + { return this->assign(__s); } + + /** + * @brief Set value to string of length 1. + * @param c Source character. + * + * Assigning to a character makes this string length 1 and + * (*this)[0] == @a c. + */ + __versa_string& + operator=(_CharT __c) + { + this->assign(1, __c); + return *this; + } + + // Iterators: + /** + * Returns a read/write iterator that points to the first character in + * the %string. Unshares the string. + */ + iterator + begin() + { + this->_M_leak(); + return iterator(this->_M_data()); + } + + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ + const_iterator + begin() const + { return const_iterator(this->_M_data()); } + + /** + * Returns a read/write iterator that points one past the last + * character in the %string. Unshares the string. + */ + iterator + end() + { + this->_M_leak(); + return iterator(this->_M_data() + this->size()); + } + + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ + const_iterator + end() const + { return const_iterator(this->_M_data() + this->size()); } + + /** + * Returns a read/write reverse iterator that points to the last + * character in the %string. Iteration is done in reverse element + * order. Unshares the string. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->end()); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first character in the %string. Iteration is done in reverse + * element order. Unshares the string. + */ + reverse_iterator + rend() + { return reverse_iterator(this->begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->begin()); } + + public: + // Capacity: + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + size() const + { return this->_M_length(); } + + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + length() const + { return this->_M_length(); } + + /// Returns the size() of the largest possible %string. + size_type + max_size() const + { return this->_M_max_size(); } + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * @param c Character to fill any new elements. + * + * This function will %resize the %string to the specified + * number of characters. If the number is smaller than the + * %string's current size the %string is truncated, otherwise + * the %string is extended and new elements are set to @a c. + */ + void + resize(size_type __n, _CharT __c); + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * + * This function will resize the %string to the specified length. If + * the new size is smaller than the %string's current size the %string + * is truncated, otherwise the %string is extended and new characters + * are default-constructed. For basic types such as char, this means + * setting them to 0. + */ + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + + /** + * Returns the total number of characters that the %string can hold + * before needing to allocate more memory. + */ + size_type + capacity() const + { return this->_M_capacity(); } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * characters. + * @param res_arg Number of characters required. + * @throw std::length_error If @a res_arg exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %string to hold the specified number of characters. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the string length that will be + * required, the user can reserve the memory in %advance, and thus + * prevent a possible reallocation of memory and copying of %string + * data. + */ + void + reserve(size_type __res_arg = 0) + { this->_M_reserve(__res_arg); } + + /** + * Erases the string, making it empty. + */ + void + clear() + { this->_M_clear(); } + + /** + * Returns true if the %string is empty. Equivalent to *this == "". + */ + bool + empty() const + { return this->size() == 0; } + + // Element access: + /** + * @brief Subscript access to the data contained in the %string. + * @param pos The index of the character to access. + * @return Read-only (constant) reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[] (size_type __pos) const + { + _GLIBCXX_DEBUG_ASSERT(__pos <= this->size()); + return this->_M_data()[__pos]; + } + + /** + * @brief Subscript access to the data contained in the %string. + * @param pos The index of the character to access. + * @return Read/write reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) Unshares the string. + */ + reference + operator[](size_type __pos) + { + // allow pos == size() as v3 extension: + _GLIBCXX_DEBUG_ASSERT(__pos <= this->size()); + // but be strict in pedantic mode: + _GLIBCXX_DEBUG_PEDASSERT(__pos < this->size()); + this->_M_leak(); + return this->_M_data()[__pos]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read-only (const) reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + if (__n >= this->size()) + std::__throw_out_of_range(__N("__versa_string::at")); + return this->_M_data()[__n]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read/write reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. Success results in + * unsharing the string. + */ + reference + at(size_type __n) + { + if (__n >= this->size()) + std::__throw_out_of_range(__N("__versa_string::at")); + this->_M_leak(); + return this->_M_data()[__n]; + } + + // Modifiers: + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + __versa_string& + operator+=(const __versa_string& __str) + { return this->append(__str); } + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + __versa_string& + operator+=(const _CharT* __s) + { return this->append(__s); } + + /** + * @brief Append a character. + * @param c The character to append. + * @return Reference to this string. + */ + __versa_string& + operator+=(_CharT __c) + { + this->push_back(__c); + return *this; + } + + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + __versa_string& + append(const __versa_string& __str) + { return _M_append(__str._M_data(), __str.size()); } + + /** + * @brief Append a substring. + * @param str The string to append. + * @param pos Index of the first character of str to append. + * @param n The number of characters to append. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function appends @a n characters from @a str starting at @a pos + * to this string. If @a n is is larger than the number of available + * characters in @a str, the remainder of @a str is appended. + */ + __versa_string& + append(const __versa_string& __str, size_type __pos, size_type __n) + { return _M_append(__str._M_data() + + __str._M_check(__pos, "__versa_string::append"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Append a C substring. + * @param s The C string to append. + * @param n The number of characters to append. + * @return Reference to this string. + */ + __versa_string& + append(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check_length(size_type(0), __n, "__versa_string::append"); + return _M_append(__s, __n); + } + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + __versa_string& + append(const _CharT* __s) + { + __glibcxx_requires_string(__s); + const size_type __n = traits_type::length(__s); + _M_check_length(size_type(0), __n, "__versa_string::append"); + return _M_append(__s, __n); + } + + /** + * @brief Append multiple characters. + * @param n The number of characters to append. + * @param c The character to use. + * @return Reference to this string. + * + * Appends n copies of c to this string. + */ + __versa_string& + append(size_type __n, _CharT __c) + { return _M_replace_aux(this->size(), size_type(0), __n, __c); } + + /** + * @brief Append a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Appends characters in the range [first,last) to this string. + */ + template<class _InputIterator> + __versa_string& + append(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_iend(), _M_iend(), __first, __last); } + + /** + * @brief Append a single character. + * @param c Character to append. + */ + void + push_back(_CharT __c) + { + const size_type __size = this->size(); + if (__size + 1 > this->capacity() || this->_M_is_shared()) + this->_M_mutate(__size, size_type(0), 0, size_type(1)); + traits_type::assign(this->_M_data()[__size], __c); + this->_M_set_length(__size + 1); + } + + /** + * @brief Set value to contents of another string. + * @param str Source string to use. + * @return Reference to this string. + */ + __versa_string& + assign(const __versa_string& __str) + { + this->_M_assign(__str); + return *this; + } + + /** + * @brief Set value to a substring of a string. + * @param str The string to use. + * @param pos Index of the first character of str. + * @param n Number of characters to use. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function sets this string to the substring of @a str consisting + * of @a n characters at @a pos. If @a n is is larger than the number + * of available characters in @a str, the remainder of @a str is used. + */ + __versa_string& + assign(const __versa_string& __str, size_type __pos, size_type __n) + { return _M_replace(size_type(0), this->size(), __str._M_data() + + __str._M_check(__pos, "__versa_string::assign"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Set value to a C substring. + * @param s The C string to use. + * @param n Number of characters to use. + * @return Reference to this string. + * + * This function sets the value of this string to the first @a n + * characters of @a s. If @a n is is larger than the number of + * available characters in @a s, the remainder of @a s is used. + */ + __versa_string& + assign(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + return _M_replace(size_type(0), this->size(), __s, __n); + } + + /** + * @brief Set value to contents of a C string. + * @param s The C string to use. + * @return Reference to this string. + * + * This function sets the value of this string to the value of @a s. + * The data is copied, so there is no dependence on @a s once the + * function returns. + */ + __versa_string& + assign(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return _M_replace(size_type(0), this->size(), __s, + traits_type::length(__s)); + } + + /** + * @brief Set value to multiple characters. + * @param n Length of the resulting string. + * @param c The character to use. + * @return Reference to this string. + * + * This function sets the value of this string to @a n copies of + * character @a c. + */ + __versa_string& + assign(size_type __n, _CharT __c) + { return _M_replace_aux(size_type(0), this->size(), __n, __c); } + + /** + * @brief Set value to a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Sets value of string to characters in the range [first,last). + */ + template<class _InputIterator> + __versa_string& + assign(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } + + /** + * @brief Insert multiple characters. + * @param p Iterator referencing location in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a n copies of character @a c starting at the position + * referenced by iterator @a p. If adding characters causes the length + * to exceed max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + void + insert(iterator __p, size_type __n, _CharT __c) + { this->replace(__p, __p, __n, __c); } + + /** + * @brief Insert a range of characters. + * @param p Iterator referencing location in string to insert at. + * @param beg Start of range. + * @param end End of range. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [beg,end). If adding characters causes + * the length to exceed max_size(), length_error is thrown. The value + * of the string doesn't change if an error is thrown. + */ + template<class _InputIterator> + void + insert(iterator __p, _InputIterator __beg, _InputIterator __end) + { this->replace(__p, __p, __beg, __end); } + + /** + * @brief Insert value of a string. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts value of @a str starting at @a pos1. If adding characters + * causes the length to exceed max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ + __versa_string& + insert(size_type __pos1, const __versa_string& __str) + { return this->replace(__pos1, size_type(0), + __str._M_data(), __str.size()); } + + /** + * @brief Insert a substring. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @param pos2 Start of characters in str to insert. + * @param n Number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos1 > size() or + * @a pos2 > @a str.size(). + * + * Starting at @a pos1, insert @a n character of @a str beginning with + * @a pos2. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a pos1 is beyond the end of + * this string or @a pos2 is beyond the end of @a str, out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + __versa_string& + insert(size_type __pos1, const __versa_string& __str, + size_type __pos2, size_type __n) + { return this->replace(__pos1, size_type(0), __str._M_data() + + __str._M_check(__pos2, "__versa_string::insert"), + __str._M_limit(__pos2, __n)); } + + /** + * @brief Insert a C substring. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @param n The number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + __versa_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { return this->replace(__pos, size_type(0), __s, __n); } + + /** + * @brief Insert a C string. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + __versa_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, size_type(0), __s, + traits_type::length(__s)); + } + + /** + * @brief Insert multiple characters. + * @param pos Index in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts @a n copies of character @a c starting at index @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos > length(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + __versa_string& + insert(size_type __pos, size_type __n, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "__versa_string::insert"), + size_type(0), __n, __c); } + + /** + * @brief Insert one character. + * @param p Iterator referencing position in string to insert at. + * @param c The character to insert. + * @return Iterator referencing newly inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts character @a c at position referenced by @a p. If adding + * character causes the length to exceed max_size(), length_error is + * thrown. If @a p is beyond end of string, out_of_range is thrown. + * The value of the string doesn't change if an error is thrown. + */ + iterator + insert(iterator __p, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); + const size_type __pos = __p - _M_ibegin(); + _M_replace_aux(__pos, size_type(0), size_type(1), __c); + this->_M_set_leaked(); + return iterator(this->_M_data() + __pos); + } + + /** + * @brief Remove characters. + * @param pos Index of first character to remove (default 0). + * @param n Number of characters to remove (default remainder). + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Removes @a n characters from this string starting at @a pos. The + * length of the string is reduced by @a n. If there are < @a n + * characters to remove, the remainder of the string is truncated. If + * @a p is beyond end of string, out_of_range is thrown. The value of + * the string doesn't change if an error is thrown. + */ + __versa_string& + erase(size_type __pos = 0, size_type __n = npos) + { + this->_M_erase(_M_check(__pos, "__versa_string::erase"), + _M_limit(__pos, __n)); + return *this; + } + + /** + * @brief Remove one character. + * @param position Iterator referencing the character to remove. + * @return iterator referencing same location after removal. + * + * Removes the character at @a position from this string. The value + * of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __position) + { + _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() + && __position < _M_iend()); + const size_type __pos = __position - _M_ibegin(); + this->_M_erase(__pos, size_type(1)); + this->_M_set_leaked(); + return iterator(this->_M_data() + __pos); + } + + /** + * @brief Remove a range of characters. + * @param first Iterator referencing the first character to remove. + * @param last Iterator referencing the end of the range. + * @return Iterator referencing location of first after removal. + * + * Removes the characters in the range [first,last) from this string. + * The value of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __first, iterator __last) + { + _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last + && __last <= _M_iend()); + const size_type __pos = __first - _M_ibegin(); + this->_M_erase(__pos, __last - __first); + this->_M_set_leaked(); + return iterator(this->_M_data() + __pos); + } + + /** + * @brief Replace characters with value from another string. + * @param pos Index of first character to replace. + * @param n Number of characters to be replaced. + * @param str String to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos+n) from this string. + * In place, the value of @a str is inserted. If @a pos is beyond end + * of string, out_of_range is thrown. If the length of the result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + __versa_string& + replace(size_type __pos, size_type __n, const __versa_string& __str) + { return this->replace(__pos, __n, __str._M_data(), __str.size()); } + + /** + * @brief Replace characters with value from another string. + * @param pos1 Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str String to insert. + * @param pos2 Index of first character of str to use. + * @param n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size() or @a pos2 > + * str.size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos1,pos1 + n) from this + * string. In place, the value of @a str is inserted. If @a pos is + * beyond end of string, out_of_range is thrown. If the length of the + * result exceeds max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + __versa_string& + replace(size_type __pos1, size_type __n1, const __versa_string& __str, + size_type __pos2, size_type __n2) + { + return this->replace(__pos1, __n1, __str._M_data() + + __str._M_check(__pos2, + "__versa_string::replace"), + __str._M_limit(__pos2, __n2)); + } + + /** + * @brief Replace characters with value of a C substring. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param s C string to insert. + * @param n2 Number of characters from @a s to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n2 characters of @a s are inserted, or all + * of @a s if @a n2 is too large. If @a pos is beyond end of string, + * out_of_range is thrown. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + __versa_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_requires_string_len(__s, __n2); + return _M_replace(_M_check(__pos, "__versa_string::replace"), + _M_limit(__pos, __n1), __s, __n2); + } + + /** + * @brief Replace characters with value of a C string. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param s C string to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n characters of @a s are inserted. If @a + * pos is beyond end of string, out_of_range is thrown. If the length + * of result exceeds max_size(), length_error is thrown. The value of + * the string doesn't change if an error is thrown. + */ + __versa_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } + + /** + * @brief Replace characters with multiple characters. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param n2 Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, @a n2 copies of @a c are inserted. If @a pos is beyond + * end of string, out_of_range is thrown. If the length of result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + __versa_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "__versa_string::replace"), + _M_limit(__pos, __n1), __n2, __c); } + + /** + * @brief Replace range of characters with string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param str String value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the value of + * @a str is inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + __versa_string& + replace(iterator __i1, iterator __i2, const __versa_string& __str) + { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } + + /** + * @brief Replace range of characters with C substring. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @param n Number of characters from s to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the first @a + * n characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + __versa_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); + } + + /** + * @brief Replace range of characters with C string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the + * characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + __versa_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__i1, __i2, __s, traits_type::length(__s)); + } + + /** + * @brief Replace range of characters with multiple characters + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param n Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, @a n copies + * of @a c are inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + __versa_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); + } + + /** + * @brief Replace range of characters with range. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param k1 Iterator referencing start of range to insert. + * @param k2 Iterator referencing end of range to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, characters + * in the range [k1,k2) are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + template<class _InputIterator> + __versa_string& + replace(iterator __i1, iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); + } + + // Specializations for the common case of pointer and iterator: + // useful to avoid the overhead of temporary buffering in _M_replace. + __versa_string& + replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + __versa_string& + replace(iterator __i1, iterator __i2, + const _CharT* __k1, const _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + __versa_string& + replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + __versa_string& + replace(iterator __i1, iterator __i2, + const_iterator __k1, const_iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + private: + template<class _Integer> + __versa_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n, + _Integer __val, std::__true_type) + { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } + + template<class _InputIterator> + __versa_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, std::__false_type); + + __versa_string& + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c); + + __versa_string& + _M_replace(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2); + + __versa_string& + _M_append(const _CharT* __s, size_type __n); + + public: + + /** + * @brief Copy substring into C string. + * @param s C string to copy value into. + * @param n Number of characters to copy. + * @param pos Index of first character to copy. + * @return Number of characters actually copied + * @throw std::out_of_range If pos > size(). + * + * Copies up to @a n characters starting at @a pos into the C string @a + * s. If @a pos is greater than size(), out_of_range is thrown. + */ + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + + /** + * @brief Swap contents with another string. + * @param s String to swap with. + * + * Exchanges the contents of this string with that of @a s in constant + * time. + */ + void + swap(__versa_string& __s) + { this->_M_swap(__s); } + + // String operations: + /** + * @brief Return const pointer to null-terminated contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + c_str() const + { return this->_M_data(); } + + /** + * @brief Return const pointer to contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + data() const + { return this->_M_data(); } + + /** + * @brief Return copy of allocator used to construct this string. + */ + allocator_type + get_allocator() const + { return allocator_type(this->_M_get_allocator()); } + + /** + * @brief Find position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search from. + * @param n Number of characters from @a s to search for. + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the first @a n characters + * in @a s within this string. If found, returns the index where it + * begins. If not found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a string. + * @param str String to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const __versa_string& __str, size_type __pos = 0) const + { return this->find(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a C string. + * @param s C string to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a string. + * @param str String to locate. + * @param pos Index of character to search back from (default end). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const __versa_string& __str, size_type __pos = npos) const + { return this->rfind(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search back from. + * @param n Number of characters from s to search for. + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the first @a n + * characters in @a s within this string. If found, returns the index + * where it begins. If not found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a C string. + * @param s C string to locate. + * @param pos Index of character to start search at (default end). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->rfind(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + rfind(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Find position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const __versa_string& __str, size_type __pos = 0) const + { return this->find_first_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character of C substring. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to search for. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a character of C string. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for the character @a c within + * this string. If found, returns the index where it was found. If + * not found, returns npos. + * + * Note: equivalent to find(c, pos). + */ + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return this->find(__c, __pos); } + + /** + * @brief Find last position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const __versa_string& __str, size_type __pos = npos) const + { return this->find_last_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character of C substring. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @param n Number of characters from s to search for. + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a character of C string. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default 0). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + * + * Note: equivalent to rfind(c, pos). + */ + size_type + find_last_of(_CharT __c, size_type __pos = npos) const + { return this->rfind(__c, __pos); } + + /** + * @brief Find position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a str within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const __versa_string& __str, size_type __pos = 0) const + { return this->find_first_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in the first @a n characters of @a s within this string. If found, + * returns the index where it was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a s within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character other than @a c + * within this string. If found, returns the index where it was found. + * If not found, returns npos. + */ + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a str within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const __versa_string& __str, + size_type __pos = npos) const + { return this->find_last_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in the first @a n characters of @a s within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character other than + * @a c within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Get a substring. + * @param pos Index of first character (default 0). + * @param n Number of characters in substring (default remainder). + * @return The new string. + * @throw std::out_of_range If pos > size(). + * + * Construct and return a new string using the @a n characters starting + * at @a pos. If the string is too short, use the remainder of the + * characters. If @a pos is beyond the end of the string, out_of_range + * is thrown. + */ + __versa_string + substr(size_type __pos = 0, size_type __n = npos) const + { + return __versa_string(*this, _M_check(__pos, "__versa_string::substr"), + __n); + } + + /** + * @brief Compare to a string. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a str, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a str. Determines the effective length rlen of the strings to + * compare as the smallest of size() and str.size(). The function + * then compares the two strings by calling traits::compare(data(), + * str.data(),rlen). If the result of the comparison is nonzero returns + * it, otherwise the shorter one is ordered first. + */ + int + compare(const __versa_string& __str) const + { + if (this->_M_compare(__str)) + return 0; + + const size_type __size = this->size(); + const size_type __osize = __str.size(); + const size_type __len = std::min(__size, __osize); + + int __r = traits_type::compare(this->_M_data(), __str.data(), __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + /** + * @brief Compare substring to a string. + * @param pos Index of first character of substring. + * @param n Number of characters in substring. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a str, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a str. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and @a str.size(). The function then compares the two + * strings by calling traits::compare(substring.data(),str.data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos, size_type __n, + const __versa_string& __str) const; + + /** + * @brief Compare substring to a substring. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param str String to compare against. + * @param pos2 Index of first character of substring of str. + * @param n2 Number of characters in substring of str. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form the substring of @a str from the @a n2 characters + * starting at @a pos2. Returns an integer < 0 if this substring is + * ordered before the substring of @a str, 0 if their values are + * equivalent, or > 0 if this substring is ordered after the substring + * of @a str. Determines the effective length rlen of the strings + * to compare as the smallest of the lengths of the substrings. The + * function then compares the two strings by calling + * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos1, size_type __n1, const __versa_string& __str, + size_type __pos2, size_type __n2) const; + + /** + * @brief Compare to a C string. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a s, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a s. Determines the effective length rlen of the strings to + * compare as the smallest of size() and the length of a string + * constructed from @a s. The function then compares the two strings + * by calling traits::compare(data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(const _CharT* __s) const; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5 String::compare specification questionable + /** + * @brief Compare substring to a C string. + * @param pos Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a s, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a s. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and the length of a string constructed from @a s. The + * function then compares the two string by calling + * traits::compare(substring.data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s) const; + + /** + * @brief Compare substring against a character array. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s character array to compare against. + * @param n2 Number of characters of s. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form a string from the first @a n2 characters of @a s. + * Returns an integer < 0 if this substring is ordered before the string + * from @a s, 0 if their values are equivalent, or > 0 if this substring + * is ordered after the string from @a s. Determines the effective + * length rlen of the strings to compare as the smallest of the length + * of the substring and @a n2. The function then compares the two + * strings by calling traits::compare(substring.data(),s,rlen). If the + * result of the comparison is nonzero returns it, otherwise the shorter + * one is ordered first. + * + * NB: s must have at least n2 characters, '\0' has no special + * meaning. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const; + }; + + // operator+ + /** + * @brief Concatenate two strings. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs); + + /** + * @brief Concatenate C string and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs); + + /** + * @brief Concatenate character and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(_CharT __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs); + + /** + * @brief Concatenate string and C string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs); + + /** + * @brief Concatenate string and character. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + _CharT __rhs); + + // operator == + /** + * @brief Test equivalence of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) == 0; } + + /** + * @brief Test equivalence of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) == 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator==(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) == 0; } + + /** + * @brief Test equivalence of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) == 0; } + + // operator != + /** + * @brief Test difference of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) != 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator!=(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) != 0; } + + // operator < + /** + * @brief Test if string precedes string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if string precedes C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if C string precedes string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) > 0; } + + // operator > + /** + * @brief Test if string follows string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if string follows C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if C string follows string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) < 0; } + + // operator <= + /** + * @brief Test if string doesn't follow string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if string doesn't follow C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if C string doesn't follow string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<=(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) >= 0; } + + // operator >= + /** + * @brief Test if string doesn't precede string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if string doesn't precede C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if C string doesn't precede string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>=(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) <= 0; } + + /** + * @brief Swap contents of two strings. + * @param lhs First string. + * @param rhs Second string. + * + * Exchanges the contents of @a lhs and @a rhs in constant time. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline void + swap(__versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { __lhs.swap(__rhs); } + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Read stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until whitespace is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + __gnu_cxx::__versa_string<_CharT, _Traits, + _Alloc, _Base>& __str); + + /** + * @brief Write string to a stream. + * @param os Output stream. + * @param str String to write out. + * @return Reference to the output stream. + * + * Output characters of @a str into os following the same rules as for + * writing a C string. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const __gnu_cxx::__versa_string<_CharT, _Traits, + _Alloc, _Base>& __str) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 586. string inserter not a formatted function + return __ostream_insert(__os, __str.data(), __str.size()); + } + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @param delim Character marking end of line. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until @a delim is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. If @a + * delim was encountered, it is extracted but not stored into @a str. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str, + _CharT __delim); + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from is into @a str until '\n' is found, the end of + * the stream is encountered, or str.max_size() is reached. If is.width() + * is non-zero, that is the limit on the number of characters stored into + * @a str. Any previous contents of @a str are erased. If end of line was + * encountered, it is extracted but not stored into @a str. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str) + { return getline(__is, __str, __is.widen('\n')); } + +_GLIBCXX_END_NAMESPACE + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include "vstring.tcc" +#endif + +#endif /* _VSTRING_H */ diff --git a/libstdc++/include/ext/vstring.tcc b/libstdc++/include/ext/vstring.tcc new file mode 100644 index 0000000..3e4cd77 --- /dev/null +++ b/libstdc++/include/ext/vstring.tcc @@ -0,0 +1,690 @@ +// Versatile string -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 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. + +/** @file ext/vstring.tcc + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VSTRING_TCC +#define _VSTRING_TCC 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>::npos; + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + void + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + resize(size_type __n, _CharT __c) + { + const size_type __size = this->size(); + if (__size < __n) + this->append(__n - __size, __c); + else if (__n < __size) + this->_M_erase(__n, __size - __n); + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base>& + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + _M_append(const _CharT* __s, size_type __n) + { + const size_type __len = __n + this->size(); + + if (__len <= this->capacity() && !this->_M_is_shared()) + { + if (__n) + this->_S_copy(this->_M_data() + this->size(), __s, __n); + } + else + this->_M_mutate(this->size(), size_type(0), __s, __n); + + this->_M_set_length(__len); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + template<typename _InputIterator> + __versa_string<_CharT, _Traits, _Alloc, _Base>& + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, std::__false_type) + { + const __versa_string __s(__k1, __k2); + const size_type __n1 = __i2 - __i1; + return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(), + __s.size()); + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base>& + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c) + { + _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux"); + + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __n2 - __n1; + + if (__new_size <= this->capacity() && !this->_M_is_shared()) + { + _CharT* __p = this->_M_data() + __pos1; + + const size_type __how_much = __old_size - __pos1 - __n1; + if (__how_much && __n1 != __n2) + this->_S_move(__p + __n2, __p + __n1, __how_much); + } + else + this->_M_mutate(__pos1, __n1, 0, __n2); + + if (__n2) + this->_S_assign(this->_M_data() + __pos1, __n2, __c); + + this->_M_set_length(__new_size); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base>& + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + _M_replace(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2) + { + _M_check_length(__len1, __len2, "__versa_string::_M_replace"); + + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __len2 - __len1; + + if (__new_size <= this->capacity() && !this->_M_is_shared()) + { + _CharT* __p = this->_M_data() + __pos; + + const size_type __how_much = __old_size - __pos - __len1; + if (_M_disjunct(__s)) + { + if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2) + this->_S_copy(__p, __s, __len2); + } + else + { + // Work in-place. + if (__len2 && __len2 <= __len1) + this->_S_move(__p, __s, __len2); + if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2 > __len1) + { + if (__s + __len2 <= __p + __len1) + this->_S_move(__p, __s, __len2); + else if (__s >= __p + __len1) + this->_S_copy(__p, __s + __len2 - __len1, __len2); + else + { + const size_type __nleft = (__p + __len1) - __s; + this->_S_move(__p, __s, __nleft); + this->_S_copy(__p + __nleft, __p + __len2, + __len2 - __nleft); + } + } + } + } + else + this->_M_mutate(__pos, __len1, __s, __len2); + + this->_M_set_length(__new_size); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { + __versa_string<_CharT, _Traits, _Alloc, _Base> __str; + __str.reserve(__lhs.size() + __rhs.size()); + __str.append(__lhs); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { + __glibcxx_requires_string(__lhs); + typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; + typedef typename __string_type::size_type __size_type; + const __size_type __len = _Traits::length(__lhs); + __string_type __str; + __str.reserve(__len + __rhs.size()); + __str.append(__lhs, __len); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(_CharT __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { + __versa_string<_CharT, _Traits, _Alloc, _Base> __str; + __str.reserve(__rhs.size() + 1); + __str.push_back(__lhs); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { + __glibcxx_requires_string(__rhs); + typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; + typedef typename __string_type::size_type __size_type; + const __size_type __len = _Traits::length(__rhs); + __string_type __str; + __str.reserve(__lhs.size() + __len); + __str.append(__lhs); + __str.append(__rhs, __len); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + _CharT __rhs) + { + __versa_string<_CharT, _Traits, _Alloc, _Base> __str; + __str.reserve(__lhs.size() + 1); + __str.append(__lhs); + __str.push_back(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "__versa_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + this->_S_copy(__s, this->_M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + const _CharT* __data = this->_M_data(); + + if (__n == 0) + return __pos <= __size ? __pos : npos; + + if (__n <= __size) + { + for (; __pos <= __size - __n; ++__pos) + if (traits_type::eq(__data[__pos], __s[0]) + && traits_type::compare(__data + __pos + 1, + __s + 1, __n - 1) == 0) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find(_CharT __c, size_type __pos) const + { + size_type __ret = npos; + const size_type __size = this->size(); + if (__pos < __size) + { + const _CharT* __data = this->_M_data(); + const size_type __n = __size - __pos; + const _CharT* __p = traits_type::find(__data + __pos, __n, __c); + if (__p) + __ret = __p - __data; + } + return __ret; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + if (__n <= __size) + { + __pos = std::min(size_type(__size - __n), __pos); + const _CharT* __data = this->_M_data(); + do + { + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + rfind(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(this->_M_data()[__size], __c)) + return __size; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __n && __pos < this->size(); ++__pos) + { + const _CharT* __p = traits_type::find(__s, __n, + this->_M_data()[__pos]); + if (__p) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (traits_type::find(__s, __n, this->_M_data()[__size])) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __pos < this->size(); ++__pos) + if (!traits_type::find(__s, __n, this->_M_data()[__pos])) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_first_not_of(_CharT __c, size_type __pos) const + { + for (; __pos < this->size(); ++__pos) + if (!traits_type::eq(this->_M_data()[__pos], __c)) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::find(__s, __n, this->_M_data()[__size])) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_last_not_of(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(this->_M_data()[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + compare(size_type __pos, size_type __n, const __versa_string& __str) const + { + _M_check(__pos, "__versa_string::compare"); + __n = _M_limit(__pos, __n); + const size_type __osize = __str.size(); + const size_type __len = std::min(__n, __osize); + int __r = traits_type::compare(this->_M_data() + __pos, + __str.data(), __len); + if (!__r) + __r = __n - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + compare(size_type __pos1, size_type __n1, const __versa_string& __str, + size_type __pos2, size_type __n2) const + { + _M_check(__pos1, "__versa_string::compare"); + __str._M_check(__pos2, "__versa_string::compare"); + __n1 = _M_limit(__pos1, __n1); + __n2 = __str._M_limit(__pos2, __n2); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(this->_M_data() + __pos1, + __str.data() + __pos2, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + compare(const _CharT* __s) const + { + __glibcxx_requires_string(__s); + const size_type __size = this->size(); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__size, __osize); + int __r = traits_type::compare(this->_M_data(), __s, __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string <_CharT, _Traits, _Alloc, _Base>:: + compare(size_type __pos, size_type __n1, const _CharT* __s) const + { + __glibcxx_requires_string(__s); + _M_check(__pos, "__versa_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__n1, __osize); + int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string <_CharT, _Traits, _Alloc, _Base>:: + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const + { + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "__versa_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, + __gnu_cxx::__versa_string<_CharT, _Traits, + _Alloc, _Base>& __str) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> + __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const streamsize __w = __in.width(); + const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) + : __str.max_size(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + __in.width(0); + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + // 211. operator>>(istream&, string&) doesn't set failbit + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str, + _CharT __delim) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> + __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const __int_type __idelim = _Traits::to_int_type(__delim); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !_Traits::eq_int_type(__c, __idelim)) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (_Traits::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + +_GLIBCXX_END_NAMESPACE + +#endif // _VSTRING_TCC diff --git a/libstdc++/include/ext/vstring_fwd.h b/libstdc++/include/ext/vstring_fwd.h new file mode 100644 index 0000000..9537006 --- /dev/null +++ b/libstdc++/include/ext/vstring_fwd.h @@ -0,0 +1,75 @@ +// Versatile string forward -*- C++ -*- + +// 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. + +/** @file ext/vstring_fwd.h + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VSTRING_FWD_H +#define _VSTRING_FWD_H 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/char_traits.h> +#include <memory> // For allocator. + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _CharT, typename _Traits, typename _Alloc> + class __sso_string_base; + + template<typename _CharT, typename _Traits, typename _Alloc> + class __rc_string_base; + + template<typename _CharT, typename _Traits = std::char_traits<_CharT>, + typename _Alloc = std::allocator<_CharT>, + template + <typename, typename, typename> class _Base = __sso_string_base> + class __versa_string; + + typedef __versa_string<char> __vstring; + typedef __vstring __sso_string; + typedef + __versa_string<char, std::char_traits<char>, + std::allocator<char>, __rc_string_base> __rc_string; + +#ifdef _GLIBCXX_USE_WCHAR_T + typedef __versa_string<wchar_t> __wvstring; + typedef __wvstring __wsso_string; + typedef + __versa_string<wchar_t, std::char_traits<wchar_t>, + std::allocator<wchar_t>, __rc_string_base> __wrc_string; +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _VSTRING_FWD_H */ diff --git a/libstdc++/include/ext/vstring_util.h b/libstdc++/include/ext/vstring_util.h new file mode 100644 index 0000000..5ff3034 --- /dev/null +++ b/libstdc++/include/ext/vstring_util.h @@ -0,0 +1,177 @@ +// Versatile string utility -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 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. + +/** @file ext/vstring_util.h + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VSTRING_UTIL_H +#define _VSTRING_UTIL_H 1 + +#pragma GCC system_header + +#include <ext/vstring_fwd.h> +#include <debug/debug.h> +#include <bits/stl_function.h> // For less +#include <bits/functexcept.h> +#include <locale> +#include <algorithm> // For std::distance, srd::search. +#include <bits/ostream_insert.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _CharT, typename _Traits, typename _Alloc> + struct __vstring_utility + { + typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; + + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef typename _CharT_alloc_type::size_type size_type; + typedef typename _CharT_alloc_type::pointer pointer; + typedef typename _CharT_alloc_type::const_pointer const_pointer; + + // For __sso_string. + typedef __gnu_cxx:: + __normal_iterator<pointer, __gnu_cxx:: + __versa_string<_CharT, _Traits, _Alloc, + __sso_string_base> > + __sso_iterator; + typedef __gnu_cxx:: + __normal_iterator<const_pointer, __gnu_cxx:: + __versa_string<_CharT, _Traits, _Alloc, + __sso_string_base> > + __const_sso_iterator; + + // For __rc_string. + typedef __gnu_cxx:: + __normal_iterator<pointer, __gnu_cxx:: + __versa_string<_CharT, _Traits, _Alloc, + __rc_string_base> > + __rc_iterator; + typedef __gnu_cxx:: + __normal_iterator<const_pointer, __gnu_cxx:: + __versa_string<_CharT, _Traits, _Alloc, + __rc_string_base> > + __const_rc_iterator; + + // NB: When the allocator is empty, deriving from it saves space + // (http://www.cantrip.org/emptyopt.html). + template<typename _Alloc1> + struct _Alloc_hider + : public _Alloc1 + { + _Alloc_hider(const _Alloc1& __a, _CharT* __ptr) + : _Alloc1(__a), _M_p(__ptr) { } + + _CharT* _M_p; // The actual data. + }; + + // For use in _M_construct (_S_construct) forward_iterator_tag. + template<typename _Type> + static bool + _S_is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template<typename _Type> + static bool + _S_is_null_pointer(_Type) + { return false; } + + // When __n = 1 way faster than the general multichar + // traits_type::copy/move/assign. + static void + _S_copy(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::copy(__d, __s, __n); + } + + static void + _S_move(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::move(__d, __s, __n); + } + + static void + _S_assign(_CharT* __d, size_type __n, _CharT __c) + { + if (__n == 1) + traits_type::assign(*__d, __c); + else + traits_type::assign(__d, __n, __c); + } + + // _S_copy_chars is a separate template to permit specialization + // to optimize for the common case of pointers as iterators. + template<typename _Iterator> + static void + _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + { + for (; __k1 != __k2; ++__k1, ++__p) + traits_type::assign(*__p, *__k1); // These types are off. + } + + static void + _S_copy_chars(_CharT* __p, __sso_iterator __k1, __sso_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, __const_sso_iterator __k1, + __const_sso_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, __rc_iterator __k1, __rc_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, __const_rc_iterator __k1, + __const_rc_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) + { _S_copy(__p, __k1, __k2 - __k1); } + + static void + _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + { _S_copy(__p, __k1, __k2 - __k1); } + }; + +_GLIBCXX_END_NAMESPACE + +#endif /* _VSTRING_UTIL_H */ diff --git a/libstdc++/include/precompiled/extc++.h b/libstdc++/include/precompiled/extc++.h new file mode 100644 index 0000000..f01f39d --- /dev/null +++ b/libstdc++/include/precompiled/extc++.h @@ -0,0 +1,65 @@ +// C++ includes used for precompiling extensions -*- C++ -*- + +// Copyright (C) 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. + +/** @file extc++.h + * This is an implementation file for a precompiled header. + */ + +#include <bits/stdtr1c++.h> + +#include <ext/algorithm> +#include <ext/array_allocator.h> +#include <ext/bitmap_allocator.h> +#include <ext/codecvt_specializations.h> +#include <ext/debug_allocator.h> +#include <ext/functional> +#include <ext/hash_map> +#include <ext/hash_set> +#include <ext/iterator> +#include <ext/malloc_allocator.h> +#include <ext/memory> +#include <ext/mt_allocator.h> +#include <ext/new_allocator.h> +#include <ext/numeric> +#include <ext/pod_char_traits.h> +#include <ext/pool_allocator.h> +#include <ext/rb_tree> +#include <ext/rope> +#include <ext/slist> +#include <ext/stdio_filebuf.h> +#include <ext/stdio_sync_filebuf.h> +#include <ext/typelist.h> +#include <ext/vstring.h> +#include <ext/pb_ds/assoc_container.hpp> +#include <ext/pb_ds/priority_queue.hpp> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/hash_policy.hpp> +#include <ext/pb_ds/list_update_policy.hpp> +#include <ext/pb_ds/tree_policy.hpp> +#include <ext/pb_ds/trie_policy.hpp> diff --git a/libstdc++/include/precompiled/stdc++.h b/libstdc++/include/precompiled/stdc++.h new file mode 100644 index 0000000..df9c217 --- /dev/null +++ b/libstdc++/include/precompiled/stdc++.h @@ -0,0 +1,86 @@ +// C++ includes used for precompiling -*- C++ -*- + +// Copyright (C) 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. + +/** @file stdc++.h + * This is an implementation file for a precompiled header. + */ + +// 17.4.1.2 Headers + +// C +#include <cassert> +#include <cctype> +#include <cerrno> +#include <cfloat> +#include <ciso646> +#include <climits> +#include <clocale> +#include <cmath> +#include <csetjmp> +#include <csignal> +#include <cstdarg> +#include <cstddef> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ctime> + +// C++ +#include <algorithm> +#include <bitset> +#include <complex> +#include <deque> +#include <exception> +#include <fstream> +#include <functional> +#include <iomanip> +#include <ios> +#include <iosfwd> +#include <iostream> +#include <istream> +#include <iterator> +#include <limits> +#include <list> +#include <locale> +#include <map> +#include <memory> +#include <new> +#include <numeric> +#include <ostream> +#include <queue> +#include <set> +#include <sstream> +#include <stack> +#include <stdexcept> +#include <streambuf> +#include <string> +#include <typeinfo> +#include <utility> +#include <valarray> +#include <vector> diff --git a/libstdc++/include/precompiled/stdtr1c++.h b/libstdc++/include/precompiled/stdtr1c++.h new file mode 100644 index 0000000..2d65cf9 --- /dev/null +++ b/libstdc++/include/precompiled/stdtr1c++.h @@ -0,0 +1,58 @@ +// C++ includes used for precompiling TR1 -*- C++ -*- + +// Copyright (C) 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. + +/** @file stdtr1c++.h + * This is an implementation file for a precompiled header. + */ + +#include <bits/stdc++.h> + +#include <tr1/array> +#include <tr1/cctype> +#include <tr1/cfenv> +#include <tr1/cfloat> +#include <tr1/cinttypes> +#include <tr1/climits> +#include <tr1/cmath> +#include <tr1/complex> +#include <tr1/cstdarg> +#include <tr1/cstdbool> +#include <tr1/cstdint> +#include <tr1/cstdio> +#include <tr1/cstdlib> +#include <tr1/ctgmath> +#include <tr1/ctime> +#include <tr1/cwchar> +#include <tr1/cwctype> +#include <tr1/functional> +#include <tr1/random> +#include <tr1/tuple> +#include <tr1/unordered_map> +#include <tr1/unordered_set> +#include <tr1/utility> diff --git a/libstdc++/include/std/std_algorithm.h b/libstdc++/include/std/std_algorithm.h new file mode 100644 index 0000000..7ffbf97 --- /dev/null +++ b/libstdc++/include/std/std_algorithm.h @@ -0,0 +1,70 @@ +// <algorithm> -*- C++ -*- + +// Copyright (C) 2001, 2002 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/algorithm + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_ALGORITHM +#define _GLIBCXX_ALGORITHM 1 + +#pragma GCC system_header + +#include <bits/stl_algobase.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_algo.h> + +#endif /* _GLIBCXX_ALGORITHM */ diff --git a/libstdc++/include/std/std_bitset.h b/libstdc++/include/std/std_bitset.h new file mode 100644 index 0000000..860e775 --- /dev/null +++ b/libstdc++/include/std/std_bitset.h @@ -0,0 +1,1344 @@ +// <bitset> -*- C++ -*- + +// Copyright (C) 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. + +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/bitset + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_BITSET +#define _GLIBCXX_BITSET 1 + +#pragma GCC system_header + +#include <cstddef> // For size_t +#include <cstring> // For memset +#include <limits> // For numeric_limits +#include <string> +#include <bits/functexcept.h> // For invalid_argument, out_of_range, + // overflow_error +#include <ostream> // For ostream (operator<<) +#include <istream> // For istream (operator>>) + +#define _GLIBCXX_BITSET_BITS_PER_WORD numeric_limits<unsigned long>::digits +#define _GLIBCXX_BITSET_WORDS(__n) \ + ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1) \ + / _GLIBCXX_BITSET_BITS_PER_WORD) + +_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) + + /** + * @if maint + * Base class, general case. It is a class inveriant that _Nw will be + * nonnegative. + * + * See documentation for bitset. + * @endif + */ + template<size_t _Nw> + struct _Base_bitset + { + typedef unsigned long _WordT; + + /// 0 is the least significant word. + _WordT _M_w[_Nw]; + + _Base_bitset() + { _M_do_reset(); } + + _Base_bitset(unsigned long __val) + { + _M_do_reset(); + _M_w[0] = __val; + } + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + _WordT& + _M_getword(size_t __pos) + { return _M_w[_S_whichword(__pos)]; } + + _WordT + _M_getword(size_t __pos) const + { return _M_w[_S_whichword(__pos)]; } + + _WordT& + _M_hiword() + { return _M_w[_Nw - 1]; } + + _WordT + _M_hiword() const + { return _M_w[_Nw - 1]; } + + void + _M_do_and(const _Base_bitset<_Nw>& __x) + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] &= __x._M_w[__i]; + } + + void + _M_do_or(const _Base_bitset<_Nw>& __x) + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] |= __x._M_w[__i]; + } + + void + _M_do_xor(const _Base_bitset<_Nw>& __x) + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] ^= __x._M_w[__i]; + } + + void + _M_do_left_shift(size_t __shift); + + void + _M_do_right_shift(size_t __shift); + + void + _M_do_flip() + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] = ~_M_w[__i]; + } + + void + _M_do_set() + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] = ~static_cast<_WordT>(0); + } + + void + _M_do_reset() + { std::memset(_M_w, 0, _Nw * sizeof(_WordT)); } + + bool + _M_is_equal(const _Base_bitset<_Nw>& __x) const + { + for (size_t __i = 0; __i < _Nw; ++__i) + { + if (_M_w[__i] != __x._M_w[__i]) + return false; + } + return true; + } + + bool + _M_is_any() const + { + for (size_t __i = 0; __i < _Nw; __i++) + { + if (_M_w[__i] != static_cast<_WordT>(0)) + return true; + } + return false; + } + + size_t + _M_do_count() const + { + size_t __result = 0; + for (size_t __i = 0; __i < _Nw; __i++) + __result += __builtin_popcountl(_M_w[__i]); + return __result; + } + + unsigned long + _M_do_to_ulong() const; + + // find first "on" bit + size_t + _M_do_find_first(size_t __not_found) const; + + // find the next "on" bit that follows "prev" + size_t + _M_do_find_next(size_t __prev, size_t __not_found) const; + }; + + // Definitions of non-inline functions from _Base_bitset. + template<size_t _Nw> + void + _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; + + if (__offset == 0) + for (size_t __n = _Nw - 1; __n >= __wshift; --__n) + _M_w[__n] = _M_w[__n - __wshift]; + else + { + const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD + - __offset); + for (size_t __n = _Nw - 1; __n > __wshift; --__n) + _M_w[__n] = ((_M_w[__n - __wshift] << __offset) + | (_M_w[__n - __wshift - 1] >> __sub_offset)); + _M_w[__wshift] = _M_w[0] << __offset; + } + + std::fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); + } + } + + template<size_t _Nw> + void + _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __limit = _Nw - __wshift - 1; + + if (__offset == 0) + for (size_t __n = 0; __n <= __limit; ++__n) + _M_w[__n] = _M_w[__n + __wshift]; + else + { + const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD + - __offset); + for (size_t __n = 0; __n < __limit; ++__n) + _M_w[__n] = ((_M_w[__n + __wshift] >> __offset) + | (_M_w[__n + __wshift + 1] << __sub_offset)); + _M_w[__limit] = _M_w[_Nw-1] >> __offset; + } + + std::fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); + } + } + + template<size_t _Nw> + unsigned long + _Base_bitset<_Nw>::_M_do_to_ulong() const + { + for (size_t __i = 1; __i < _Nw; ++__i) + if (_M_w[__i]) + __throw_overflow_error(__N("_Base_bitset::_M_do_to_ulong")); + return _M_w[0]; + } + + template<size_t _Nw> + size_t + _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const + { + for (size_t __i = 0; __i < _Nw; __i++) + { + _WordT __thisword = _M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword)); + } + // not found, so return an indication of failure. + return __not_found; + } + + template<size_t _Nw> + size_t + _Base_bitset<_Nw>::_M_do_find_next(size_t __prev, size_t __not_found) const + { + // make bound inclusive + ++__prev; + + // check out of bounds + if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD) + return __not_found; + + // search first word + size_t __i = _S_whichword(__prev); + _WordT __thisword = _M_w[__i]; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if (__thisword != static_cast<_WordT>(0)) + return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword)); + + // check subsequent words + __i++; + for (; __i < _Nw; __i++) + { + __thisword = _M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword)); + } + // not found, so return an indication of failure. + return __not_found; + } // end _M_do_find_next + + /** + * @if maint + * Base class, specialization for a single word. + * + * See documentation for bitset. + * @endif + */ + template<> + struct _Base_bitset<1> + { + typedef unsigned long _WordT; + _WordT _M_w; + + _Base_bitset(void) + : _M_w(0) + { } + + _Base_bitset(unsigned long __val) + : _M_w(__val) + { } + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + _WordT& + _M_getword(size_t) + { return _M_w; } + + _WordT + _M_getword(size_t) const + { return _M_w; } + + _WordT& + _M_hiword() + { return _M_w; } + + _WordT + _M_hiword() const + { return _M_w; } + + void + _M_do_and(const _Base_bitset<1>& __x) + { _M_w &= __x._M_w; } + + void + _M_do_or(const _Base_bitset<1>& __x) + { _M_w |= __x._M_w; } + + void + _M_do_xor(const _Base_bitset<1>& __x) + { _M_w ^= __x._M_w; } + + void + _M_do_left_shift(size_t __shift) + { _M_w <<= __shift; } + + void + _M_do_right_shift(size_t __shift) + { _M_w >>= __shift; } + + void + _M_do_flip() + { _M_w = ~_M_w; } + + void + _M_do_set() + { _M_w = ~static_cast<_WordT>(0); } + + void + _M_do_reset() + { _M_w = 0; } + + bool + _M_is_equal(const _Base_bitset<1>& __x) const + { return _M_w == __x._M_w; } + + bool + _M_is_any() const + { return _M_w != 0; } + + size_t + _M_do_count() const + { return __builtin_popcountl(_M_w); } + + unsigned long + _M_do_to_ulong() const + { return _M_w; } + + size_t + _M_do_find_first(size_t __not_found) const + { + if (_M_w != 0) + return __builtin_ctzl(_M_w); + else + return __not_found; + } + + // find the next "on" bit that follows "prev" + size_t + _M_do_find_next(size_t __prev, size_t __not_found) const + { + ++__prev; + if (__prev >= ((size_t) _GLIBCXX_BITSET_BITS_PER_WORD)) + return __not_found; + + _WordT __x = _M_w >> __prev; + if (__x != 0) + return __builtin_ctzl(__x) + __prev; + else + return __not_found; + } + }; + + /** + * @if maint + * Base class, specialization for no storage (zero-length %bitset). + * + * See documentation for bitset. + * @endif + */ + template<> + struct _Base_bitset<0> + { + typedef unsigned long _WordT; + + _Base_bitset() + { } + + _Base_bitset(unsigned long) + { } + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + // This would normally give access to the data. The bounds-checking + // in the bitset class will prevent the user from getting this far, + // but (1) it must still return an lvalue to compile, and (2) the + // user might call _Unchecked_set directly, in which case this /needs/ + // to fail. Let's not penalize zero-length users unless they actually + // make an unchecked call; all the memory ugliness is therefore + // localized to this single should-never-get-this-far function. + _WordT& + _M_getword(size_t) const + { + __throw_out_of_range(__N("_Base_bitset::_M_getword")); + return *new _WordT; + } + + _WordT + _M_hiword() const + { return 0; } + + void + _M_do_and(const _Base_bitset<0>&) + { } + + void + _M_do_or(const _Base_bitset<0>&) + { } + + void + _M_do_xor(const _Base_bitset<0>&) + { } + + void + _M_do_left_shift(size_t) + { } + + void + _M_do_right_shift(size_t) + { } + + void + _M_do_flip() + { } + + void + _M_do_set() + { } + + void + _M_do_reset() + { } + + // Are all empty bitsets equal to each other? Are they equal to + // themselves? How to compare a thing which has no state? What is + // the sound of one zero-length bitset clapping? + bool + _M_is_equal(const _Base_bitset<0>&) const + { return true; } + + bool + _M_is_any() const + { return false; } + + size_t + _M_do_count() const + { return 0; } + + unsigned long + _M_do_to_ulong() const + { return 0; } + + // Normally "not found" is the size, but that could also be + // misinterpreted as an index in this corner case. Oh well. + size_t + _M_do_find_first(size_t) const + { return 0; } + + size_t + _M_do_find_next(size_t, size_t) const + { return 0; } + }; + + + // Helper class to zero out the unused high-order bits in the highest word. + template<size_t _Extrabits> + struct _Sanitize + { + static void _S_do_sanitize(unsigned long& __val) + { __val &= ~((~static_cast<unsigned long>(0)) << _Extrabits); } + }; + + template<> + struct _Sanitize<0> + { static void _S_do_sanitize(unsigned long) {} }; + + /** + * @brief The %bitset class represents a @e fixed-size sequence of bits. + * + * @ingroup Containers + * + * (Note that %bitset does @e not meet the formal requirements of a + * <a href="tables.html#65">container</a>. Mainly, it lacks iterators.) + * + * The template argument, @a Nb, may be any non-negative number, + * specifying the number of bits (e.g., "0", "12", "1024*1024"). + * + * In the general unoptimized case, storage is allocated in word-sized + * blocks. Let B be the number of bits in a word, then (Nb+(B-1))/B + * words will be used for storage. B - Nb%B bits are unused. (They are + * the high-order bits in the highest word.) It is a class invariant + * that those unused bits are always zero. + * + * If you think of %bitset as "a simple array of bits," be aware that + * your mental picture is reversed: a %bitset behaves the same way as + * bits in integers do, with the bit at index 0 in the "least significant + * / right-hand" position, and the bit at index Nb-1 in the "most + * significant / left-hand" position. Thus, unlike other containers, a + * %bitset's index "counts from right to left," to put it very loosely. + * + * This behavior is preserved when translating to and from strings. For + * example, the first line of the following program probably prints + * "b('a') is 0001100001" on a modern ASCII system. + * + * @code + * #include <bitset> + * #include <iostream> + * #include <sstream> + * + * using namespace std; + * + * int main() + * { + * long a = 'a'; + * bitset<10> b(a); + * + * cout << "b('a') is " << b << endl; + * + * ostringstream s; + * s << b; + * string str = s.str(); + * cout << "index 3 in the string is " << str[3] << " but\n" + * << "index 3 in the bitset is " << b[3] << endl; + * } + * @endcode + * + * Also see http://gcc.gnu.org/onlinedocs/libstdc++/ext/sgiexts.html#ch23 + * for a description of extensions. + * + * @if maint + * Most of the actual code isn't contained in %bitset<> itself, but in the + * base class _Base_bitset. The base class works with whole words, not with + * individual bits. This allows us to specialize _Base_bitset for the + * important special case where the %bitset is only a single word. + * + * Extra confusion can result due to the fact that the storage for + * _Base_bitset @e is a regular array, and is indexed as such. This is + * carefully encapsulated. + * @endif + */ + template<size_t _Nb> + class bitset + : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> + { + private: + typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; + typedef unsigned long _WordT; + + void + _M_do_sanitize() + { + _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD>:: + _S_do_sanitize(this->_M_hiword()); + } + + public: + /** + * This encapsulates the concept of a single bit. An instance of this + * class is a proxy for an actual bit; this way the individual bit + * operations are done as faster word-size bitwise instructions. + * + * Most users will never need to use this class directly; conversions + * to and from bool are automatic and should be transparent. Overloaded + * operators help to preserve the illusion. + * + * (On a typical system, this "bit %reference" is 64 times the size of + * an actual bit. Ha.) + */ + class reference + { + friend class bitset; + + _WordT *_M_wp; + size_t _M_bpos; + + // left undefined + reference(); + + public: + reference(bitset& __b, size_t __pos) + { + _M_wp = &__b._M_getword(__pos); + _M_bpos = _Base::_S_whichbit(__pos); + } + + ~reference() + { } + + // For b[i] = __x; + reference& + operator=(bool __x) + { + if (__x) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + return *this; + } + + // For b[i] = b[__j]; + reference& + operator=(const reference& __j) + { + if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos))) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + return *this; + } + + // Flips the bit + bool + operator~() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } + + // For __x = b[i]; + operator bool() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } + + // For b[i].flip(); + reference& + flip() + { + *_M_wp ^= _Base::_S_maskbit(_M_bpos); + return *this; + } + }; + friend class reference; + + // 23.3.5.1 constructors: + /// All bits set to zero. + bitset() + { } + + /// Initial bits bitwise-copied from a single word (others set to zero). + bitset(unsigned long __val) + : _Base(__val) + { _M_do_sanitize(); } + + /** + * @brief Use a subset of a string. + * @param s A string of '0' and '1' characters. + * @param position Index of the first character in @a s to use; + * defaults to zero. + * @throw std::out_of_range If @a pos is bigger the size of @a s. + * @throw std::invalid_argument If a character appears in the string + * which is neither '0' nor '1'. + */ + template<class _CharT, class _Traits, class _Alloc> + explicit + bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __position = 0) + : _Base() + { + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, + std::basic_string<_CharT, _Traits, _Alloc>::npos); + } + + /** + * @brief Use a subset of a string. + * @param s A string of '0' and '1' characters. + * @param position Index of the first character in @a s to use. + * @param n The number of characters to copy. + * @throw std::out_of_range If @a pos is bigger the size of @a s. + * @throw std::invalid_argument If a character appears in the string + * which is neither '0' nor '1'. + */ + template<class _CharT, class _Traits, class _Alloc> + bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __position, size_t __n) + : _Base() + { + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, __n); + } + + // 23.3.5.2 bitset operations: + //@{ + /** + * @brief Operations on bitsets. + * @param rhs A same-sized bitset. + * + * These should be self-explanatory. + */ + bitset<_Nb>& + operator&=(const bitset<_Nb>& __rhs) + { + this->_M_do_and(__rhs); + return *this; + } + + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) + { + this->_M_do_or(__rhs); + return *this; + } + + bitset<_Nb>& + operator^=(const bitset<_Nb>& __rhs) + { + this->_M_do_xor(__rhs); + return *this; + } + //@} + + //@{ + /** + * @brief Operations on bitsets. + * @param position The number of places to shift. + * + * These should be self-explanatory. + */ + bitset<_Nb>& + operator<<=(size_t __position) + { + if (__builtin_expect(__position < _Nb, 1)) + { + this->_M_do_left_shift(__position); + this->_M_do_sanitize(); + } + else + this->_M_do_reset(); + return *this; + } + + bitset<_Nb>& + operator>>=(size_t __position) + { + if (__builtin_expect(__position < _Nb, 1)) + { + this->_M_do_right_shift(__position); + this->_M_do_sanitize(); + } + else + this->_M_do_reset(); + return *this; + } + //@} + + //@{ + /** + * These versions of single-bit set, reset, flip, and test are + * extensions from the SGI version. They do no range checking. + * @ingroup SGIextensions + */ + bitset<_Nb>& + _Unchecked_set(size_t __pos) + { + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_set(size_t __pos, int __val) + { + if (__val) + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); + else + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_reset(size_t __pos) + { + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_flip(size_t __pos) + { + this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); + return *this; + } + + bool + _Unchecked_test(size_t __pos) const + { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) + != static_cast<_WordT>(0)); } + //@} + + // Set, reset, and flip. + /** + * @brief Sets every bit to true. + */ + bitset<_Nb>& + set() + { + this->_M_do_set(); + this->_M_do_sanitize(); + return *this; + } + + /** + * @brief Sets a given bit to a particular value. + * @param position The index of the bit. + * @param val Either true or false, defaults to true. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bitset<_Nb>& + set(size_t __position, bool __val = true) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::set")); + return _Unchecked_set(__position, __val); + } + + /** + * @brief Sets every bit to false. + */ + bitset<_Nb>& + reset() + { + this->_M_do_reset(); + return *this; + } + + /** + * @brief Sets a given bit to false. + * @param position The index of the bit. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + * + * Same as writing @c set(pos,false). + */ + bitset<_Nb>& + reset(size_t __position) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::reset")); + return _Unchecked_reset(__position); + } + + /** + * @brief Toggles every bit to its opposite value. + */ + bitset<_Nb>& + flip() + { + this->_M_do_flip(); + this->_M_do_sanitize(); + return *this; + } + + /** + * @brief Toggles a given bit to its opposite value. + * @param position The index of the bit. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bitset<_Nb>& + flip(size_t __position) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::flip")); + return _Unchecked_flip(__position); + } + + /// See the no-argument flip(). + bitset<_Nb> + operator~() const + { return bitset<_Nb>(*this).flip(); } + + //@{ + /** + * @brief Array-indexing support. + * @param position Index into the %bitset. + * @return A bool for a 'const %bitset'. For non-const bitsets, an + * instance of the reference proxy class. + * @note These operators do no range checking and throw no exceptions, + * as required by DR 11 to the standard. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already + * resolves DR 11 (items 1 and 2), but does not do the range-checking + * required by that DR's resolution. -pme + * The DR has since been changed: range-checking is a precondition + * (users' responsibility), and these functions must not throw. -pme + * @endif + */ + reference + operator[](size_t __position) + { return reference(*this,__position); } + + bool + operator[](size_t __position) const + { return _Unchecked_test(__position); } + //@} + + /** + * @brief Retuns a numerical interpretation of the %bitset. + * @return The integral equivalent of the bits. + * @throw std::overflow_error If there are too many bits to be + * represented in an @c unsigned @c long. + */ + unsigned long + to_ulong() const + { return this->_M_do_to_ulong(); } + + /** + * @brief Retuns a character interpretation of the %bitset. + * @return The string equivalent of the bits. + * + * Note the ordering of the bits: decreasing character positions + * correspond to increasing bit positions (see the main class notes for + * an example). + */ + template<class _CharT, class _Traits, class _Alloc> + std::basic_string<_CharT, _Traits, _Alloc> + to_string() const + { + std::basic_string<_CharT, _Traits, _Alloc> __result; + _M_copy_to_string(__result); + return __result; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 434. bitset::to_string() hard to use. + template<class _CharT, class _Traits> + std::basic_string<_CharT, _Traits, std::allocator<_CharT> > + to_string() const + { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); } + + template<class _CharT> + std::basic_string<_CharT, std::char_traits<_CharT>, + std::allocator<_CharT> > + to_string() const + { + return to_string<_CharT, std::char_traits<_CharT>, + std::allocator<_CharT> >(); + } + + std::basic_string<char, std::char_traits<char>, std::allocator<char> > + to_string() const + { + return to_string<char, std::char_traits<char>, + std::allocator<char> >(); + } + + // Helper functions for string operations. + template<class _CharT, class _Traits, class _Alloc> + void + _M_copy_from_string(const std::basic_string<_CharT, + _Traits, _Alloc>& __s, + size_t, size_t); + + template<class _CharT, class _Traits, class _Alloc> + void + _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&) const; + + /// Returns the number of bits which are set. + size_t + count() const + { return this->_M_do_count(); } + + /// Returns the total number of bits. + size_t + size() const + { return _Nb; } + + //@{ + /// These comparisons for equality/inequality are, well, @e bitwise. + bool + operator==(const bitset<_Nb>& __rhs) const + { return this->_M_is_equal(__rhs); } + + bool + operator!=(const bitset<_Nb>& __rhs) const + { return !this->_M_is_equal(__rhs); } + //@} + + /** + * @brief Tests the value of a bit. + * @param position The index of a bit. + * @return The value at @a pos. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bool + test(size_t __position) const + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::test")); + return _Unchecked_test(__position); + } + + /** + * @brief Tests whether any of the bits are on. + * @return True if at least one bit is set. + */ + bool + any() const + { return this->_M_is_any(); } + + /** + * @brief Tests whether any of the bits are on. + * @return True if none of the bits are set. + */ + bool + none() const + { return !this->_M_is_any(); } + + //@{ + /// Self-explanatory. + bitset<_Nb> + operator<<(size_t __position) const + { return bitset<_Nb>(*this) <<= __position; } + + bitset<_Nb> + operator>>(size_t __position) const + { return bitset<_Nb>(*this) >>= __position; } + //@} + + /** + * @brief Finds the index of the first "on" bit. + * @return The index of the first bit set, or size() if not found. + * @ingroup SGIextensions + * @sa _Find_next + */ + size_t + _Find_first() const + { return this->_M_do_find_first(_Nb); } + + /** + * @brief Finds the index of the next "on" bit after prev. + * @return The index of the next bit set, or size() if not found. + * @param prev Where to start searching. + * @ingroup SGIextensions + * @sa _Find_first + */ + size_t + _Find_next(size_t __prev ) const + { return this->_M_do_find_next(__prev, _Nb); } + }; + + // Definitions of non-inline member functions. + template<size_t _Nb> + template<class _CharT, class _Traits, class _Alloc> + void + bitset<_Nb>:: + _M_copy_from_string(const std::basic_string<_CharT, _Traits, + _Alloc>& __s, size_t __pos, size_t __n) + { + reset(); + const size_t __nbits = std::min(_Nb, std::min(__n, __s.size() - __pos)); + for (size_t __i = __nbits; __i > 0; --__i) + { + switch(__s[__pos + __nbits - __i]) + { + case '0': + break; + case '1': + _Unchecked_set(__i - 1); + break; + default: + __throw_invalid_argument(__N("bitset::_M_copy_from_string")); + } + } + } + + template<size_t _Nb> + template<class _CharT, class _Traits, class _Alloc> + void + bitset<_Nb>:: + _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>& __s) const + { + __s.assign(_Nb, '0'); + for (size_t __i = _Nb; __i > 0; --__i) + if (_Unchecked_test(__i - 1)) + __s[_Nb - __i] = '1'; + } + + // 23.3.5.3 bitset operations: + //@{ + /** + * @brief Global bitwise operations on bitsets. + * @param x A bitset. + * @param y A bitset of the same size as @a x. + * @return A new bitset. + * + * These should be self-explanatory. + */ + template<size_t _Nb> + inline bitset<_Nb> + operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { + bitset<_Nb> __result(__x); + __result &= __y; + return __result; + } + + template<size_t _Nb> + inline bitset<_Nb> + operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { + bitset<_Nb> __result(__x); + __result |= __y; + return __result; + } + + template <size_t _Nb> + inline bitset<_Nb> + operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { + bitset<_Nb> __result(__x); + __result ^= __y; + return __result; + } + //@} + + //@{ + /** + * @brief Global I/O operators for bitsets. + * + * Direct I/O between streams and bitsets is supported. Output is + * straightforward. Input will skip whitespace, only accept '0' and '1' + * characters, and will only extract as many digits as the %bitset will + * hold. + */ + template<class _CharT, class _Traits, size_t _Nb> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + { + typedef typename _Traits::char_type char_type; + std::basic_string<_CharT, _Traits> __tmp; + __tmp.reserve(_Nb); + + std::ios_base::iostate __state = std::ios_base::goodbit; + typename std::basic_istream<_CharT, _Traits>::sentry __sentry(__is); + if (__sentry) + { + try + { + basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 303. Bitset input operator underspecified + const char_type __zero = __is.widen('0'); + const char_type __one = __is.widen('1'); + for (size_t __i = _Nb; __i > 0; --__i) + { + static typename _Traits::int_type __eof = _Traits::eof(); + + typename _Traits::int_type __c1 = __buf->sbumpc(); + if (_Traits::eq_int_type(__c1, __eof)) + { + __state |= std::ios_base::eofbit; + break; + } + else + { + const char_type __c2 = _Traits::to_char_type(__c1); + if (__c2 == __zero) + __tmp.push_back('0'); + else if (__c2 == __one) + __tmp.push_back('1'); + else if (_Traits::eq_int_type(__buf->sputbackc(__c2), + __eof)) + { + __state |= std::ios_base::failbit; + break; + } + } + } + } + catch(...) + { __is._M_setstate(std::ios_base::badbit); } + } + + if (__tmp.empty() && _Nb) + __state |= std::ios_base::failbit; + else + __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb); + if (__state) + __is.setstate(__state); + return __is; + } + + template <class _CharT, class _Traits, size_t _Nb> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bitset<_Nb>& __x) + { + std::basic_string<_CharT, _Traits> __tmp; + __x._M_copy_to_string(__tmp); + return __os << __tmp; + } + + // Specializations for zero-sized bitsets, to avoid "unsigned comparison + // with zero" warnings. + template<> + inline bitset<0>& + bitset<0>:: + set(size_t, bool) + { + __throw_out_of_range(__N("bitset::set")); + return *this; + } + + template<> + inline bitset<0>& + bitset<0>:: + reset(size_t) + { + __throw_out_of_range(__N("bitset::reset")); + return *this; + } + + template<> + inline bitset<0>& + bitset<0>:: + flip(size_t) + { + __throw_out_of_range(__N("bitset::flip")); + return *this; + } + + template<> + inline bool + bitset<0>:: + test(size_t) const + { + __throw_out_of_range(__N("bitset::test")); + return false; + } + //@} + +_GLIBCXX_END_NESTED_NAMESPACE + +#undef _GLIBCXX_BITSET_WORDS +#undef _GLIBCXX_BITSET_BITS_PER_WORD + +#ifdef _GLIBCXX_DEBUG +# include <debug/bitset> +#endif + +#endif /* _GLIBCXX_BITSET */ diff --git a/libstdc++/include/std/std_complex.h b/libstdc++/include/std/std_complex.h new file mode 100644 index 0000000..26f31f6 --- /dev/null +++ b/libstdc++/include/std/std_complex.h @@ -0,0 +1,1489 @@ +// The template and inlines for the -*- C++ -*- complex number classes. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 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. + +/** @file complex + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 26.2 Complex Numbers +// Note: this is not a conforming implementation. +// Initially implemented by Ulrich Drepper <drepper@cygnus.com> +// Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> +// + +#ifndef _GLIBCXX_COMPLEX +#define _GLIBCXX_COMPLEX 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/cpp_type_traits.h> +#include <cmath> +#include <sstream> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Forward declarations. + template<typename _Tp> class complex; + template<> class complex<float>; + template<> class complex<double>; + template<> class complex<long double>; + + /// Return magnitude of @a z. + template<typename _Tp> _Tp abs(const complex<_Tp>&); + /// Return phase angle of @a z. + template<typename _Tp> _Tp arg(const complex<_Tp>&); + /// Return @a z magnitude squared. + template<typename _Tp> _Tp norm(const complex<_Tp>&); + + /// Return complex conjugate of @a z. + template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&); + /// Return complex with magnitude @a rho and angle @a theta. + template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0); + + // Transcendentals: + /// Return complex cosine of @a z. + template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); + /// Return complex hyperbolic cosine of @a z. + template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); + /// Return complex base e exponential of @a z. + template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); + /// Return complex natural logarithm of @a z. + template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); + /// Return complex base 10 logarithm of @a z. + template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); + /// Return complex cosine of @a z. + template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); + /// Return @a x to the @a y'th power. + template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); + /// Return @a x to the @a y'th power. + template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, + const complex<_Tp>&); + /// Return @a x to the @a y'th power. + template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); + /// Return complex sine of @a z. + template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); + /// Return complex hyperbolic sine of @a z. + template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); + /// Return complex square root of @a z. + template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); + /// Return complex tangent of @a z. + template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); + /// Return complex hyperbolic tangent of @a z. + template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); + //@} + + + // 26.2.2 Primary template class complex + /** + * Template to represent complex numbers. + * + * Specializations for float, double, and long double are part of the + * library. Results with any other type are not guaranteed. + * + * @param Tp Type of real and imaginary values. + */ + template<typename _Tp> + struct complex + { + /// Value typedef. + typedef _Tp value_type; + + /// Default constructor. First parameter is x, second parameter is y. + /// Unspecified parameters default to 0. + complex(const _Tp& = _Tp(), const _Tp & = _Tp()); + + // Lets the compiler synthesize the copy constructor + // complex (const complex<_Tp>&); + /// Copy constructor. + template<typename _Up> + complex(const complex<_Up>&); + + /// Return real part of complex number. + _Tp& real(); + /// Return real part of complex number. + const _Tp& real() const; + /// Return imaginary part of complex number. + _Tp& imag(); + /// Return imaginary part of complex number. + const _Tp& imag() const; + + /// Assign this complex number to scalar @a t. + complex<_Tp>& operator=(const _Tp&); + /// Add @a t to this complex number. + complex<_Tp>& operator+=(const _Tp&); + /// Subtract @a t from this complex number. + complex<_Tp>& operator-=(const _Tp&); + /// Multiply this complex number by @a t. + complex<_Tp>& operator*=(const _Tp&); + /// Divide this complex number by @a t. + complex<_Tp>& operator/=(const _Tp&); + + // Lets the compiler synthesize the + // copy and assignment operator + // complex<_Tp>& operator= (const complex<_Tp>&); + /// Assign this complex number to complex @a z. + template<typename _Up> + complex<_Tp>& operator=(const complex<_Up>&); + /// Add @a z to this complex number. + template<typename _Up> + complex<_Tp>& operator+=(const complex<_Up>&); + /// Subtract @a z from this complex number. + template<typename _Up> + complex<_Tp>& operator-=(const complex<_Up>&); + /// Multiply this complex number by @a z. + template<typename _Up> + complex<_Tp>& operator*=(const complex<_Up>&); + /// Divide this complex number by @a z. + template<typename _Up> + complex<_Tp>& operator/=(const complex<_Up>&); + + const complex& __rep() const; + + private: + _Tp _M_real; + _Tp _M_imag; + }; + + template<typename _Tp> + inline _Tp& + complex<_Tp>::real() { return _M_real; } + + template<typename _Tp> + inline const _Tp& + complex<_Tp>::real() const { return _M_real; } + + template<typename _Tp> + inline _Tp& + complex<_Tp>::imag() { return _M_imag; } + + template<typename _Tp> + inline const _Tp& + complex<_Tp>::imag() const { return _M_imag; } + + template<typename _Tp> + inline + complex<_Tp>::complex(const _Tp& __r, const _Tp& __i) + : _M_real(__r), _M_imag(__i) { } + + template<typename _Tp> + template<typename _Up> + inline + complex<_Tp>::complex(const complex<_Up>& __z) + : _M_real(__z.real()), _M_imag(__z.imag()) { } + + template<typename _Tp> + complex<_Tp>& + complex<_Tp>::operator=(const _Tp& __t) + { + _M_real = __t; + _M_imag = _Tp(); + return *this; + } + + // 26.2.5/1 + template<typename _Tp> + inline complex<_Tp>& + complex<_Tp>::operator+=(const _Tp& __t) + { + _M_real += __t; + return *this; + } + + // 26.2.5/3 + template<typename _Tp> + inline complex<_Tp>& + complex<_Tp>::operator-=(const _Tp& __t) + { + _M_real -= __t; + return *this; + } + + // 26.2.5/5 + template<typename _Tp> + complex<_Tp>& + complex<_Tp>::operator*=(const _Tp& __t) + { + _M_real *= __t; + _M_imag *= __t; + return *this; + } + + // 26.2.5/7 + template<typename _Tp> + complex<_Tp>& + complex<_Tp>::operator/=(const _Tp& __t) + { + _M_real /= __t; + _M_imag /= __t; + return *this; + } + + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator=(const complex<_Up>& __z) + { + _M_real = __z.real(); + _M_imag = __z.imag(); + return *this; + } + + // 26.2.5/9 + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator+=(const complex<_Up>& __z) + { + _M_real += __z.real(); + _M_imag += __z.imag(); + return *this; + } + + // 26.2.5/11 + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator-=(const complex<_Up>& __z) + { + _M_real -= __z.real(); + _M_imag -= __z.imag(); + return *this; + } + + // 26.2.5/13 + // XXX: This is a grammar school implementation. + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator*=(const complex<_Up>& __z) + { + const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); + _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); + _M_real = __r; + return *this; + } + + // 26.2.5/15 + // XXX: This is a grammar school implementation. + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator/=(const complex<_Up>& __z) + { + const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); + const _Tp __n = std::norm(__z); + _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; + _M_real = __r / __n; + return *this; + } + + template<typename _Tp> + inline const complex<_Tp>& + complex<_Tp>::__rep() const { return *this; } + + // Operators: + //@{ + /// Return new complex value @a x plus @a y. + template<typename _Tp> + inline complex<_Tp> + operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r += __y; + return __r; + } + + template<typename _Tp> + inline complex<_Tp> + operator+(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r.real() += __y; + return __r; + } + + template<typename _Tp> + inline complex<_Tp> + operator+(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __y; + __r.real() += __x; + return __r; + } + //@} + + //@{ + /// Return new complex value @a x minus @a y. + template<typename _Tp> + inline complex<_Tp> + operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r -= __y; + return __r; + } + + template<typename _Tp> + inline complex<_Tp> + operator-(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r.real() -= __y; + return __r; + } + + template<typename _Tp> + inline complex<_Tp> + operator-(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r(__x, -__y.imag()); + __r.real() -= __y.real(); + return __r; + } + //@} + + //@{ + /// Return new complex value @a x times @a y. + template<typename _Tp> + inline complex<_Tp> + operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r *= __y; + return __r; + } + + template<typename _Tp> + inline complex<_Tp> + operator*(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r *= __y; + return __r; + } + + template<typename _Tp> + inline complex<_Tp> + operator*(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __y; + __r *= __x; + return __r; + } + //@} + + //@{ + /// Return new complex value @a x divided by @a y. + template<typename _Tp> + inline complex<_Tp> + operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + + template<typename _Tp> + inline complex<_Tp> + operator/(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + + template<typename _Tp> + inline complex<_Tp> + operator/(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + //@} + + /// Return @a x. + template<typename _Tp> + inline complex<_Tp> + operator+(const complex<_Tp>& __x) + { return __x; } + + /// Return complex negation of @a x. + template<typename _Tp> + inline complex<_Tp> + operator-(const complex<_Tp>& __x) + { return complex<_Tp>(-__x.real(), -__x.imag()); } + + //@{ + /// Return true if @a x is equal to @a y. + template<typename _Tp> + inline bool + operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __x.real() == __y.real() && __x.imag() == __y.imag(); } + + template<typename _Tp> + inline bool + operator==(const complex<_Tp>& __x, const _Tp& __y) + { return __x.real() == __y && __x.imag() == _Tp(); } + + template<typename _Tp> + inline bool + operator==(const _Tp& __x, const complex<_Tp>& __y) + { return __x == __y.real() && _Tp() == __y.imag(); } + //@} + + //@{ + /// Return false if @a x is equal to @a y. + template<typename _Tp> + inline bool + operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __x.real() != __y.real() || __x.imag() != __y.imag(); } + + template<typename _Tp> + inline bool + operator!=(const complex<_Tp>& __x, const _Tp& __y) + { return __x.real() != __y || __x.imag() != _Tp(); } + + template<typename _Tp> + inline bool + operator!=(const _Tp& __x, const complex<_Tp>& __y) + { return __x != __y.real() || _Tp() != __y.imag(); } + //@} + + /// Extraction operator for complex values. + template<typename _Tp, typename _CharT, class _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) + { + _Tp __re_x, __im_x; + _CharT __ch; + __is >> __ch; + if (__ch == '(') + { + __is >> __re_x >> __ch; + if (__ch == ',') + { + __is >> __im_x >> __ch; + if (__ch == ')') + __x = complex<_Tp>(__re_x, __im_x); + else + __is.setstate(ios_base::failbit); + } + else if (__ch == ')') + __x = __re_x; + else + __is.setstate(ios_base::failbit); + } + else + { + __is.putback(__ch); + __is >> __re_x; + __x = __re_x; + } + return __is; + } + + /// Insertion operator for complex values. + template<typename _Tp, typename _CharT, class _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) + { + basic_ostringstream<_CharT, _Traits> __s; + __s.flags(__os.flags()); + __s.imbue(__os.getloc()); + __s.precision(__os.precision()); + __s << '(' << __x.real() << ',' << __x.imag() << ')'; + return __os << __s.str(); + } + + // Values + template<typename _Tp> + inline _Tp& + real(complex<_Tp>& __z) + { return __z.real(); } + + template<typename _Tp> + inline const _Tp& + real(const complex<_Tp>& __z) + { return __z.real(); } + + template<typename _Tp> + inline _Tp& + imag(complex<_Tp>& __z) + { return __z.imag(); } + + template<typename _Tp> + inline const _Tp& + imag(const complex<_Tp>& __z) + { return __z.imag(); } + + // 26.2.7/3 abs(__z): Returns the magnitude of __z. + template<typename _Tp> + inline _Tp + __complex_abs(const complex<_Tp>& __z) + { + _Tp __x = __z.real(); + _Tp __y = __z.imag(); + const _Tp __s = std::max(abs(__x), abs(__y)); + if (__s == _Tp()) // well ... + return __s; + __x /= __s; + __y /= __s; + return __s * sqrt(__x * __x + __y * __y); + } + +#if _GLIBCXX_USE_C99_COMPLEX + inline float + __complex_abs(__complex__ float __z) { return __builtin_cabsf(__z); } + + inline double + __complex_abs(__complex__ double __z) { return __builtin_cabs(__z); } + + inline long double + __complex_abs(const __complex__ long double& __z) + { return __builtin_cabsl(__z); } + + template<typename _Tp> + inline _Tp + abs(const complex<_Tp>& __z) { return __complex_abs(__z.__rep()); } +#else + template<typename _Tp> + inline _Tp + abs(const complex<_Tp>& __z) { return __complex_abs(__z); } +#endif + + + // 26.2.7/4: arg(__z): Returns the phase angle of __z. + template<typename _Tp> + inline _Tp + __complex_arg(const complex<_Tp>& __z) + { return atan2(__z.imag(), __z.real()); } + +#if _GLIBCXX_USE_C99_COMPLEX + inline float + __complex_arg(__complex__ float __z) { return __builtin_cargf(__z); } + + inline double + __complex_arg(__complex__ double __z) { return __builtin_carg(__z); } + + inline long double + __complex_arg(const __complex__ long double& __z) + { return __builtin_cargl(__z); } + + template<typename _Tp> + inline _Tp + arg(const complex<_Tp>& __z) { return __complex_arg(__z.__rep()); } +#else + template<typename _Tp> + inline _Tp + arg(const complex<_Tp>& __z) { return __complex_arg(__z); } +#endif + + // 26.2.7/5: norm(__z) returns the squared magintude of __z. + // As defined, norm() is -not- a norm is the common mathematical + // sens used in numerics. The helper class _Norm_helper<> tries to + // distinguish between builtin floating point and the rest, so as + // to deliver an answer as close as possible to the real value. + template<bool> + struct _Norm_helper + { + template<typename _Tp> + static inline _Tp _S_do_it(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return __x * __x + __y * __y; + } + }; + + template<> + struct _Norm_helper<true> + { + template<typename _Tp> + static inline _Tp _S_do_it(const complex<_Tp>& __z) + { + _Tp __res = std::abs(__z); + return __res * __res; + } + }; + + template<typename _Tp> + inline _Tp + norm(const complex<_Tp>& __z) + { + return _Norm_helper<__is_floating<_Tp>::__value + && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); + } + + template<typename _Tp> + inline complex<_Tp> + polar(const _Tp& __rho, const _Tp& __theta) + { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } + + template<typename _Tp> + inline complex<_Tp> + conj(const complex<_Tp>& __z) + { return complex<_Tp>(__z.real(), -__z.imag()); } + + // Transcendentals + + // 26.2.8/1 cos(__z): Returns the cosine of __z. + template<typename _Tp> + inline complex<_Tp> + __complex_cos(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); + } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_cos(__complex__ float __z) { return __builtin_ccosf(__z); } + + inline __complex__ double + __complex_cos(__complex__ double __z) { return __builtin_ccos(__z); } + + inline __complex__ long double + __complex_cos(const __complex__ long double& __z) + { return __builtin_ccosl(__z); } + + template<typename _Tp> + inline complex<_Tp> + cos(const complex<_Tp>& __z) { return __complex_cos(__z.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + cos(const complex<_Tp>& __z) { return __complex_cos(__z); } +#endif + + // 26.2.8/2 cosh(__z): Returns the hyperbolic cosine of __z. + template<typename _Tp> + inline complex<_Tp> + __complex_cosh(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); + } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_cosh(__complex__ float __z) { return __builtin_ccoshf(__z); } + + inline __complex__ double + __complex_cosh(__complex__ double __z) { return __builtin_ccosh(__z); } + + inline __complex__ long double + __complex_cosh(const __complex__ long double& __z) + { return __builtin_ccoshl(__z); } + + template<typename _Tp> + inline complex<_Tp> + cosh(const complex<_Tp>& __z) { return __complex_cosh(__z.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); } +#endif + + // 26.2.8/3 exp(__z): Returns the complex base e exponential of x + template<typename _Tp> + inline complex<_Tp> + __complex_exp(const complex<_Tp>& __z) + { return std::polar(exp(__z.real()), __z.imag()); } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); } + + inline __complex__ double + __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); } + + inline __complex__ long double + __complex_exp(const __complex__ long double& __z) + { return __builtin_cexpl(__z); } + + template<typename _Tp> + inline complex<_Tp> + exp(const complex<_Tp>& __z) { return __complex_exp(__z.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + exp(const complex<_Tp>& __z) { return __complex_exp(__z); } +#endif + + // 26.2.8/5 log(__z): Reurns the natural complex logaritm of __z. + // The branch cut is along the negative axis. + template<typename _Tp> + inline complex<_Tp> + __complex_log(const complex<_Tp>& __z) + { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_log(__complex__ float __z) { return __builtin_clogf(__z); } + + inline __complex__ double + __complex_log(__complex__ double __z) { return __builtin_clog(__z); } + + inline __complex__ long double + __complex_log(const __complex__ long double& __z) + { return __builtin_clogl(__z); } + + template<typename _Tp> + inline complex<_Tp> + log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + log(const complex<_Tp>& __z) { return __complex_log(__z); } +#endif + + template<typename _Tp> + inline complex<_Tp> + log10(const complex<_Tp>& __z) + { return std::log(__z) / log(_Tp(10.0)); } + + // 26.2.8/10 sin(__z): Returns the sine of __z. + template<typename _Tp> + inline complex<_Tp> + __complex_sin(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); + } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_sin(__complex__ float __z) { return __builtin_csinf(__z); } + + inline __complex__ double + __complex_sin(__complex__ double __z) { return __builtin_csin(__z); } + + inline __complex__ long double + __complex_sin(const __complex__ long double& __z) + { return __builtin_csinl(__z); } + + template<typename _Tp> + inline complex<_Tp> + sin(const complex<_Tp>& __z) { return __complex_sin(__z.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + sin(const complex<_Tp>& __z) { return __complex_sin(__z); } +#endif + + // 26.2.8/11 sinh(__z): Returns the hyperbolic sine of __z. + template<typename _Tp> + inline complex<_Tp> + __complex_sinh(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); + } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_sinh(__complex__ float __z) { return __builtin_csinhf(__z); } + + inline __complex__ double + __complex_sinh(__complex__ double __z) { return __builtin_csinh(__z); } + + inline __complex__ long double + __complex_sinh(const __complex__ long double& __z) + { return __builtin_csinhl(__z); } + + template<typename _Tp> + inline complex<_Tp> + sinh(const complex<_Tp>& __z) { return __complex_sinh(__z.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + sinh(const complex<_Tp>& __z) { return __complex_sinh(__z); } +#endif + + // 26.2.8/13 sqrt(__z): Returns the complex square root of __z. + // The branch cut is on the negative axis. + template<typename _Tp> + complex<_Tp> + __complex_sqrt(const complex<_Tp>& __z) + { + _Tp __x = __z.real(); + _Tp __y = __z.imag(); + + if (__x == _Tp()) + { + _Tp __t = sqrt(abs(__y) / 2); + return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); + } + else + { + _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); + _Tp __u = __t / 2; + return __x > _Tp() + ? complex<_Tp>(__u, __y / __t) + : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); + } + } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_sqrt(__complex__ float __z) { return __builtin_csqrtf(__z); } + + inline __complex__ double + __complex_sqrt(__complex__ double __z) { return __builtin_csqrt(__z); } + + inline __complex__ long double + __complex_sqrt(const __complex__ long double& __z) + { return __builtin_csqrtl(__z); } + + template<typename _Tp> + inline complex<_Tp> + sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z); } +#endif + + // 26.2.8/14 tan(__z): Return the complex tangent of __z. + + template<typename _Tp> + inline complex<_Tp> + __complex_tan(const complex<_Tp>& __z) + { return std::sin(__z) / std::cos(__z); } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_tan(__complex__ float __z) { return __builtin_ctanf(__z); } + + inline __complex__ double + __complex_tan(__complex__ double __z) { return __builtin_ctan(__z); } + + inline __complex__ long double + __complex_tan(const __complex__ long double& __z) + { return __builtin_ctanl(__z); } + + template<typename _Tp> + inline complex<_Tp> + tan(const complex<_Tp>& __z) { return __complex_tan(__z.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + tan(const complex<_Tp>& __z) { return __complex_tan(__z); } +#endif + + + // 26.2.8/15 tanh(__z): Returns the hyperbolic tangent of __z. + + template<typename _Tp> + inline complex<_Tp> + __complex_tanh(const complex<_Tp>& __z) + { return std::sinh(__z) / std::cosh(__z); } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); } + + inline __complex__ double + __complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); } + + inline __complex__ long double + __complex_tanh(const __complex__ long double& __z) + { return __builtin_ctanhl(__z); } + + template<typename _Tp> + inline complex<_Tp> + tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); } +#endif + + + // 26.2.8/9 pow(__x, __y): Returns the complex power base of __x + // raised to the __y-th power. The branch + // cut is on the negative axis. + template<typename _Tp> + inline complex<_Tp> + pow(const complex<_Tp>& __z, int __n) + { return std::__pow_helper(__z, __n); } + + template<typename _Tp> + complex<_Tp> + pow(const complex<_Tp>& __x, const _Tp& __y) + { +#ifndef _GLIBCXX_USE_C99_COMPLEX + if (__x == _Tp()) + return _Tp(); +#endif + if (__x.imag() == _Tp() && __x.real() > _Tp()) + return pow(__x.real(), __y); + + complex<_Tp> __t = std::log(__x); + return std::polar(exp(__y * __t.real()), __y * __t.imag()); + } + + template<typename _Tp> + inline complex<_Tp> + __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); } + +#if _GLIBCXX_USE_C99_COMPLEX + inline __complex__ float + __complex_pow(__complex__ float __x, __complex__ float __y) + { return __builtin_cpowf(__x, __y); } + + inline __complex__ double + __complex_pow(__complex__ double __x, __complex__ double __y) + { return __builtin_cpow(__x, __y); } + + inline __complex__ long double + __complex_pow(const __complex__ long double& __x, + const __complex__ long double& __y) + { return __builtin_cpowl(__x, __y); } + + template<typename _Tp> + inline complex<_Tp> + pow(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __complex_pow(__x.__rep(), __y.__rep()); } +#else + template<typename _Tp> + inline complex<_Tp> + pow(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __complex_pow(__x, __y); } +#endif + + template<typename _Tp> + inline complex<_Tp> + pow(const _Tp& __x, const complex<_Tp>& __y) + { + return __x > _Tp() ? std::polar(pow(__x, __y.real()), + __y.imag() * log(__x)) + : std::pow(complex<_Tp>(__x, _Tp()), __y); + } + + // 26.2.3 complex specializations + // complex<float> specialization + template<> + struct complex<float> + { + typedef float value_type; + typedef __complex__ float _ComplexT; + + complex(_ComplexT __z) : _M_value(__z) { } + + complex(float = 0.0f, float = 0.0f); + + explicit complex(const complex<double>&); + explicit complex(const complex<long double>&); + + float& real(); + const float& real() const; + float& imag(); + const float& imag() const; + + complex<float>& operator=(float); + complex<float>& operator+=(float); + complex<float>& operator-=(float); + complex<float>& operator*=(float); + complex<float>& operator/=(float); + + // Let's the compiler synthetize the copy and assignment + // operator. It always does a pretty good job. + // complex& operator= (const complex&); + template<typename _Tp> + complex<float>&operator=(const complex<_Tp>&); + template<typename _Tp> + complex<float>& operator+=(const complex<_Tp>&); + template<class _Tp> + complex<float>& operator-=(const complex<_Tp>&); + template<class _Tp> + complex<float>& operator*=(const complex<_Tp>&); + template<class _Tp> + complex<float>&operator/=(const complex<_Tp>&); + + const _ComplexT& __rep() const { return _M_value; } + + private: + _ComplexT _M_value; + }; + + inline float& + complex<float>::real() + { return __real__ _M_value; } + + inline const float& + complex<float>::real() const + { return __real__ _M_value; } + + inline float& + complex<float>::imag() + { return __imag__ _M_value; } + + inline const float& + complex<float>::imag() const + { return __imag__ _M_value; } + + inline + complex<float>::complex(float r, float i) + { + __real__ _M_value = r; + __imag__ _M_value = i; + } + + inline complex<float>& + complex<float>::operator=(float __f) + { + __real__ _M_value = __f; + __imag__ _M_value = 0.0f; + return *this; + } + + inline complex<float>& + complex<float>::operator+=(float __f) + { + __real__ _M_value += __f; + return *this; + } + + inline complex<float>& + complex<float>::operator-=(float __f) + { + __real__ _M_value -= __f; + return *this; + } + + inline complex<float>& + complex<float>::operator*=(float __f) + { + _M_value *= __f; + return *this; + } + + inline complex<float>& + complex<float>::operator/=(float __f) + { + _M_value /= __f; + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // 26.2.3 complex specializations + // complex<double> specialization + template<> + struct complex<double> + { + typedef double value_type; + typedef __complex__ double _ComplexT; + + complex(_ComplexT __z) : _M_value(__z) { } + + complex(double = 0.0, double = 0.0); + + complex(const complex<float>&); + explicit complex(const complex<long double>&); + + double& real(); + const double& real() const; + double& imag(); + const double& imag() const; + + complex<double>& operator=(double); + complex<double>& operator+=(double); + complex<double>& operator-=(double); + complex<double>& operator*=(double); + complex<double>& operator/=(double); + + // The compiler will synthetize this, efficiently. + // complex& operator= (const complex&); + template<typename _Tp> + complex<double>& operator=(const complex<_Tp>&); + template<typename _Tp> + complex<double>& operator+=(const complex<_Tp>&); + template<typename _Tp> + complex<double>& operator-=(const complex<_Tp>&); + template<typename _Tp> + complex<double>& operator*=(const complex<_Tp>&); + template<typename _Tp> + complex<double>& operator/=(const complex<_Tp>&); + + const _ComplexT& __rep() const { return _M_value; } + + private: + _ComplexT _M_value; + }; + + inline double& + complex<double>::real() + { return __real__ _M_value; } + + inline const double& + complex<double>::real() const + { return __real__ _M_value; } + + inline double& + complex<double>::imag() + { return __imag__ _M_value; } + + inline const double& + complex<double>::imag() const + { return __imag__ _M_value; } + + inline + complex<double>::complex(double __r, double __i) + { + __real__ _M_value = __r; + __imag__ _M_value = __i; + } + + inline complex<double>& + complex<double>::operator=(double __d) + { + __real__ _M_value = __d; + __imag__ _M_value = 0.0; + return *this; + } + + inline complex<double>& + complex<double>::operator+=(double __d) + { + __real__ _M_value += __d; + return *this; + } + + inline complex<double>& + complex<double>::operator-=(double __d) + { + __real__ _M_value -= __d; + return *this; + } + + inline complex<double>& + complex<double>::operator*=(double __d) + { + _M_value *= __d; + return *this; + } + + inline complex<double>& + complex<double>::operator/=(double __d) + { + _M_value /= __d; + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // 26.2.3 complex specializations + // complex<long double> specialization + template<> + struct complex<long double> + { + typedef long double value_type; + typedef __complex__ long double _ComplexT; + + complex(_ComplexT __z) : _M_value(__z) { } + + complex(long double = 0.0L, long double = 0.0L); + + complex(const complex<float>&); + complex(const complex<double>&); + + long double& real(); + const long double& real() const; + long double& imag(); + const long double& imag() const; + + complex<long double>& operator= (long double); + complex<long double>& operator+= (long double); + complex<long double>& operator-= (long double); + complex<long double>& operator*= (long double); + complex<long double>& operator/= (long double); + + // The compiler knows how to do this efficiently + // complex& operator= (const complex&); + template<typename _Tp> + complex<long double>& operator=(const complex<_Tp>&); + template<typename _Tp> + complex<long double>& operator+=(const complex<_Tp>&); + template<typename _Tp> + complex<long double>& operator-=(const complex<_Tp>&); + template<typename _Tp> + complex<long double>& operator*=(const complex<_Tp>&); + template<typename _Tp> + complex<long double>& operator/=(const complex<_Tp>&); + + const _ComplexT& __rep() const { return _M_value; } + + private: + _ComplexT _M_value; + }; + + inline + complex<long double>::complex(long double __r, long double __i) + { + __real__ _M_value = __r; + __imag__ _M_value = __i; + } + + inline long double& + complex<long double>::real() + { return __real__ _M_value; } + + inline const long double& + complex<long double>::real() const + { return __real__ _M_value; } + + inline long double& + complex<long double>::imag() + { return __imag__ _M_value; } + + inline const long double& + complex<long double>::imag() const + { return __imag__ _M_value; } + + inline complex<long double>& + complex<long double>::operator=(long double __r) + { + __real__ _M_value = __r; + __imag__ _M_value = 0.0L; + return *this; + } + + inline complex<long double>& + complex<long double>::operator+=(long double __r) + { + __real__ _M_value += __r; + return *this; + } + + inline complex<long double>& + complex<long double>::operator-=(long double __r) + { + __real__ _M_value -= __r; + return *this; + } + + inline complex<long double>& + complex<long double>::operator*=(long double __r) + { + _M_value *= __r; + return *this; + } + + inline complex<long double>& + complex<long double>::operator/=(long double __r) + { + _M_value /= __r; + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // These bits have to be at the end of this file, so that the + // specializations have all been defined. + // ??? No, they have to be there because of compiler limitation at + // inlining. It suffices that class specializations be defined. + inline + complex<float>::complex(const complex<double>& __z) + : _M_value(__z.__rep()) { } + + inline + complex<float>::complex(const complex<long double>& __z) + : _M_value(__z.__rep()) { } + + inline + complex<double>::complex(const complex<float>& __z) + : _M_value(__z.__rep()) { } + + inline + complex<double>::complex(const complex<long double>& __z) + : _M_value(__z.__rep()) { } + + inline + complex<long double>::complex(const complex<float>& __z) + : _M_value(__z.__rep()) { } + + inline + complex<long double>::complex(const complex<double>& __z) + : _M_value(__z.__rep()) { } + +_GLIBCXX_END_NAMESPACE + +#endif /* _GLIBCXX_COMPLEX */ diff --git a/libstdc++/include/std/std_deque.h b/libstdc++/include/std/std_deque.h new file mode 100644 index 0000000..57c6e43 --- /dev/null +++ b/libstdc++/include/std/std_deque.h @@ -0,0 +1,80 @@ +// <deque> -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/deque + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_DEQUE +#define _GLIBCXX_DEQUE 1 + +#pragma GCC system_header + +#include <bits/functexcept.h> +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_deque.h> + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/deque.tcc> +#endif + +#ifdef _GLIBCXX_DEBUG +# include <debug/deque> +#endif + +#endif /* _GLIBCXX_DEQUE */ diff --git a/libstdc++/include/std/std_fstream.h b/libstdc++/include/std/std_fstream.h new file mode 100644 index 0000000..0c81633 --- /dev/null +++ b/libstdc++/include/std/std_fstream.h @@ -0,0 +1,808 @@ +// File based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, +// 2006, 2007 +// 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. + +/** @file fstream + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 27.8 File-based streams +// + +#ifndef _GLIBCXX_FSTREAM +#define _GLIBCXX_FSTREAM 1 + +#pragma GCC system_header + +#include <istream> +#include <ostream> +#include <locale> // For codecvt +#include <cstdio> // For SEEK_SET, SEEK_CUR, SEEK_END, BUFSIZ +#include <bits/basic_file.h> +#include <bits/gthr.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // [27.8.1.1] template class basic_filebuf + /** + * @brief The actual work of input and output (for files). + * + * This class associates both its input and output sequence with an + * external disk file, and maintains a joint file position for both + * sequences. Many of its sematics are described in terms of similar + * behavior in the Standard C Library's @c FILE streams. + */ + // Requirements on traits_type, specific to this class: + // traits_type::pos_type must be fpos<traits_type::state_type> + // traits_type::off_type must be streamoff + // traits_type::state_type must be Assignable and DefaultConstructable, + // and traits_type::state_type() must be the initial state for codecvt. + template<typename _CharT, typename _Traits> + class basic_filebuf : public basic_streambuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + typedef basic_streambuf<char_type, traits_type> __streambuf_type; + typedef basic_filebuf<char_type, traits_type> __filebuf_type; + typedef __basic_file<char> __file_type; + typedef typename traits_type::state_type __state_type; + typedef codecvt<char_type, char, __state_type> __codecvt_type; + + friend class ios_base; // For sync_with_stdio. + + protected: + // Data Members: + // MT lock inherited from libio or other low-level io library. + __c_lock _M_lock; + + // External buffer. + __file_type _M_file; + + /** + * @if maint + * Place to stash in || out || in | out settings for current filebuf. + * @endif + */ + ios_base::openmode _M_mode; + + // Beginning state type for codecvt. + __state_type _M_state_beg; + + // During output, the state that corresponds to pptr(), + // during input, the state that corresponds to egptr() and + // _M_ext_next. + __state_type _M_state_cur; + + // Not used for output. During input, the state that corresponds + // to eback() and _M_ext_buf. + __state_type _M_state_last; + + /** + * @if maint + * Pointer to the beginning of internal buffer. + * @endif + */ + char_type* _M_buf; + + /** + * @if maint + * Actual size of internal buffer. This number is equal to the size + * of the put area + 1 position, reserved for the overflow char of + * a full area. + * @endif + */ + size_t _M_buf_size; + + // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. + bool _M_buf_allocated; + + /** + * @if maint + * _M_reading == false && _M_writing == false for 'uncommitted' mode; + * _M_reading == true for 'read' mode; + * _M_writing == true for 'write' mode; + * + * NB: _M_reading == true && _M_writing == true is unused. + * @endif + */ + bool _M_reading; + bool _M_writing; + + //@{ + /** + * @if maint + * Necessary bits for putback buffer management. + * + * @note pbacks of over one character are not currently supported. + * @endif + */ + char_type _M_pback; + char_type* _M_pback_cur_save; + char_type* _M_pback_end_save; + bool _M_pback_init; + //@} + + // Cached codecvt facet. + const __codecvt_type* _M_codecvt; + + /** + * @if maint + * Buffer for external characters. Used for input when + * codecvt::always_noconv() == false. When valid, this corresponds + * to eback(). + * @endif + */ + char* _M_ext_buf; + + /** + * @if maint + * Size of buffer held by _M_ext_buf. + * @endif + */ + streamsize _M_ext_buf_size; + + /** + * @if maint + * Pointers into the buffer held by _M_ext_buf that delimit a + * subsequence of bytes that have been read but not yet converted. + * When valid, _M_ext_next corresponds to egptr(). + * @endif + */ + const char* _M_ext_next; + char* _M_ext_end; + + /** + * @if maint + * Initializes pback buffers, and moves normal buffers to safety. + * Assumptions: + * _M_in_cur has already been moved back + * @endif + */ + void + _M_create_pback() + { + if (!_M_pback_init) + { + _M_pback_cur_save = this->gptr(); + _M_pback_end_save = this->egptr(); + this->setg(&_M_pback, &_M_pback, &_M_pback + 1); + _M_pback_init = true; + } + } + + /** + * @if maint + * Deactivates pback buffer contents, and restores normal buffer. + * Assumptions: + * The pback buffer has only moved forward. + * @endif + */ + void + _M_destroy_pback() throw() + { + if (_M_pback_init) + { + // Length _M_in_cur moved in the pback buffer. + _M_pback_cur_save += this->gptr() != this->eback(); + this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); + _M_pback_init = false; + } + } + + public: + // Constructors/destructor: + /** + * @brief Does not open any files. + * + * The default constructor initializes the parent class using its + * own default ctor. + */ + basic_filebuf(); + + /** + * @brief The destructor closes the file first. + */ + virtual + ~basic_filebuf() + { this->close(); } + + // Members: + /** + * @brief Returns true if the external file is open. + */ + bool + is_open() const throw() + { return _M_file.is_open(); } + + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * @return @c this on success, NULL on failure + * + * If a file is already open, this function immediately fails. + * Otherwise it tries to open the file named @a s using the flags + * given in @a mode. + * + * Table 92, adapted here, gives the relation between openmode + * combinations and the equivalent fopen() flags. + * (NB: lines in|out|app and binary|in|out|app per DR 596) + * +---------------------------------------------------------+ + * | ios_base Flag combination stdio equivalent | + * |binary in out trunc app | + * +---------------------------------------------------------+ + * | + "w" | + * | + + "a" | + * | + + "w" | + * | + "r" | + * | + + "r+" | + * | + + + "w+" | + * | + + + "a+" | + * +---------------------------------------------------------+ + * | + + "wb" | + * | + + + "ab" | + * | + + + "wb" | + * | + + "rb" | + * | + + + "r+b" | + * | + + + + "w+b" | + * | + + + + "a+b" | + * +---------------------------------------------------------+ + */ + __filebuf_type* + open(const char* __s, ios_base::openmode __mode); + + /** + * @brief Closes the currently associated file. + * @return @c this on success, NULL on failure + * + * If no file is currently open, this function immediately fails. + * + * If a "put buffer area" exists, @c overflow(eof) is called to flush + * all the characters. The file is then closed. + * + * If any operations fail, this function also fails. + */ + __filebuf_type* + close() throw(); + + protected: + void + _M_allocate_internal_buffer(); + + void + _M_destroy_internal_buffer() throw(); + + // [27.8.1.4] overridden virtual functions + virtual streamsize + showmanyc(); + + // Stroustrup, 1998, p. 628 + // underflow() and uflow() functions are called to get the next + // charater from the real input source when the buffer is empty. + // Buffered input uses underflow() + + virtual int_type + underflow(); + + virtual int_type + pbackfail(int_type __c = _Traits::eof()); + + // Stroustrup, 1998, p 648 + // The overflow() function is called to transfer characters to the + // real output destination when the buffer is full. A call to + // overflow(c) outputs the contents of the buffer plus the + // character c. + // 27.5.2.4.5 + // Consume some sequence of the characters in the pending sequence. + virtual int_type + overflow(int_type __c = _Traits::eof()); + + // Convert internal byte sequence to external, char-based + // sequence via codecvt. + bool + _M_convert_to_external(char_type*, streamsize); + + /** + * @brief Manipulates the buffer. + * @param s Pointer to a buffer area. + * @param n Size of @a s. + * @return @c this + * + * If no file has been opened, and both @a s and @a n are zero, then + * the stream becomes unbuffered. Otherwise, @c s is used as a + * buffer; see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 + * for more. + */ + virtual __streambuf_type* + setbuf(char_type* __s, streamsize __n); + + virtual pos_type + seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + virtual pos_type + seekpos(pos_type __pos, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + // Common code for seekoff and seekpos + pos_type + _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); + + virtual int + sync(); + + virtual void + imbue(const locale& __loc); + + virtual streamsize + xsgetn(char_type* __s, streamsize __n); + + virtual streamsize + xsputn(const char_type* __s, streamsize __n); + + // Flushes output buffer, then writes unshift sequence. + bool + _M_terminate_output(); + + /** + * @if maint + * This function sets the pointers of the internal buffer, both get + * and put areas. Typically: + * + * __off == egptr() - eback() upon underflow/uflow ('read' mode); + * __off == 0 upon overflow ('write' mode); + * __off == -1 upon open, setbuf, seekoff/pos ('uncommitted' mode). + * + * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size + * reflects the actual allocated memory and the last cell is reserved + * for the overflow char of a full put area. + * @endif + */ + void + _M_set_buffer(streamsize __off) + { + const bool __testin = _M_mode & ios_base::in; + const bool __testout = _M_mode & ios_base::out; + + if (__testin && __off > 0) + this->setg(_M_buf, _M_buf, _M_buf + __off); + else + this->setg(_M_buf, _M_buf, _M_buf); + + if (__testout && __off == 0 && _M_buf_size > 1 ) + this->setp(_M_buf, _M_buf + _M_buf_size - 1); + else + this->setp(NULL, NULL); + } + }; + + // [27.8.1.5] Template class basic_ifstream + /** + * @brief Controlling input for files. + * + * This class supports reading from named files, using the inherited + * functions from std::basic_istream. To control the associated + * sequence, an instance of std::basic_filebuf is used, which this page + * refers to as @c sb. + */ + template<typename _CharT, typename _Traits> + class basic_ifstream : public basic_istream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_filebuf<char_type, traits_type> __filebuf_type; + typedef basic_istream<char_type, traits_type> __istream_type; + + private: + __filebuf_type _M_filebuf; + + public: + // Constructors/Destructors: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + basic_ifstream() : __istream_type(), _M_filebuf() + { this->init(&_M_filebuf); } + + /** + * @brief Create an input file stream. + * @param s Null terminated string specifying the filename. + * @param mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::in is automatically included in @a mode. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + explicit + basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) + : __istream_type(), _M_filebuf() + { + this->init(&_M_filebuf); + this->open(__s, __mode); + } + + /** + * @brief The destructor does nothing. + * + * The file is closed by the filebuf object, not the formatting + * stream. + */ + ~basic_ifstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_filebuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __filebuf_type* + rdbuf() const + { return const_cast<__filebuf_type*>(&_M_filebuf); } + + /** + * @brief Wrapper to test for an open file. + * @return @c rdbuf()->is_open() + */ + bool + is_open() + { return _M_filebuf.is_open(); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 365. Lack of const-qualification in clause 27 + bool + is_open() const + { return _M_filebuf.is_open(); } + + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * + * Calls @c std::basic_filebuf::open(s,mode|in). If that function + * fails, @c failbit is set in the stream's error state. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + void + open(const char* __s, ios_base::openmode __mode = ios_base::in) + { + if (!_M_filebuf.open(__s, __mode | ios_base::in)) + this->setstate(ios_base::failbit); + else + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 409. Closing an fstream should clear error state + this->clear(); + } + + /** + * @brief Close the file. + * + * Calls @c std::basic_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void + close() + { + if (!_M_filebuf.close()) + this->setstate(ios_base::failbit); + } + }; + + + // [27.8.1.8] Template class basic_ofstream + /** + * @brief Controlling output for files. + * + * This class supports reading from named files, using the inherited + * functions from std::basic_ostream. To control the associated + * sequence, an instance of std::basic_filebuf is used, which this page + * refers to as @c sb. + */ + template<typename _CharT, typename _Traits> + class basic_ofstream : public basic_ostream<_CharT,_Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_filebuf<char_type, traits_type> __filebuf_type; + typedef basic_ostream<char_type, traits_type> __ostream_type; + + private: + __filebuf_type _M_filebuf; + + public: + // Constructors: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + basic_ofstream(): __ostream_type(), _M_filebuf() + { this->init(&_M_filebuf); } + + /** + * @brief Create an output file stream. + * @param s Null terminated string specifying the filename. + * @param mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::out|ios_base::trunc is automatically included in + * @a mode. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + explicit + basic_ofstream(const char* __s, + ios_base::openmode __mode = ios_base::out|ios_base::trunc) + : __ostream_type(), _M_filebuf() + { + this->init(&_M_filebuf); + this->open(__s, __mode); + } + + /** + * @brief The destructor does nothing. + * + * The file is closed by the filebuf object, not the formatting + * stream. + */ + ~basic_ofstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_filebuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __filebuf_type* + rdbuf() const + { return const_cast<__filebuf_type*>(&_M_filebuf); } + + /** + * @brief Wrapper to test for an open file. + * @return @c rdbuf()->is_open() + */ + bool + is_open() + { return _M_filebuf.is_open(); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 365. Lack of const-qualification in clause 27 + bool + is_open() const + { return _M_filebuf.is_open(); } + + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * + * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that + * function fails, @c failbit is set in the stream's error state. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + void + open(const char* __s, + ios_base::openmode __mode = ios_base::out | ios_base::trunc) + { + if (!_M_filebuf.open(__s, __mode | ios_base::out)) + this->setstate(ios_base::failbit); + else + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 409. Closing an fstream should clear error state + this->clear(); + } + + /** + * @brief Close the file. + * + * Calls @c std::basic_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void + close() + { + if (!_M_filebuf.close()) + this->setstate(ios_base::failbit); + } + }; + + + // [27.8.1.11] Template class basic_fstream + /** + * @brief Controlling intput and output for files. + * + * This class supports reading from and writing to named files, using + * the inherited functions from std::basic_iostream. To control the + * associated sequence, an instance of std::basic_filebuf is used, which + * this page refers to as @c sb. + */ + template<typename _CharT, typename _Traits> + class basic_fstream : public basic_iostream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_filebuf<char_type, traits_type> __filebuf_type; + typedef basic_ios<char_type, traits_type> __ios_type; + typedef basic_iostream<char_type, traits_type> __iostream_type; + + private: + __filebuf_type _M_filebuf; + + public: + // Constructors/destructor: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + basic_fstream() + : __iostream_type(), _M_filebuf() + { this->init(&_M_filebuf); } + + /** + * @brief Create an input/output file stream. + * @param s Null terminated string specifying the filename. + * @param mode Open file in specified mode (see std::ios_base). + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + explicit + basic_fstream(const char* __s, + ios_base::openmode __mode = ios_base::in | ios_base::out) + : __iostream_type(NULL), _M_filebuf() + { + this->init(&_M_filebuf); + this->open(__s, __mode); + } + + /** + * @brief The destructor does nothing. + * + * The file is closed by the filebuf object, not the formatting + * stream. + */ + ~basic_fstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_filebuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __filebuf_type* + rdbuf() const + { return const_cast<__filebuf_type*>(&_M_filebuf); } + + /** + * @brief Wrapper to test for an open file. + * @return @c rdbuf()->is_open() + */ + bool + is_open() + { return _M_filebuf.is_open(); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 365. Lack of const-qualification in clause 27 + bool + is_open() const + { return _M_filebuf.is_open(); } + + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * + * Calls @c std::basic_filebuf::open(s,mode). If that + * function fails, @c failbit is set in the stream's error state. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + void + open(const char* __s, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { + if (!_M_filebuf.open(__s, __mode)) + this->setstate(ios_base::failbit); + else + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 409. Closing an fstream should clear error state + this->clear(); + } + + /** + * @brief Close the file. + * + * Calls @c std::basic_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void + close() + { + if (!_M_filebuf.close()) + this->setstate(ios_base::failbit); + } + }; + +_GLIBCXX_END_NAMESPACE + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/fstream.tcc> +#endif + +#endif /* _GLIBCXX_FSTREAM */ diff --git a/libstdc++/include/std/std_functional.h b/libstdc++/include/std/std_functional.h new file mode 100644 index 0000000..feadaa2 --- /dev/null +++ b/libstdc++/include/std/std_functional.h @@ -0,0 +1,57 @@ +// <functional> -*- C++ -*- + +// Copyright (C) 2001, 2002 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. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file include/functional + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_FUNCTIONAL +#define _GLIBCXX_FUNCTIONAL 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <cstddef> +#include <bits/stl_function.h> + +#endif /* _GLIBCXX_FUNCTIONAL */ diff --git a/libstdc++/include/std/std_iomanip.h b/libstdc++/include/std/std_iomanip.h new file mode 100644 index 0000000..13b21d5 --- /dev/null +++ b/libstdc++/include/std/std_iomanip.h @@ -0,0 +1,300 @@ +// Standard stream manipulators -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 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. + +/** @file iomanip + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 27.6.3 Standard manipulators +// + +#ifndef _GLIBCXX_IOMANIP +#define _GLIBCXX_IOMANIP 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <istream> +#include <functional> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // [27.6.3] standard manipulators + // Also see DR 183. + + struct _Resetiosflags { ios_base::fmtflags _M_mask; }; + + /** + * @brief Manipulator for @c setf. + * @param mask A format flags mask. + * + * Sent to a stream object, this manipulator resets the specified flags, + * via @e stream.setf(0,mask). + */ + inline _Resetiosflags + resetiosflags(ios_base::fmtflags __mask) + { + _Resetiosflags __x; + __x._M_mask = __mask; + return __x; + } + + template<typename _CharT, typename _Traits> + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Resetiosflags __f) + { + __is.setf(ios_base::fmtflags(0), __f._M_mask); + return __is; + } + + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Resetiosflags __f) + { + __os.setf(ios_base::fmtflags(0), __f._M_mask); + return __os; + } + + + struct _Setiosflags { ios_base::fmtflags _M_mask; }; + + /** + * @brief Manipulator for @c setf. + * @param mask A format flags mask. + * + * Sent to a stream object, this manipulator sets the format flags + * to @a mask. + */ + inline _Setiosflags + setiosflags(ios_base::fmtflags __mask) + { + _Setiosflags __x; + __x._M_mask = __mask; + return __x; + } + + template<typename _CharT, typename _Traits> + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setiosflags __f) + { + __is.setf(__f._M_mask); + return __is; + } + + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setiosflags __f) + { + __os.setf(__f._M_mask); + return __os; + } + + + struct _Setbase { int _M_base; }; + + /** + * @brief Manipulator for @c setf. + * @param base A numeric base. + * + * Sent to a stream object, this manipulator changes the + * @c ios_base::basefield flags to @c oct, @c dec, or @c hex when @a base + * is 8, 10, or 16, accordingly, and to 0 if @a base is any other value. + */ + inline _Setbase + setbase(int __base) + { + _Setbase __x; + __x._M_base = __base; + return __x; + } + + template<typename _CharT, typename _Traits> + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setbase __f) + { + __is.setf(__f._M_base == 8 ? ios_base::oct : + __f._M_base == 10 ? ios_base::dec : + __f._M_base == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __is; + } + + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setbase __f) + { + __os.setf(__f._M_base == 8 ? ios_base::oct : + __f._M_base == 10 ? ios_base::dec : + __f._M_base == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __os; + } + + + template<typename _CharT> + struct _Setfill { _CharT _M_c; }; + + /** + * @brief Manipulator for @c fill. + * @param c The new fill character. + * + * Sent to a stream object, this manipulator calls @c fill(c) for that + * object. + */ + template<typename _CharT> + inline _Setfill<_CharT> + setfill(_CharT __c) + { + _Setfill<_CharT> __x; + __x._M_c = __c; + return __x; + } + + template<typename _CharT, typename _Traits> + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setfill<_CharT> __f) + { + __is.fill(__f._M_c); + return __is; + } + + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setfill<_CharT> __f) + { + __os.fill(__f._M_c); + return __os; + } + + + struct _Setprecision { int _M_n; }; + + /** + * @brief Manipulator for @c precision. + * @param n The new precision. + * + * Sent to a stream object, this manipulator calls @c precision(n) for + * that object. + */ + inline _Setprecision + setprecision(int __n) + { + _Setprecision __x; + __x._M_n = __n; + return __x; + } + + template<typename _CharT, typename _Traits> + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setprecision __f) + { + __is.precision(__f._M_n); + return __is; + } + + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setprecision __f) + { + __os.precision(__f._M_n); + return __os; + } + + + struct _Setw { int _M_n; }; + + /** + * @brief Manipulator for @c width. + * @param n The new width. + * + * Sent to a stream object, this manipulator calls @c width(n) for + * that object. + */ + inline _Setw + setw(int __n) + { + _Setw __x; + __x._M_n = __n; + return __x; + } + + template<typename _CharT, typename _Traits> + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setw __f) + { + __is.width(__f._M_n); + return __is; + } + + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setw __f) + { + __os.width(__f._M_n); + return __os; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template ostream& operator<<(ostream&, _Setfill<char>); + extern template ostream& operator<<(ostream&, _Setiosflags); + extern template ostream& operator<<(ostream&, _Resetiosflags); + extern template ostream& operator<<(ostream&, _Setbase); + extern template ostream& operator<<(ostream&, _Setprecision); + extern template ostream& operator<<(ostream&, _Setw); + extern template istream& operator>>(istream&, _Setfill<char>); + extern template istream& operator>>(istream&, _Setiosflags); + extern template istream& operator>>(istream&, _Resetiosflags); + extern template istream& operator>>(istream&, _Setbase); + extern template istream& operator>>(istream&, _Setprecision); + extern template istream& operator>>(istream&, _Setw); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template wostream& operator<<(wostream&, _Setfill<wchar_t>); + extern template wostream& operator<<(wostream&, _Setiosflags); + extern template wostream& operator<<(wostream&, _Resetiosflags); + extern template wostream& operator<<(wostream&, _Setbase); + extern template wostream& operator<<(wostream&, _Setprecision); + extern template wostream& operator<<(wostream&, _Setw); + extern template wistream& operator>>(wistream&, _Setfill<wchar_t>); + extern template wistream& operator>>(wistream&, _Setiosflags); + extern template wistream& operator>>(wistream&, _Resetiosflags); + extern template wistream& operator>>(wistream&, _Setbase); + extern template wistream& operator>>(wistream&, _Setprecision); + extern template wistream& operator>>(wistream&, _Setw); +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _GLIBCXX_IOMANIP */ diff --git a/libstdc++/include/std/std_ios.h b/libstdc++/include/std/std_ios.h new file mode 100644 index 0000000..f081115 --- /dev/null +++ b/libstdc++/include/std/std_ios.h @@ -0,0 +1,52 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002 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. + +/** @file ios + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 27.4 Iostreams base classes +// + +#ifndef _GLIBCXX_IOS +#define _GLIBCXX_IOS 1 + +#pragma GCC system_header + +#include <iosfwd> +#include <exception> // For ios_base::failure +#include <bits/char_traits.h> // For char_traits, streamoff, streamsize, fpos +#include <cstdio> // For SEEK_SET, SEEK_CUR, SEEK_END +#include <bits/localefwd.h> // For class locale +#include <bits/ios_base.h> // For ios_base declarations. +#include <streambuf> +#include <bits/basic_ios.h> + +#endif /* _GLIBCXX_IOS */ diff --git a/libstdc++/include/std/std_iosfwd.h b/libstdc++/include/std/std_iosfwd.h new file mode 100644 index 0000000..a4d0c3f --- /dev/null +++ b/libstdc++/include/std/std_iosfwd.h @@ -0,0 +1,168 @@ +// Forwarding declarations -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 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. + +/** @file iosfwd + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 27.2 Forward declarations +// + +#ifndef _GLIBCXX_IOSFWD +#define _GLIBCXX_IOSFWD 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/c++locale.h> +#include <bits/c++io.h> +#include <cctype> // For isspace, etc. +#include <bits/stringfwd.h> // For string forward declarations. +#include <bits/postypes.h> +#include <bits/functexcept.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_ios; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_streambuf; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_istream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_ostream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_iostream; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_stringbuf; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_istringstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_ostringstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_stringstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_filebuf; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_ifstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_ofstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_fstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class istreambuf_iterator; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class ostreambuf_iterator; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // Not included. (??? Apparently no LWG number?) + class ios_base; + + /** + * @defgroup s27_2_iosfwd I/O Forward Declarations + * + * Nearly all of the I/O classes are parameterized on the type of + * characters they read and write. (The major exception is ios_base at + * the top of the hierarchy.) This is a change from pre-Standard + * streams, which were not templates. + * + * For ease of use and compatibility, all of the basic_* I/O-related + * classes are given typedef names for both of the builtin character + * widths (wide and narrow). The typedefs are the same as the + * pre-Standard names, for example: + * + * @code + * typedef basic_ifstream<char> ifstream; + * @endcode + * + * Because properly forward-declaring these classes can be difficult, you + * should not do it yourself. Instead, include the <iosfwd> + * header, which contains only declarations of all the I/O classes as + * well as the typedefs. Trying to forward-declare the typedefs + * themselves (e.g., "class ostream;") is not valid ISO C++. + * + * For more specific declarations, see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#10 + * + * @{ + */ + typedef basic_ios<char> ios; ///< @isiosfwd + typedef basic_streambuf<char> streambuf; ///< @isiosfwd + typedef basic_istream<char> istream; ///< @isiosfwd + typedef basic_ostream<char> ostream; ///< @isiosfwd + typedef basic_iostream<char> iostream; ///< @isiosfwd + typedef basic_stringbuf<char> stringbuf; ///< @isiosfwd + typedef basic_istringstream<char> istringstream; ///< @isiosfwd + typedef basic_ostringstream<char> ostringstream; ///< @isiosfwd + typedef basic_stringstream<char> stringstream; ///< @isiosfwd + typedef basic_filebuf<char> filebuf; ///< @isiosfwd + typedef basic_ifstream<char> ifstream; ///< @isiosfwd + typedef basic_ofstream<char> ofstream; ///< @isiosfwd + typedef basic_fstream<char> fstream; ///< @isiosfwd + +#ifdef _GLIBCXX_USE_WCHAR_T + typedef basic_ios<wchar_t> wios; ///< @isiosfwd + typedef basic_streambuf<wchar_t> wstreambuf; ///< @isiosfwd + typedef basic_istream<wchar_t> wistream; ///< @isiosfwd + typedef basic_ostream<wchar_t> wostream; ///< @isiosfwd + typedef basic_iostream<wchar_t> wiostream; ///< @isiosfwd + typedef basic_stringbuf<wchar_t> wstringbuf; ///< @isiosfwd + typedef basic_istringstream<wchar_t> wistringstream; ///< @isiosfwd + typedef basic_ostringstream<wchar_t> wostringstream; ///< @isiosfwd + typedef basic_stringstream<wchar_t> wstringstream; ///< @isiosfwd + typedef basic_filebuf<wchar_t> wfilebuf; ///< @isiosfwd + typedef basic_ifstream<wchar_t> wifstream; ///< @isiosfwd + typedef basic_ofstream<wchar_t> wofstream; ///< @isiosfwd + typedef basic_fstream<wchar_t> wfstream; ///< @isiosfwd +#endif + /** @} */ + +_GLIBCXX_END_NAMESPACE + +#endif /* _GLIBCXX_IOSFWD */ diff --git a/libstdc++/include/std/std_iostream.h b/libstdc++/include/std/std_iostream.h new file mode 100644 index 0000000..0ff0da2 --- /dev/null +++ b/libstdc++/include/std/std_iostream.h @@ -0,0 +1,81 @@ +// Standard iostream objects -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 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. + +/** @file iostream + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 27.3 Standard iostream objects +// + +#ifndef _GLIBCXX_IOSTREAM +#define _GLIBCXX_IOSTREAM 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <ostream> +#include <istream> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @name Standard Stream Objects + * + * The <iostream> header declares the eight <em>standard stream + * objects</em>. For other declarations, see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#10 and the + * @link s27_2_iosfwd I/O forward declarations @endlink + * + * They are required by default to cooperate with the global C library's + * @c FILE streams, and to be available during program startup and + * termination. For more information, see the HOWTO linked to above. + */ + //@{ + extern istream cin; ///< Linked to standard input + extern ostream cout; ///< Linked to standard output + extern ostream cerr; ///< Linked to standard error (unbuffered) + extern ostream clog; ///< Linked to standard error (buffered) + +#ifdef _GLIBCXX_USE_WCHAR_T + extern wistream wcin; ///< Linked to standard input + extern wostream wcout; ///< Linked to standard output + extern wostream wcerr; ///< Linked to standard error (unbuffered) + extern wostream wclog; ///< Linked to standard error (buffered) +#endif + //@} + + // For construction of filebuffers for cout, cin, cerr, clog et. al. + static ios_base::Init __ioinit; + +_GLIBCXX_END_NAMESPACE + +#endif /* _GLIBCXX_IOSTREAM */ diff --git a/libstdc++/include/std/std_istream.h b/libstdc++/include/std/std_istream.h new file mode 100644 index 0000000..e81c9cd --- /dev/null +++ b/libstdc++/include/std/std_istream.h @@ -0,0 +1,848 @@ +// Input streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +/** @file istream + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_ISTREAM +#define _GLIBCXX_ISTREAM 1 + +#pragma GCC system_header + +#include <ios> +#include <limits> // For numeric_limits + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // [27.6.1.1] Template class basic_istream + /** + * @brief Controlling input. + * + * This is the base class for all input streams. It provides text + * formatting of all builtin types, and communicates with any class + * derived from basic_streambuf to do the actual input. + */ + template<typename _CharT, typename _Traits> + class basic_istream : virtual public basic_ios<_CharT, _Traits> + { + public: + // Types (inherited from basic_ios (27.4.4)): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + // Non-standard Types: + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_ios<_CharT, _Traits> __ios_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > + __num_get_type; + typedef ctype<_CharT> __ctype_type; + + template<typename _CharT2, typename _Traits2> + friend basic_istream<_CharT2, _Traits2>& + operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2&); + + template<typename _CharT2, typename _Traits2> + friend basic_istream<_CharT2, _Traits2>& + operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); + + protected: + // Data Members: + /** + * @if maint + * The number of characters extracted in the previous unformatted + * function; see gcount(). + * @endif + */ + streamsize _M_gcount; + + public: + // [27.6.1.1.1] constructor/destructor + /** + * @brief Base constructor. + * + * This ctor is almost never called by the user directly, rather from + * derived classes' initialization lists, which pass a pointer to + * their own stream buffer. + */ + explicit + basic_istream(__streambuf_type* __sb): _M_gcount(streamsize(0)) + { this->init(__sb); } + + /** + * @brief Base destructor. + * + * This does very little apart from providing a virtual base dtor. + */ + virtual + ~basic_istream() + { _M_gcount = streamsize(0); } + + // [27.6.1.1.2] prefix/suffix + class sentry; + friend class sentry; + + // [27.6.1.2] formatted input + // [27.6.1.2.3] basic_istream::operator>> + //@{ + /** + * @brief Interface for manipulators. + * + * Manuipulators such as @c std::ws and @c std::dec use these + * functions in constructs like "std::cin >> std::ws". For more + * information, see the iomanip header. + */ + __istream_type& + operator>>(__istream_type& (*__pf)(__istream_type&)) + { return __pf(*this); } + + __istream_type& + operator>>(__ios_type& (*__pf)(__ios_type&)) + { + __pf(*this); + return *this; + } + + __istream_type& + operator>>(ios_base& (*__pf)(ios_base&)) + { + __pf(*this); + return *this; + } + //@} + + // [27.6.1.2.2] arithmetic extractors + /** + * @name Arithmetic Extractors + * + * All the @c operator>> functions (aka <em>formatted input + * functions</em>) have some common behavior. Each starts by + * constructing a temporary object of type std::basic_istream::sentry + * with the second argument (noskipws) set to false. This has several + * effects, concluding with the setting of a status flag; see the + * sentry documentation for more. + * + * If the sentry status is good, the function tries to extract + * whatever data is appropriate for the type of the argument. + * + * If an exception is thrown during extraction, ios_base::badbit + * will be turned on in the stream's error state without causing an + * ios_base::failure to be thrown. The original exception will then + * be rethrown. + */ + //@{ + /** + * @brief Basic arithmetic extractors + * @param A variable of builtin type. + * @return @c *this if successful + * + * These functions use the stream's current locale (specifically, the + * @c num_get facet) to parse the input data. + */ + __istream_type& + operator>>(bool& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(short& __n); + + __istream_type& + operator>>(unsigned short& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(int& __n); + + __istream_type& + operator>>(unsigned int& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(long& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(unsigned long& __n) + { return _M_extract(__n); } + +#ifdef _GLIBCXX_USE_LONG_LONG + __istream_type& + operator>>(long long& __n) + { return _M_extract(__n); } + + __istream_type& + operator>>(unsigned long long& __n) + { return _M_extract(__n); } +#endif + + __istream_type& + operator>>(float& __f) + { return _M_extract(__f); } + + __istream_type& + operator>>(double& __f) + { return _M_extract(__f); } + + __istream_type& + operator>>(long double& __f) + { return _M_extract(__f); } + + __istream_type& + operator>>(void*& __p) + { return _M_extract(__p); } + + /** + * @brief Extracting into another streambuf. + * @param sb A pointer to a streambuf + * + * This function behaves like one of the basic arithmetic extractors, + * in that it also constructs a sentry object and has the same error + * handling behavior. + * + * If @a sb is NULL, the stream will set failbit in its error state. + * + * Characters are extracted from this stream and inserted into the + * @a sb streambuf until one of the following occurs: + * + * - the input stream reaches end-of-file, + * - insertion into the output buffer fails (in this case, the + * character that would have been inserted is not extracted), or + * - an exception occurs (and in this case is caught) + * + * If the function inserts no characters, failbit is set. + */ + __istream_type& + operator>>(__streambuf_type* __sb); + //@} + + // [27.6.1.3] unformatted input + /** + * @brief Character counting + * @return The number of characters extracted by the previous + * unformatted input function dispatched for this stream. + */ + streamsize + gcount() const + { return _M_gcount; } + + /** + * @name Unformatted Input Functions + * + * All the unformatted input functions have some common behavior. + * Each starts by constructing a temporary object of type + * std::basic_istream::sentry with the second argument (noskipws) + * set to true. This has several effects, concluding with the + * setting of a status flag; see the sentry documentation for more. + * + * If the sentry status is good, the function tries to extract + * whatever data is appropriate for the type of the argument. + * + * The number of characters extracted is stored for later retrieval + * by gcount(). + * + * If an exception is thrown during extraction, ios_base::badbit + * will be turned on in the stream's error state without causing an + * ios_base::failure to be thrown. The original exception will then + * be rethrown. + */ + //@{ + /** + * @brief Simple extraction. + * @return A character, or eof(). + * + * Tries to extract a character. If none are available, sets failbit + * and returns traits::eof(). + */ + int_type + get(); + + /** + * @brief Simple extraction. + * @param c The character in which to store data. + * @return *this + * + * Tries to extract a character and store it in @a c. If none are + * available, sets failbit and returns traits::eof(). + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __istream_type& + get(char_type& __c); + + /** + * @brief Simple multiple-character extraction. + * @param s Pointer to an array. + * @param n Maximum number of characters to store in @a s. + * @param delim A "stop" character. + * @return *this + * + * Characters are extracted and stored into @a s until one of the + * following happens: + * + * - @c n-1 characters are stored + * - the input sequence reaches EOF + * - the next character equals @a delim, in which case the character + * is not extracted + * + * If no characters are stored, failbit is set in the stream's error + * state. + * + * In any case, a null character is stored into the next location in + * the array. + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __istream_type& + get(char_type* __s, streamsize __n, char_type __delim); + + /** + * @brief Simple multiple-character extraction. + * @param s Pointer to an array. + * @param n Maximum number of characters to store in @a s. + * @return *this + * + * Returns @c get(s,n,widen('\n')). + */ + __istream_type& + get(char_type* __s, streamsize __n) + { return this->get(__s, __n, this->widen('\n')); } + + /** + * @brief Extraction into another streambuf. + * @param sb A streambuf in which to store data. + * @param delim A "stop" character. + * @return *this + * + * Characters are extracted and inserted into @a sb until one of the + * following happens: + * + * - the input sequence reaches EOF + * - insertion into the output buffer fails (in this case, the + * character that would have been inserted is not extracted) + * - the next character equals @a delim (in this case, the character + * is not extracted) + * - an exception occurs (and in this case is caught) + * + * If no characters are stored, failbit is set in the stream's error + * state. + */ + __istream_type& + get(__streambuf_type& __sb, char_type __delim); + + /** + * @brief Extraction into another streambuf. + * @param sb A streambuf in which to store data. + * @return *this + * + * Returns @c get(sb,widen('\n')). + */ + __istream_type& + get(__streambuf_type& __sb) + { return this->get(__sb, this->widen('\n')); } + + /** + * @brief String extraction. + * @param s A character array in which to store the data. + * @param n Maximum number of characters to extract. + * @param delim A "stop" character. + * @return *this + * + * Extracts and stores characters into @a s until one of the + * following happens. Note that these criteria are required to be + * tested in the order listed here, to allow an input line to exactly + * fill the @a s array without setting failbit. + * + * -# the input sequence reaches end-of-file, in which case eofbit + * is set in the stream error state + * -# the next character equals @c delim, in which case the character + * is extracted (and therefore counted in @c gcount()) but not stored + * -# @c n-1 characters are stored, in which case failbit is set + * in the stream error state + * + * If no characters are extracted, failbit is set. (An empty line of + * input should therefore not cause failbit to be set.) + * + * In any case, a null character is stored in the next location in + * the array. + */ + __istream_type& + getline(char_type* __s, streamsize __n, char_type __delim); + + /** + * @brief String extraction. + * @param s A character array in which to store the data. + * @param n Maximum number of characters to extract. + * @return *this + * + * Returns @c getline(s,n,widen('\n')). + */ + __istream_type& + getline(char_type* __s, streamsize __n) + { return this->getline(__s, __n, this->widen('\n')); } + + /** + * @brief Discarding characters + * @param n Number of characters to discard. + * @param delim A "stop" character. + * @return *this + * + * Extracts characters and throws them away until one of the + * following happens: + * - if @a n @c != @c std::numeric_limits<int>::max(), @a n + * characters are extracted + * - the input sequence reaches end-of-file + * - the next character equals @a delim (in this case, the character + * is extracted); note that this condition will never occur if + * @a delim equals @c traits::eof(). + * + * NB: Provide three overloads, instead of the single function + * (with defaults) mandated by the Standard: this leads to a + * better performing implementation, while still conforming to + * the Standard. + */ + __istream_type& + ignore(); + + __istream_type& + ignore(streamsize __n); + + __istream_type& + ignore(streamsize __n, int_type __delim); + + /** + * @brief Looking ahead in the stream + * @return The next character, or eof(). + * + * If, after constructing the sentry object, @c good() is false, + * returns @c traits::eof(). Otherwise reads but does not extract + * the next input character. + */ + int_type + peek(); + + /** + * @brief Extraction without delimiters. + * @param s A character array. + * @param n Maximum number of characters to store. + * @return *this + * + * If the stream state is @c good(), extracts characters and stores + * them into @a s until one of the following happens: + * - @a n characters are stored + * - the input sequence reaches end-of-file, in which case the error + * state is set to @c failbit|eofbit. + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __istream_type& + read(char_type* __s, streamsize __n); + + /** + * @brief Extraction until the buffer is exhausted, but no more. + * @param s A character array. + * @param n Maximum number of characters to store. + * @return The number of characters extracted. + * + * Extracts characters and stores them into @a s depending on the + * number of characters remaining in the streambuf's buffer, + * @c rdbuf()->in_avail(), called @c A here: + * - if @c A @c == @c -1, sets eofbit and extracts no characters + * - if @c A @c == @c 0, extracts no characters + * - if @c A @c > @c 0, extracts @c min(A,n) + * + * The goal is to empty the current buffer, and to not request any + * more from the external input sequence controlled by the streambuf. + */ + streamsize + readsome(char_type* __s, streamsize __n); + + /** + * @brief Unextracting a single character. + * @param c The character to push back into the input stream. + * @return *this + * + * If @c rdbuf() is not null, calls @c rdbuf()->sputbackc(c). + * + * If @c rdbuf() is null or if @c sputbackc() fails, sets badbit in + * the error state. + * + * @note Since no characters are extracted, the next call to + * @c gcount() will return 0, as required by DR 60. + */ + __istream_type& + putback(char_type __c); + + /** + * @brief Unextracting the previous character. + * @return *this + * + * If @c rdbuf() is not null, calls @c rdbuf()->sungetc(c). + * + * If @c rdbuf() is null or if @c sungetc() fails, sets badbit in + * the error state. + * + * @note Since no characters are extracted, the next call to + * @c gcount() will return 0, as required by DR 60. + */ + __istream_type& + unget(); + + /** + * @brief Synchronizing the stream buffer. + * @return 0 on success, -1 on failure + * + * If @c rdbuf() is a null pointer, returns -1. + * + * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, + * sets badbit and returns -1. + * + * Otherwise, returns 0. + * + * @note This function does not count the number of characters + * extracted, if any, and therefore does not affect the next + * call to @c gcount(). + */ + int + sync(); + + /** + * @brief Getting the current read position. + * @return A file position object. + * + * If @c fail() is not false, returns @c pos_type(-1) to indicate + * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,in). + * + * @note This function does not count the number of characters + * extracted, if any, and therefore does not affect the next + * call to @c gcount(). + */ + pos_type + tellg(); + + /** + * @brief Changing the current read position. + * @param pos A file position object. + * @return *this + * + * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If + * that function fails, sets failbit. + * + * @note This function does not count the number of characters + * extracted, if any, and therefore does not affect the next + * call to @c gcount(). + */ + __istream_type& + seekg(pos_type); + + /** + * @brief Changing the current read position. + * @param off A file offset object. + * @param dir The direction in which to seek. + * @return *this + * + * If @c fail() is not true, calls @c rdbuf()->pubseekoff(off,dir). + * If that function fails, sets failbit. + * + * @note This function does not count the number of characters + * extracted, if any, and therefore does not affect the next + * call to @c gcount(). + */ + __istream_type& + seekg(off_type, ios_base::seekdir); + //@} + + protected: + explicit + basic_istream(): _M_gcount(streamsize(0)) { } + + template<typename _ValueT> + __istream_type& + _M_extract(_ValueT& __v); + }; + + // Explicit specialization declarations, defined in src/istream.cc. + template<> + basic_istream<char>& + basic_istream<char>:: + getline(char_type* __s, streamsize __n, char_type __delim); + + template<> + basic_istream<char>& + basic_istream<char>:: + ignore(streamsize __n); + + template<> + basic_istream<char>& + basic_istream<char>:: + ignore(streamsize __n, int_type __delim); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + basic_istream<wchar_t>& + basic_istream<wchar_t>:: + getline(char_type* __s, streamsize __n, char_type __delim); + + template<> + basic_istream<wchar_t>& + basic_istream<wchar_t>:: + ignore(streamsize __n); + + template<> + basic_istream<wchar_t>& + basic_istream<wchar_t>:: + ignore(streamsize __n, int_type __delim); +#endif + + /** + * @brief Performs setup work for input streams. + * + * Objects of this class are created before all of the standard + * extractors are run. It is responsible for "exception-safe prefix and + * suffix operations," although only prefix actions are currently required + * by the standard. Additional actions may be added by the + * implementation, and we list them in + * http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/howto.html#5 + * under [27.6] notes. + */ + template<typename _CharT, typename _Traits> + class basic_istream<_CharT, _Traits>::sentry + { + public: + /// Easy access to dependant types. + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef typename _Traits::int_type __int_type; + + /** + * @brief The constructor performs all the work. + * @param is The input stream to guard. + * @param noskipws Whether to consume whitespace or not. + * + * If the stream state is good (@a is.good() is true), then the + * following actions are performed, otherwise the sentry state is + * false ("not okay") and failbit is set in the stream state. + * + * The sentry's preparatory actions are: + * + * -# if the stream is tied to an output stream, @c is.tie()->flush() + * is called to synchronize the output sequence + * -# if @a noskipws is false, and @c ios_base::skipws is set in + * @c is.flags(), the sentry extracts and discards whitespace + * characters from the stream. The currently imbued locale is + * used to determine whether each character is whitespace. + * + * If the stream state is still good, then the sentry state becomes + * true ("okay"). + */ + explicit + sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false); + + /** + * @brief Quick status checking. + * @return The sentry state. + * + * For ease of use, sentries may be converted to booleans. The + * return value is that of the sentry state (true == okay). + */ + operator bool() const + { return _M_ok; } + + private: + bool _M_ok; + }; + + // [27.6.1.2.3] character extraction templates + //@{ + /** + * @brief Character extractors + * @param in An input stream. + * @param c A character reference. + * @return in + * + * Behaves like one of the formatted arithmetic extractors described in + * std::basic_istream. After constructing a sentry object with good + * status, this function extracts a character (if one is available) and + * stores it in @a c. Otherwise, sets failbit in the input stream. + */ + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c); + + template<class _Traits> + inline basic_istream<char, _Traits>& + operator>>(basic_istream<char, _Traits>& __in, unsigned char& __c) + { return (__in >> reinterpret_cast<char&>(__c)); } + + template<class _Traits> + inline basic_istream<char, _Traits>& + operator>>(basic_istream<char, _Traits>& __in, signed char& __c) + { return (__in >> reinterpret_cast<char&>(__c)); } + //@} + + //@{ + /** + * @brief Character string extractors + * @param in An input stream. + * @param s A pointer to a character array. + * @return in + * + * Behaves like one of the formatted arithmetic extractors described in + * std::basic_istream. After constructing a sentry object with good + * status, this function extracts up to @c n characters and stores them + * into the array starting at @a s. @c n is defined as: + * + * - if @c width() is greater than zero, @c n is width() + * - otherwise @c n is "the number of elements of the largest array of + * @c char_type that can store a terminating @c eos." [27.6.1.2.3]/6 + * + * Characters are extracted and stored until one of the following happens: + * - @c n-1 characters are stored + * - EOF is reached + * - the next character is whitespace according to the current locale + * - the next character is a null byte (i.e., @c charT() ) + * + * @c width(0) is then called for the input stream. + * + * If no characters are extracted, sets failbit. + */ + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s); + + // Explicit specialization declaration, defined in src/istream.cc. + template<> + basic_istream<char>& + operator>>(basic_istream<char>& __in, char* __s); + + template<class _Traits> + inline basic_istream<char, _Traits>& + operator>>(basic_istream<char, _Traits>& __in, unsigned char* __s) + { return (__in >> reinterpret_cast<char*>(__s)); } + + template<class _Traits> + inline basic_istream<char, _Traits>& + operator>>(basic_istream<char, _Traits>& __in, signed char* __s) + { return (__in >> reinterpret_cast<char*>(__s)); } + //@} + + // 27.6.1.5 Template class basic_iostream + /** + * @brief Merging istream and ostream capabilities. + * + * This class multiply inherits from the input and output stream classes + * simply to provide a single interface. + */ + template<typename _CharT, typename _Traits> + class basic_iostream + : public basic_istream<_CharT, _Traits>, + public basic_ostream<_CharT, _Traits> + { + public: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 271. basic_iostream missing typedefs + // Types (inherited): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + // Non-standard Types: + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_ostream<_CharT, _Traits> __ostream_type; + + /** + * @brief Constructor does nothing. + * + * Both of the parent classes are initialized with the same + * streambuf pointer passed to this constructor. + */ + explicit + basic_iostream(basic_streambuf<_CharT, _Traits>* __sb) + : __istream_type(), __ostream_type() + { this->init(__sb); } + + /** + * @brief Destructor does nothing. + */ + virtual + ~basic_iostream() { } + + protected: + explicit + basic_iostream() : __istream_type(), __ostream_type() + { } + }; + + // [27.6.1.4] standard basic_istream manipulators + /** + * @brief Quick and easy way to eat whitespace + * + * This manipulator extracts whitespace characters, stopping when the + * next character is non-whitespace, or when the input sequence is empty. + * If the sequence is empty, @c eofbit is set in the stream, but not + * @c failbit. + * + * The current locale is used to distinguish whitespace characters. + * + * Example: + * @code + * MyClass mc; + * + * std::cin >> std::ws >> mc; + * @endcode + * will skip leading whitespace before calling operator>> on cin and your + * object. Note that the same effect can be achieved by creating a + * std::basic_istream::sentry inside your definition of operator>>. + */ + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + ws(basic_istream<_CharT, _Traits>& __is); + +_GLIBCXX_END_NAMESPACE + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/istream.tcc> +#endif + +#endif /* _GLIBCXX_ISTREAM */ diff --git a/libstdc++/include/std/std_iterator.h b/libstdc++/include/std/std_iterator.h new file mode 100644 index 0000000..f0317b4 --- /dev/null +++ b/libstdc++/include/std/std_iterator.h @@ -0,0 +1,75 @@ +// <iterator> -*- C++ -*- + +// Copyright (C) 2001, 2002 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/iterator + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_ITERATOR +#define _GLIBCXX_ITERATOR 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <cstddef> +#include <bits/stl_iterator_base_types.h> +#include <bits/stl_iterator_base_funcs.h> +#include <bits/stl_iterator.h> +#include <ostream> +#include <istream> +#include <bits/stream_iterator.h> +#include <bits/streambuf_iterator.h> + +#endif /* _GLIBCXX_ITERATOR */ diff --git a/libstdc++/include/std/std_limits.h b/libstdc++/include/std/std_limits.h new file mode 100644 index 0000000..d1211fd --- /dev/null +++ b/libstdc++/include/std/std_limits.h @@ -0,0 +1,1160 @@ +// The template and inlines for the numeric_limits classes. -*- C++ -*- + +// Copyright (C) 1999, 2000, 2001, 2002, 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. + +/** @file limits + * This is a Standard C++ Library header. + */ + +// Note: this is not a conforming implementation. +// Written by Gabriel Dos Reis <gdr@codesourcery.com> + +// +// ISO 14882:1998 +// 18.2.1 +// + +#ifndef _GLIBCXX_NUMERIC_LIMITS +#define _GLIBCXX_NUMERIC_LIMITS 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +// +// The numeric_limits<> traits document implementation-defined aspects +// of fundamental arithmetic data types (integers and floating points). +// From Standard C++ point of view, there are 13 such types: +// * integers +// bool (1) +// char, signed char, unsigned char (3) +// short, unsigned short (2) +// int, unsigned (2) +// long, unsigned long (2) +// +// * floating points +// float (1) +// double (1) +// long double (1) +// +// GNU C++ undertstands (where supported by the host C-library) +// * integer +// long long, unsigned long long (2) +// +// which brings us to 15 fundamental arithmetic data types in GNU C++. +// +// +// Since a numeric_limits<> is a bit tricky to get right, we rely on +// an interface composed of macros which should be defined in config/os +// or config/cpu when they differ from the generic (read arbitrary) +// definitions given here. +// + +// These values can be overridden in the target configuration file. +// The default values are appropriate for many 32-bit targets. + +// GCC only intrinsicly supports modulo integral types. The only remaining +// integral exceptional values is division by zero. Only targets that do not +// signal division by zero in some "hard to ignore" way should use false. +#ifndef __glibcxx_integral_traps +# define __glibcxx_integral_traps true +#endif + +// float +// + +// Default values. Should be overriden in configuration files if necessary. + +#ifndef __glibcxx_float_has_denorm_loss +# define __glibcxx_float_has_denorm_loss false +#endif +#ifndef __glibcxx_float_traps +# define __glibcxx_float_traps false +#endif +#ifndef __glibcxx_float_tinyness_before +# define __glibcxx_float_tinyness_before false +#endif + +// double + +// Default values. Should be overriden in configuration files if necessary. + +#ifndef __glibcxx_double_has_denorm_loss +# define __glibcxx_double_has_denorm_loss false +#endif +#ifndef __glibcxx_double_traps +# define __glibcxx_double_traps false +#endif +#ifndef __glibcxx_double_tinyness_before +# define __glibcxx_double_tinyness_before false +#endif + +// long double + +// Default values. Should be overriden in configuration files if necessary. + +#ifndef __glibcxx_long_double_has_denorm_loss +# define __glibcxx_long_double_has_denorm_loss false +#endif +#ifndef __glibcxx_long_double_traps +# define __glibcxx_long_double_traps false +#endif +#ifndef __glibcxx_long_double_tinyness_before +# define __glibcxx_long_double_tinyness_before false +#endif + +// You should not need to define any macros below this point. + +#define __glibcxx_signed(T) ((T)(-1) < 0) + +#define __glibcxx_min(T) \ + (__glibcxx_signed (T) ? (T)1 << __glibcxx_digits (T) : (T)0) + +#define __glibcxx_max(T) \ + (__glibcxx_signed (T) ? ((T)1 << __glibcxx_digits (T)) - 1 : ~(T)0) + +#define __glibcxx_digits(T) \ + (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T)) + +// The fraction 643/2136 approximates log10(2) to 7 significant digits. +#define __glibcxx_digits10(T) \ + (__glibcxx_digits (T) * 643 / 2136) + + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Describes the rounding style for floating-point types. + * + * This is used in the std::numeric_limits class. + */ + enum float_round_style + { + round_indeterminate = -1, ///< Self-explanatory. + round_toward_zero = 0, ///< Self-explanatory. + round_to_nearest = 1, ///< To the nearest representable value. + round_toward_infinity = 2, ///< Self-explanatory. + round_toward_neg_infinity = 3 ///< Self-explanatory. + }; + + /** + * @brief Describes the denormalization for floating-point types. + * + * These values represent the presence or absence of a variable number + * of exponent bits. This type is used in the std::numeric_limits class. + */ + enum float_denorm_style + { + /// Indeterminate at compile time whether denormalized values are allowed. + denorm_indeterminate = -1, + /// The type does not allow denormalized values. + denorm_absent = 0, + /// The type allows denormalized values. + denorm_present = 1 + }; + + /** + * @brief Part of std::numeric_limits. + * + * The @c static @c const members are usable as integral constant + * expressions. + * + * @note This is a seperate class for purposes of efficiency; you + * should only access these members as part of an instantiation + * of the std::numeric_limits class. + */ + struct __numeric_limits_base + { + /** This will be true for all fundamental types (which have + specializations), and false for everything else. */ + static const bool is_specialized = false; + + /** The number of @c radix digits that be represented without change: for + integer types, the number of non-sign bits in the mantissa; for + floating types, the number of @c radix digits in the mantissa. */ + static const int digits = 0; + /** The number of base 10 digits that can be represented without change. */ + static const int digits10 = 0; + /** True if the type is signed. */ + static const bool is_signed = false; + /** True if the type is integer. + * @if maint + * Is this supposed to be "if the type is integral"? + * @endif + */ + static const bool is_integer = false; + /** True if the type uses an exact representation. "All integer types are + exact, but not all exact types are integer. For example, rational and + fixed-exponent representations are exact but not integer." + [18.2.1.2]/15 */ + static const bool is_exact = false; + /** For integer types, specifies the base of the representation. For + floating types, specifies the base of the exponent representation. */ + static const int radix = 0; + + /** The minimum negative integer such that @c radix raised to the power of + (one less than that integer) is a normalized floating point number. */ + static const int min_exponent = 0; + /** The minimum negative integer such that 10 raised to that power is in + the range of normalized floating point numbers. */ + static const int min_exponent10 = 0; + /** The maximum positive integer such that @c radix raised to the power of + (one less than that integer) is a representable finite floating point + number. */ + static const int max_exponent = 0; + /** The maximum positive integer such that 10 raised to that power is in + the range of representable finite floating point numbers. */ + static const int max_exponent10 = 0; + + /** True if the type has a representation for positive infinity. */ + static const bool has_infinity = false; + /** True if the type has a representation for a quiet (non-signaling) + "Not a Number." */ + static const bool has_quiet_NaN = false; + /** True if the type has a representation for a signaling + "Not a Number." */ + static const bool has_signaling_NaN = false; + /** See std::float_denorm_style for more information. */ + static const float_denorm_style has_denorm = denorm_absent; + /** "True if loss of accuracy is detected as a denormalization loss, + rather than as an inexact result." [18.2.1.2]/42 */ + static const bool has_denorm_loss = false; + + /** True if-and-only-if the type adheres to the IEC 559 standard, also + known as IEEE 754. (Only makes sense for floating point types.) */ + static const bool is_iec559 = false; + /** "True if the set of values representable by the type is finite. All + built-in types are bounded, this member would be false for arbitrary + precision types." [18.2.1.2]/54 */ + static const bool is_bounded = false; + /** True if the type is @e modulo, that is, if it is possible to add two + positive numbers and have a result that wraps around to a third number + that is less. Typically false for floating types, true for unsigned + integers, and true for signed integers. */ + static const bool is_modulo = false; + + /** True if trapping is implemented for this type. */ + static const bool traps = false; + /** True if tinyness is detected before rounding. (see IEC 559) */ + static const bool tinyness_before = false; + /** See std::float_round_style for more information. This is only + meaningful for floating types; integer types will all be + round_toward_zero. */ + static const float_round_style round_style = round_toward_zero; + }; + + /** + * @brief Properties of fundamental types. + * + * This class allows a program to obtain information about the + * representation of a fundamental type on a given platform. For + * non-fundamental types, the functions will return 0 and the data + * members will all be @c false. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS: DRs 201 and 184 (hi Gaby!) are + * noted, but not incorporated in this documented (yet). + * @endif + */ + template<typename _Tp> + struct numeric_limits : public __numeric_limits_base + { + /** The minimum finite value, or for floating types with + denormalization, the minimum positive normalized value. */ + static _Tp min() throw() { return static_cast<_Tp>(0); } + /** The maximum finite value. */ + static _Tp max() throw() { return static_cast<_Tp>(0); } + /** The @e machine @e epsilon: the difference between 1 and the least + value greater than 1 that is representable. */ + static _Tp epsilon() throw() { return static_cast<_Tp>(0); } + /** The maximum rounding error measurement (see LIA-1). */ + static _Tp round_error() throw() { return static_cast<_Tp>(0); } + /** The representation of positive infinity, if @c has_infinity. */ + static _Tp infinity() throw() { return static_cast<_Tp>(0); } + /** The representation of a quiet "Not a Number," if @c has_quiet_NaN. */ + static _Tp quiet_NaN() throw() { return static_cast<_Tp>(0); } + /** The representation of a signaling "Not a Number," if + @c has_signaling_NaN. */ + static _Tp signaling_NaN() throw() { return static_cast<_Tp>(0); } + /** The minimum positive denormalized value. For types where + @c has_denorm is false, this is the minimum positive normalized + value. */ + static _Tp denorm_min() throw() { return static_cast<_Tp>(0); } + }; + + // Now there follow 15 explicit specializations. Yes, 15. Make sure + // you get the count right. + + /// numeric_limits<bool> specialization. + template<> + struct numeric_limits<bool> + { + static const bool is_specialized = true; + + static bool min() throw() + { return false; } + static bool max() throw() + { return true; } + + static const int digits = 1; + static const int digits10 = 0; + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static bool epsilon() throw() + { return false; } + static bool round_error() throw() + { return false; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static bool infinity() throw() + { return false; } + static bool quiet_NaN() throw() + { return false; } + static bool signaling_NaN() throw() + { return false; } + static bool denorm_min() throw() + { return false; } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + + // It is not clear what it means for a boolean type to trap. + // This is a DR on the LWG issue list. Here, I use integer + // promotion semantics. + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<char> specialization. + template<> + struct numeric_limits<char> + { + static const bool is_specialized = true; + + static char min() throw() + { return __glibcxx_min(char); } + static char max() throw() + { return __glibcxx_max(char); } + + static const int digits = __glibcxx_digits (char); + static const int digits10 = __glibcxx_digits10 (char); + static const bool is_signed = __glibcxx_signed (char); + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static char epsilon() throw() + { return 0; } + static char round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static char infinity() throw() + { return char(); } + static char quiet_NaN() throw() + { return char(); } + static char signaling_NaN() throw() + { return char(); } + static char denorm_min() throw() + { return static_cast<char>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<signed char> specialization. + template<> + struct numeric_limits<signed char> + { + static const bool is_specialized = true; + + static signed char min() throw() + { return -__SCHAR_MAX__ - 1; } + static signed char max() throw() + { return __SCHAR_MAX__; } + + static const int digits = __glibcxx_digits (signed char); + static const int digits10 = __glibcxx_digits10 (signed char); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static signed char epsilon() throw() + { return 0; } + static signed char round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static signed char infinity() throw() + { return static_cast<signed char>(0); } + static signed char quiet_NaN() throw() + { return static_cast<signed char>(0); } + static signed char signaling_NaN() throw() + { return static_cast<signed char>(0); } + static signed char denorm_min() throw() + { return static_cast<signed char>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<unsigned char> specialization. + template<> + struct numeric_limits<unsigned char> + { + static const bool is_specialized = true; + + static unsigned char min() throw() + { return 0; } + static unsigned char max() throw() + { return __SCHAR_MAX__ * 2U + 1; } + + static const int digits = __glibcxx_digits (unsigned char); + static const int digits10 = __glibcxx_digits10 (unsigned char); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned char epsilon() throw() + { return 0; } + static unsigned char round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned char infinity() throw() + { return static_cast<unsigned char>(0); } + static unsigned char quiet_NaN() throw() + { return static_cast<unsigned char>(0); } + static unsigned char signaling_NaN() throw() + { return static_cast<unsigned char>(0); } + static unsigned char denorm_min() throw() + { return static_cast<unsigned char>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<wchar_t> specialization. + template<> + struct numeric_limits<wchar_t> + { + static const bool is_specialized = true; + + static wchar_t min() throw() + { return __glibcxx_min (wchar_t); } + static wchar_t max() throw() + { return __glibcxx_max (wchar_t); } + + static const int digits = __glibcxx_digits (wchar_t); + static const int digits10 = __glibcxx_digits10 (wchar_t); + static const bool is_signed = __glibcxx_signed (wchar_t); + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static wchar_t epsilon() throw() + { return 0; } + static wchar_t round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static wchar_t infinity() throw() + { return wchar_t(); } + static wchar_t quiet_NaN() throw() + { return wchar_t(); } + static wchar_t signaling_NaN() throw() + { return wchar_t(); } + static wchar_t denorm_min() throw() + { return wchar_t(); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<short> specialization. + template<> + struct numeric_limits<short> + { + static const bool is_specialized = true; + + static short min() throw() + { return -__SHRT_MAX__ - 1; } + static short max() throw() + { return __SHRT_MAX__; } + + static const int digits = __glibcxx_digits (short); + static const int digits10 = __glibcxx_digits10 (short); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static short epsilon() throw() + { return 0; } + static short round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static short infinity() throw() + { return short(); } + static short quiet_NaN() throw() + { return short(); } + static short signaling_NaN() throw() + { return short(); } + static short denorm_min() throw() + { return short(); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<unsigned short> specialization. + template<> + struct numeric_limits<unsigned short> + { + static const bool is_specialized = true; + + static unsigned short min() throw() + { return 0; } + static unsigned short max() throw() + { return __SHRT_MAX__ * 2U + 1; } + + static const int digits = __glibcxx_digits (unsigned short); + static const int digits10 = __glibcxx_digits10 (unsigned short); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned short epsilon() throw() + { return 0; } + static unsigned short round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned short infinity() throw() + { return static_cast<unsigned short>(0); } + static unsigned short quiet_NaN() throw() + { return static_cast<unsigned short>(0); } + static unsigned short signaling_NaN() throw() + { return static_cast<unsigned short>(0); } + static unsigned short denorm_min() throw() + { return static_cast<unsigned short>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<int> specialization. + template<> + struct numeric_limits<int> + { + static const bool is_specialized = true; + + static int min() throw() + { return -__INT_MAX__ - 1; } + static int max() throw() + { return __INT_MAX__; } + + static const int digits = __glibcxx_digits (int); + static const int digits10 = __glibcxx_digits10 (int); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static int epsilon() throw() + { return 0; } + static int round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static int infinity() throw() + { return static_cast<int>(0); } + static int quiet_NaN() throw() + { return static_cast<int>(0); } + static int signaling_NaN() throw() + { return static_cast<int>(0); } + static int denorm_min() throw() + { return static_cast<int>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<unsigned int> specialization. + template<> + struct numeric_limits<unsigned int> + { + static const bool is_specialized = true; + + static unsigned int min() throw() + { return 0; } + static unsigned int max() throw() + { return __INT_MAX__ * 2U + 1; } + + static const int digits = __glibcxx_digits (unsigned int); + static const int digits10 = __glibcxx_digits10 (unsigned int); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned int epsilon() throw() + { return 0; } + static unsigned int round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned int infinity() throw() + { return static_cast<unsigned int>(0); } + static unsigned int quiet_NaN() throw() + { return static_cast<unsigned int>(0); } + static unsigned int signaling_NaN() throw() + { return static_cast<unsigned int>(0); } + static unsigned int denorm_min() throw() + { return static_cast<unsigned int>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<long> specialization. + template<> + struct numeric_limits<long> + { + static const bool is_specialized = true; + + static long min() throw() + { return -__LONG_MAX__ - 1; } + static long max() throw() + { return __LONG_MAX__; } + + static const int digits = __glibcxx_digits (long); + static const int digits10 = __glibcxx_digits10 (long); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static long epsilon() throw() + { return 0; } + static long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static long infinity() throw() + { return static_cast<long>(0); } + static long quiet_NaN() throw() + { return static_cast<long>(0); } + static long signaling_NaN() throw() + { return static_cast<long>(0); } + static long denorm_min() throw() + { return static_cast<long>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<unsigned long> specialization. + template<> + struct numeric_limits<unsigned long> + { + static const bool is_specialized = true; + + static unsigned long min() throw() + { return 0; } + static unsigned long max() throw() + { return __LONG_MAX__ * 2UL + 1; } + + static const int digits = __glibcxx_digits (unsigned long); + static const int digits10 = __glibcxx_digits10 (unsigned long); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned long epsilon() throw() + { return 0; } + static unsigned long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned long infinity() throw() + { return static_cast<unsigned long>(0); } + static unsigned long quiet_NaN() throw() + { return static_cast<unsigned long>(0); } + static unsigned long signaling_NaN() throw() + { return static_cast<unsigned long>(0); } + static unsigned long denorm_min() throw() + { return static_cast<unsigned long>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<long long> specialization. + template<> + struct numeric_limits<long long> + { + static const bool is_specialized = true; + + static long long min() throw() + { return -__LONG_LONG_MAX__ - 1; } + static long long max() throw() + { return __LONG_LONG_MAX__; } + + static const int digits = __glibcxx_digits (long long); + static const int digits10 = __glibcxx_digits10 (long long); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static long long epsilon() throw() + { return 0; } + static long long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static long long infinity() throw() + { return static_cast<long long>(0); } + static long long quiet_NaN() throw() + { return static_cast<long long>(0); } + static long long signaling_NaN() throw() + { return static_cast<long long>(0); } + static long long denorm_min() throw() + { return static_cast<long long>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<unsigned long long> specialization. + template<> + struct numeric_limits<unsigned long long> + { + static const bool is_specialized = true; + + static unsigned long long min() throw() + { return 0; } + static unsigned long long max() throw() + { return __LONG_LONG_MAX__ * 2ULL + 1; } + + static const int digits = __glibcxx_digits (unsigned long long); + static const int digits10 = __glibcxx_digits10 (unsigned long long); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned long long epsilon() throw() + { return 0; } + static unsigned long long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned long long infinity() throw() + { return static_cast<unsigned long long>(0); } + static unsigned long long quiet_NaN() throw() + { return static_cast<unsigned long long>(0); } + static unsigned long long signaling_NaN() throw() + { return static_cast<unsigned long long>(0); } + static unsigned long long denorm_min() throw() + { return static_cast<unsigned long long>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + /// numeric_limits<float> specialization. + template<> + struct numeric_limits<float> + { + static const bool is_specialized = true; + + static float min() throw() + { return __FLT_MIN__; } + static float max() throw() + { return __FLT_MAX__; } + + static const int digits = __FLT_MANT_DIG__; + static const int digits10 = __FLT_DIG__; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = __FLT_RADIX__; + static float epsilon() throw() + { return __FLT_EPSILON__; } + static float round_error() throw() + { return 0.5F; } + + static const int min_exponent = __FLT_MIN_EXP__; + static const int min_exponent10 = __FLT_MIN_10_EXP__; + static const int max_exponent = __FLT_MAX_EXP__; + static const int max_exponent10 = __FLT_MAX_10_EXP__; + + static const bool has_infinity = __FLT_HAS_INFINITY__; + static const bool has_quiet_NaN = __FLT_HAS_QUIET_NAN__; + static const bool has_signaling_NaN = has_quiet_NaN; + static const float_denorm_style has_denorm + = bool(__FLT_HAS_DENORM__) ? denorm_present : denorm_absent; + static const bool has_denorm_loss = __glibcxx_float_has_denorm_loss; + + static float infinity() throw() + { return __builtin_huge_valf (); } + static float quiet_NaN() throw() + { return __builtin_nanf (""); } + static float signaling_NaN() throw() + { return __builtin_nansf (""); } + static float denorm_min() throw() + { return __FLT_DENORM_MIN__; } + + static const bool is_iec559 + = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = __glibcxx_float_traps; + static const bool tinyness_before = __glibcxx_float_tinyness_before; + static const float_round_style round_style = round_to_nearest; + }; + +#undef __glibcxx_float_has_denorm_loss +#undef __glibcxx_float_traps +#undef __glibcxx_float_tinyness_before + + /// numeric_limits<double> specialization. + template<> + struct numeric_limits<double> + { + static const bool is_specialized = true; + + static double min() throw() + { return __DBL_MIN__; } + static double max() throw() + { return __DBL_MAX__; } + + static const int digits = __DBL_MANT_DIG__; + static const int digits10 = __DBL_DIG__; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = __FLT_RADIX__; + static double epsilon() throw() + { return __DBL_EPSILON__; } + static double round_error() throw() + { return 0.5; } + + static const int min_exponent = __DBL_MIN_EXP__; + static const int min_exponent10 = __DBL_MIN_10_EXP__; + static const int max_exponent = __DBL_MAX_EXP__; + static const int max_exponent10 = __DBL_MAX_10_EXP__; + + static const bool has_infinity = __DBL_HAS_INFINITY__; + static const bool has_quiet_NaN = __DBL_HAS_QUIET_NAN__; + static const bool has_signaling_NaN = has_quiet_NaN; + static const float_denorm_style has_denorm + = bool(__DBL_HAS_DENORM__) ? denorm_present : denorm_absent; + static const bool has_denorm_loss = __glibcxx_double_has_denorm_loss; + + static double infinity() throw() + { return __builtin_huge_val(); } + static double quiet_NaN() throw() + { return __builtin_nan (""); } + static double signaling_NaN() throw() + { return __builtin_nans (""); } + static double denorm_min() throw() + { return __DBL_DENORM_MIN__; } + + static const bool is_iec559 + = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = __glibcxx_double_traps; + static const bool tinyness_before = __glibcxx_double_tinyness_before; + static const float_round_style round_style = round_to_nearest; + }; + +#undef __glibcxx_double_has_denorm_loss +#undef __glibcxx_double_traps +#undef __glibcxx_double_tinyness_before + + /// numeric_limits<long double> specialization. + template<> + struct numeric_limits<long double> + { + static const bool is_specialized = true; + + static long double min() throw() + { return __LDBL_MIN__; } + static long double max() throw() + { return __LDBL_MAX__; } + + static const int digits = __LDBL_MANT_DIG__; + static const int digits10 = __LDBL_DIG__; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = __FLT_RADIX__; + static long double epsilon() throw() + { return __LDBL_EPSILON__; } + static long double round_error() throw() + { return 0.5L; } + + static const int min_exponent = __LDBL_MIN_EXP__; + static const int min_exponent10 = __LDBL_MIN_10_EXP__; + static const int max_exponent = __LDBL_MAX_EXP__; + static const int max_exponent10 = __LDBL_MAX_10_EXP__; + + static const bool has_infinity = __LDBL_HAS_INFINITY__; + static const bool has_quiet_NaN = __LDBL_HAS_QUIET_NAN__; + static const bool has_signaling_NaN = has_quiet_NaN; + static const float_denorm_style has_denorm + = bool(__LDBL_HAS_DENORM__) ? denorm_present : denorm_absent; + static const bool has_denorm_loss + = __glibcxx_long_double_has_denorm_loss; + + static long double infinity() throw() + { return __builtin_huge_vall (); } + static long double quiet_NaN() throw() + { return __builtin_nanl (""); } + static long double signaling_NaN() throw() + { return __builtin_nansl (""); } + static long double denorm_min() throw() + { return __LDBL_DENORM_MIN__; } + + static const bool is_iec559 + = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = __glibcxx_long_double_traps; + static const bool tinyness_before = __glibcxx_long_double_tinyness_before; + static const float_round_style round_style = round_to_nearest; + }; + +#undef __glibcxx_long_double_has_denorm_loss +#undef __glibcxx_long_double_traps +#undef __glibcxx_long_double_tinyness_before + +_GLIBCXX_END_NAMESPACE + +#undef __glibcxx_signed +#undef __glibcxx_min +#undef __glibcxx_max +#undef __glibcxx_digits +#undef __glibcxx_digits10 + +#endif // _GLIBCXX_NUMERIC_LIMITS diff --git a/libstdc++/include/std/std_list.h b/libstdc++/include/std/std_list.h new file mode 100644 index 0000000..b46f654 --- /dev/null +++ b/libstdc++/include/std/std_list.h @@ -0,0 +1,81 @@ +// <list> -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/list + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_LIST +#define _GLIBCXX_LIST 1 + +#pragma GCC system_header + +#include <bits/functexcept.h> +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_list.h> + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/list.tcc> +#endif + +#ifdef _GLIBCXX_DEBUG +# include <debug/list> +#endif + +#endif /* _GLIBCXX_LIST */ + diff --git a/libstdc++/include/std/std_locale.h b/libstdc++/include/std/std_locale.h new file mode 100644 index 0000000..5223f90 --- /dev/null +++ b/libstdc++/include/std/std_locale.h @@ -0,0 +1,48 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +// +// ISO C++ 14882: 22.1 Locales +// + +/** @file locale + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_LOCALE +#define _GLIBCXX_LOCALE 1 + +#pragma GCC system_header + +#include <bits/localefwd.h> +#include <bits/locale_classes.h> +#include <bits/locale_facets.h> +#include <bits/locale_facets.tcc> + +#endif /* _GLIBCXX_LOCALE */ diff --git a/libstdc++/include/std/std_map.h b/libstdc++/include/std/std_map.h new file mode 100644 index 0000000..a7e8f9c --- /dev/null +++ b/libstdc++/include/std/std_map.h @@ -0,0 +1,73 @@ +// <map> -*- C++ -*- + +// Copyright (C) 2001, 2002 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/map + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_MAP +#define _GLIBCXX_MAP 1 + +#pragma GCC system_header + +#include <bits/stl_tree.h> +#include <bits/stl_map.h> +#include <bits/stl_multimap.h> + +#ifdef _GLIBCXX_DEBUG +# include <debug/map> +#endif + +#endif /* _GLIBCXX_MAP */ diff --git a/libstdc++/include/std/std_memory.h b/libstdc++/include/std/std_memory.h new file mode 100644 index 0000000..b57a94f --- /dev/null +++ b/libstdc++/include/std/std_memory.h @@ -0,0 +1,374 @@ +// <memory> -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/* + * Copyright (c) 1997-1999 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file include/memory + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_MEMORY +#define _GLIBCXX_MEMORY 1 + +#pragma GCC system_header + +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_construct.h> +#include <bits/stl_iterator_base_types.h> //for iterator_traits +#include <bits/stl_uninitialized.h> +#include <bits/stl_raw_storage_iter.h> +#include <debug/debug.h> +#include <limits> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @if maint + * This is a helper function. The unused second parameter exists to + * permit the real get_temporary_buffer to use template parameter deduction. + * + * XXX This should perhaps use the pool. + * @endif + */ + template<typename _Tp> + pair<_Tp*, ptrdiff_t> + __get_temporary_buffer(ptrdiff_t __len, _Tp*) + { + const ptrdiff_t __max = numeric_limits<ptrdiff_t>::max() / sizeof(_Tp); + if (__len > __max) + __len = __max; + + while (__len > 0) + { + _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp), + nothrow)); + if (__tmp != 0) + return pair<_Tp*, ptrdiff_t>(__tmp, __len); + __len /= 2; + } + return pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0); + } + + /** + * @brief Allocates a temporary buffer. + * @param len The number of objects of type Tp. + * @return See full description. + * + * Reinventing the wheel, but this time with prettier spokes! + * + * This function tries to obtain storage for @c len adjacent Tp + * objects. The objects themselves are not constructed, of course. + * A pair<> is returned containing "the buffer s address and + * capacity (in the units of sizeof(Tp)), or a pair of 0 values if + * no storage can be obtained." Note that the capacity obtained + * may be less than that requested if the memory is unavailable; + * you should compare len with the .second return value. + * + * Provides the nothrow exception guarantee. + */ + template<typename _Tp> + inline pair<_Tp*, ptrdiff_t> + get_temporary_buffer(ptrdiff_t __len) + { return std::__get_temporary_buffer(__len, static_cast<_Tp*>(0)); } + + /** + * @brief The companion to get_temporary_buffer(). + * @param p A buffer previously allocated by get_temporary_buffer. + * @return None. + * + * Frees the memory pointed to by p. + */ + template<typename _Tp> + void + return_temporary_buffer(_Tp* __p) + { ::operator delete(__p, nothrow); } + + /** + * A wrapper class to provide auto_ptr with reference semantics. + * For example, an auto_ptr can be assigned (or constructed from) + * the result of a function which returns an auto_ptr by value. + * + * All the auto_ptr_ref stuff should happen behind the scenes. + */ + template<typename _Tp1> + struct auto_ptr_ref + { + _Tp1* _M_ptr; + + explicit + auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { } + }; + + + /** + * @brief A simple smart pointer providing strict ownership semantics. + * + * The Standard says: + * <pre> + * An @c auto_ptr owns the object it holds a pointer to. Copying + * an @c auto_ptr copies the pointer and transfers ownership to the + * destination. If more than one @c auto_ptr owns the same object + * at the same time the behavior of the program is undefined. + * + * The uses of @c auto_ptr include providing temporary + * exception-safety for dynamically allocated memory, passing + * ownership of dynamically allocated memory to a function, and + * returning dynamically allocated memory from a function. @c + * auto_ptr does not meet the CopyConstructible and Assignable + * requirements for Standard Library <a + * href="tables.html#65">container</a> elements and thus + * instantiating a Standard Library container with an @c auto_ptr + * results in undefined behavior. + * </pre> + * Quoted from [20.4.5]/3. + * + * Good examples of what can and cannot be done with auto_ptr can + * be found in the libstdc++ testsuite. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * 127. auto_ptr<> conversion issues + * These resolutions have all been incorporated. + * @endif + */ + template<typename _Tp> + class auto_ptr + { + private: + _Tp* _M_ptr; + + public: + /// The pointed-to type. + typedef _Tp element_type; + + /** + * @brief An %auto_ptr is usually constructed from a raw pointer. + * @param p A pointer (defaults to NULL). + * + * This object now @e owns the object pointed to by @a p. + */ + explicit + auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } + + /** + * @brief An %auto_ptr can be constructed from another %auto_ptr. + * @param a Another %auto_ptr of the same type. + * + * This object now @e owns the object previously owned by @a a, + * which has given up ownsership. + */ + auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { } + + /** + * @brief An %auto_ptr can be constructed from another %auto_ptr. + * @param a Another %auto_ptr of a different but related type. + * + * A pointer-to-Tp1 must be convertible to a + * pointer-to-Tp/element_type. + * + * This object now @e owns the object previously owned by @a a, + * which has given up ownsership. + */ + template<typename _Tp1> + auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { } + + /** + * @brief %auto_ptr assignment operator. + * @param a Another %auto_ptr of the same type. + * + * This object now @e owns the object previously owned by @a a, + * which has given up ownsership. The object that this one @e + * used to own and track has been deleted. + */ + auto_ptr& + operator=(auto_ptr& __a) throw() + { + reset(__a.release()); + return *this; + } + + /** + * @brief %auto_ptr assignment operator. + * @param a Another %auto_ptr of a different but related type. + * + * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. + * + * This object now @e owns the object previously owned by @a a, + * which has given up ownsership. The object that this one @e + * used to own and track has been deleted. + */ + template<typename _Tp1> + auto_ptr& + operator=(auto_ptr<_Tp1>& __a) throw() + { + reset(__a.release()); + return *this; + } + + /** + * When the %auto_ptr goes out of scope, the object it owns is + * deleted. If it no longer owns anything (i.e., @c get() is + * @c NULL), then this has no effect. + * + * @if maint + * The C++ standard says there is supposed to be an empty throw + * specification here, but omitting it is standard conforming. Its + * presence can be detected only if _Tp::~_Tp() throws, but this is + * prohibited. [17.4.3.6]/2 + * @endif + */ + ~auto_ptr() { delete _M_ptr; } + + /** + * @brief Smart pointer dereferencing. + * + * If this %auto_ptr no longer owns anything, then this + * operation will crash. (For a smart pointer, "no longer owns + * anything" is the same as being a null pointer, and you know + * what happens when you dereference one of those...) + */ + element_type& + operator*() const throw() + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return *_M_ptr; + } + + /** + * @brief Smart pointer dereferencing. + * + * This returns the pointer itself, which the language then will + * automatically cause to be dereferenced. + */ + element_type* + operator->() const throw() + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return _M_ptr; + } + + /** + * @brief Bypassing the smart pointer. + * @return The raw pointer being managed. + * + * You can get a copy of the pointer that this object owns, for + * situations such as passing to a function which only accepts + * a raw pointer. + * + * @note This %auto_ptr still owns the memory. + */ + element_type* + get() const throw() { return _M_ptr; } + + /** + * @brief Bypassing the smart pointer. + * @return The raw pointer being managed. + * + * You can get a copy of the pointer that this object owns, for + * situations such as passing to a function which only accepts + * a raw pointer. + * + * @note This %auto_ptr no longer owns the memory. When this object + * goes out of scope, nothing will happen. + */ + element_type* + release() throw() + { + element_type* __tmp = _M_ptr; + _M_ptr = 0; + return __tmp; + } + + /** + * @brief Forcibly deletes the managed object. + * @param p A pointer (defaults to NULL). + * + * This object now @e owns the object pointed to by @a p. The + * previous object has been deleted. + */ + void + reset(element_type* __p = 0) throw() + { + if (__p != _M_ptr) + { + delete _M_ptr; + _M_ptr = __p; + } + } + + /** + * @brief Automatic conversions + * + * These operations convert an %auto_ptr into and from an auto_ptr_ref + * automatically as needed. This allows constructs such as + * @code + * auto_ptr<Derived> func_returning_auto_ptr(.....); + * ... + * auto_ptr<Base> ptr = func_returning_auto_ptr(.....); + * @endcode + */ + auto_ptr(auto_ptr_ref<element_type> __ref) throw() + : _M_ptr(__ref._M_ptr) { } + + auto_ptr& + operator=(auto_ptr_ref<element_type> __ref) throw() + { + if (__ref._M_ptr != this->get()) + { + delete _M_ptr; + _M_ptr = __ref._M_ptr; + } + return *this; + } + + template<typename _Tp1> + operator auto_ptr_ref<_Tp1>() throw() + { return auto_ptr_ref<_Tp1>(this->release()); } + + template<typename _Tp1> + operator auto_ptr<_Tp1>() throw() + { return auto_ptr<_Tp1>(this->release()); } + }; + +_GLIBCXX_END_NAMESPACE + +#endif /* _GLIBCXX_MEMORY */ diff --git a/libstdc++/include/std/std_numeric.h b/libstdc++/include/std/std_numeric.h new file mode 100644 index 0000000..03f82dd --- /dev/null +++ b/libstdc++/include/std/std_numeric.h @@ -0,0 +1,71 @@ +// <numeric> -*- C++ -*- + +// Copyright (C) 2001, 2002 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/numeric + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_NUMERIC +#define _GLIBCXX_NUMERIC 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <cstddef> +#include <iterator> +#include <bits/stl_function.h> +#include <bits/stl_numeric.h> + +#endif /* _GLIBCXX_NUMERIC */ diff --git a/libstdc++/include/std/std_ostream.h b/libstdc++/include/std/std_ostream.h new file mode 100644 index 0000000..23e9510 --- /dev/null +++ b/libstdc++/include/std/std_ostream.h @@ -0,0 +1,575 @@ +// Output streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, +// 2006, 2007 +// 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. + +/** @file ostream + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 27.6.2 Output streams +// + +#ifndef _GLIBCXX_OSTREAM +#define _GLIBCXX_OSTREAM 1 + +#pragma GCC system_header + +#include <ios> +#include <bits/ostream_insert.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // [27.6.2.1] Template class basic_ostream + /** + * @brief Controlling output. + * + * This is the base class for all output streams. It provides text + * formatting of all builtin types, and communicates with any class + * derived from basic_streambuf to do the actual output. + */ + template<typename _CharT, typename _Traits> + class basic_ostream : virtual public basic_ios<_CharT, _Traits> + { + public: + // Types (inherited from basic_ios (27.4.4)): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + // Non-standard Types: + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_ios<_CharT, _Traits> __ios_type; + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > + __num_put_type; + typedef ctype<_CharT> __ctype_type; + + // [27.6.2.2] constructor/destructor + /** + * @brief Base constructor. + * + * This ctor is almost never called by the user directly, rather from + * derived classes' initialization lists, which pass a pointer to + * their own stream buffer. + */ + explicit + basic_ostream(__streambuf_type* __sb) + { this->init(__sb); } + + /** + * @brief Base destructor. + * + * This does very little apart from providing a virtual base dtor. + */ + virtual + ~basic_ostream() { } + + // [27.6.2.3] prefix/suffix + class sentry; + friend class sentry; + + // [27.6.2.5] formatted output + // [27.6.2.5.3] basic_ostream::operator<< + //@{ + /** + * @brief Interface for manipulators. + * + * Manuipulators such as @c std::endl and @c std::hex use these + * functions in constructs like "std::cout << std::endl". For more + * information, see the iomanip header. + */ + __ostream_type& + operator<<(__ostream_type& (*__pf)(__ostream_type&)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + return __pf(*this); + } + + __ostream_type& + operator<<(__ios_type& (*__pf)(__ios_type&)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + __pf(*this); + return *this; + } + + __ostream_type& + operator<<(ios_base& (*__pf) (ios_base&)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + __pf(*this); + return *this; + } + //@} + + // [27.6.2.5.2] arithmetic inserters + /** + * @name Arithmetic Inserters + * + * All the @c operator<< functions (aka <em>formatted output + * functions</em>) have some common behavior. Each starts by + * constructing a temporary object of type std::basic_ostream::sentry. + * This can have several effects, concluding with the setting of a + * status flag; see the sentry documentation for more. + * + * If the sentry status is good, the function tries to generate + * whatever data is appropriate for the type of the argument. + * + * If an exception is thrown during insertion, ios_base::badbit + * will be turned on in the stream's error state without causing an + * ios_base::failure to be thrown. The original exception will then + * be rethrown. + */ + //@{ + /** + * @brief Basic arithmetic inserters + * @param A variable of builtin type. + * @return @c *this if successful + * + * These functions use the stream's current locale (specifically, the + * @c num_get facet) to perform numeric formatting. + */ + __ostream_type& + operator<<(long __n) + { return _M_insert(__n); } + + __ostream_type& + operator<<(unsigned long __n) + { return _M_insert(__n); } + + __ostream_type& + operator<<(bool __n) + { return _M_insert(__n); } + + __ostream_type& + operator<<(short __n); + + __ostream_type& + operator<<(unsigned short __n) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + return _M_insert(static_cast<unsigned long>(__n)); + } + + __ostream_type& + operator<<(int __n); + + __ostream_type& + operator<<(unsigned int __n) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + return _M_insert(static_cast<unsigned long>(__n)); + } + +#ifdef _GLIBCXX_USE_LONG_LONG + __ostream_type& + operator<<(long long __n) + { return _M_insert(__n); } + + __ostream_type& + operator<<(unsigned long long __n) + { return _M_insert(__n); } +#endif + + __ostream_type& + operator<<(double __f) + { return _M_insert(__f); } + + __ostream_type& + operator<<(float __f) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 117. basic_ostream uses nonexistent num_put member functions. + return _M_insert(static_cast<double>(__f)); + } + + __ostream_type& + operator<<(long double __f) + { return _M_insert(__f); } + + __ostream_type& + operator<<(const void* __p) + { return _M_insert(__p); } + + /** + * @brief Extracting from another streambuf. + * @param sb A pointer to a streambuf + * + * This function behaves like one of the basic arithmetic extractors, + * in that it also constructs a sentry object and has the same error + * handling behavior. + * + * If @a sb is NULL, the stream will set failbit in its error state. + * + * Characters are extracted from @a sb and inserted into @c *this + * until one of the following occurs: + * + * - the input stream reaches end-of-file, + * - insertion into the output sequence fails (in this case, the + * character that would have been inserted is not extracted), or + * - an exception occurs while getting a character from @a sb, which + * sets failbit in the error state + * + * If the function inserts no characters, failbit is set. + */ + __ostream_type& + operator<<(__streambuf_type* __sb); + //@} + + // [27.6.2.6] unformatted output functions + /** + * @name Unformatted Output Functions + * + * All the unformatted output functions have some common behavior. + * Each starts by constructing a temporary object of type + * std::basic_ostream::sentry. This has several effects, concluding + * with the setting of a status flag; see the sentry documentation + * for more. + * + * If the sentry status is good, the function tries to generate + * whatever data is appropriate for the type of the argument. + * + * If an exception is thrown during insertion, ios_base::badbit + * will be turned on in the stream's error state. If badbit is on in + * the stream's exceptions mask, the exception will be rethrown + * without completing its actions. + */ + //@{ + /** + * @brief Simple insertion. + * @param c The character to insert. + * @return *this + * + * Tries to insert @a c. + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __ostream_type& + put(char_type __c); + + // Core write functionality, without sentry. + void + _M_write(const char_type* __s, streamsize __n) + { + const streamsize __put = this->rdbuf()->sputn(__s, __n); + if (__put != __n) + this->setstate(ios_base::badbit); + } + + /** + * @brief Character string insertion. + * @param s The array to insert. + * @param n Maximum number of characters to insert. + * @return *this + * + * Characters are copied from @a s and inserted into the stream until + * one of the following happens: + * + * - @a n characters are inserted + * - inserting into the output sequence fails (in this case, badbit + * will be set in the stream's error state) + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __ostream_type& + write(const char_type* __s, streamsize __n); + //@} + + /** + * @brief Synchronizing the stream buffer. + * @return *this + * + * If @c rdbuf() is a null pointer, changes nothing. + * + * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, + * sets badbit. + */ + __ostream_type& + flush(); + + // [27.6.2.4] seek members + /** + * @brief Getting the current write position. + * @return A file position object. + * + * If @c fail() is not false, returns @c pos_type(-1) to indicate + * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,out). + */ + pos_type + tellp(); + + /** + * @brief Changing the current write position. + * @param pos A file position object. + * @return *this + * + * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If + * that function fails, sets failbit. + */ + __ostream_type& + seekp(pos_type); + + /** + * @brief Changing the current write position. + * @param off A file offset object. + * @param dir The direction in which to seek. + * @return *this + * + * If @c fail() is not true, calls @c rdbuf()->pubseekoff(off,dir). + * If that function fails, sets failbit. + */ + __ostream_type& + seekp(off_type, ios_base::seekdir); + + protected: + explicit + basic_ostream() { } + + template<typename _ValueT> + __ostream_type& + _M_insert(_ValueT __v); + }; + + /** + * @brief Performs setup work for output streams. + * + * Objects of this class are created before all of the standard + * inserters are run. It is responsible for "exception-safe prefix and + * suffix operations." Additional actions may be added by the + * implementation, and we list them in + * http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/howto.html#5 + * under [27.6] notes. + */ + template <typename _CharT, typename _Traits> + class basic_ostream<_CharT, _Traits>::sentry + { + // Data Members: + bool _M_ok; + basic_ostream<_CharT, _Traits>& _M_os; + + public: + /** + * @brief The constructor performs preparatory work. + * @param os The output stream to guard. + * + * If the stream state is good (@a os.good() is true), then if the + * stream is tied to another output stream, @c is.tie()->flush() + * is called to synchronize the output sequences. + * + * If the stream state is still good, then the sentry state becomes + * true ("okay"). + */ + explicit + sentry(basic_ostream<_CharT, _Traits>& __os); + + /** + * @brief Possibly flushes the stream. + * + * If @c ios_base::unitbuf is set in @c os.flags(), and + * @c std::uncaught_exception() is true, the sentry destructor calls + * @c flush() on the output stream. + */ + ~sentry() + { + // XXX MT + if (_M_os.flags() & ios_base::unitbuf && !uncaught_exception()) + { + // Can't call flush directly or else will get into recursive lock. + if (_M_os.rdbuf() && _M_os.rdbuf()->pubsync() == -1) + _M_os.setstate(ios_base::badbit); + } + } + + /** + * @brief Quick status checking. + * @return The sentry state. + * + * For ease of use, sentries may be converted to booleans. The + * return value is that of the sentry state (true == okay). + */ + operator bool() const + { return _M_ok; } + }; + + // [27.6.2.5.4] character insertion templates + //@{ + /** + * @brief Character inserters + * @param out An output stream. + * @param c A character. + * @return out + * + * Behaves like one of the formatted arithmetic inserters described in + * std::basic_ostream. After constructing a sentry object with good + * status, this function inserts a single character and any required + * padding (as determined by [22.2.2.2.2]). @c out.width(0) is then + * called. + * + * If @a c is of type @c char and the character type of the stream is not + * @c char, the character is widened before insertion. + */ + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) + { return __ostream_insert(__out, &__c, 1); } + + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) + { return (__out << __out.widen(__c)); } + + // Specialization + template <class _Traits> + inline basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, char __c) + { return __ostream_insert(__out, &__c, 1); } + + // Signed and unsigned + template<class _Traits> + inline basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, signed char __c) + { return (__out << static_cast<char>(__c)); } + + template<class _Traits> + inline basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c) + { return (__out << static_cast<char>(__c)); } + //@} + + //@{ + /** + * @brief String inserters + * @param out An output stream. + * @param s A character string. + * @return out + * @pre @a s must be a non-NULL pointer + * + * Behaves like one of the formatted arithmetic inserters described in + * std::basic_ostream. After constructing a sentry object with good + * status, this function inserts @c traits::length(s) characters starting + * at @a s, widened if necessary, followed by any required padding (as + * determined by [22.2.2.2.2]). @c out.width(0) is then called. + */ + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) + { + if (!__s) + __out.setstate(ios_base::badbit); + else + __ostream_insert(__out, __s, + static_cast<streamsize>(_Traits::length(__s))); + return __out; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits> & + operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s); + + // Partial specializationss + template<class _Traits> + inline basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, const char* __s) + { + if (!__s) + __out.setstate(ios_base::badbit); + else + __ostream_insert(__out, __s, + static_cast<streamsize>(_Traits::length(__s))); + return __out; + } + + // Signed and unsigned + template<class _Traits> + inline basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s) + { return (__out << reinterpret_cast<const char*>(__s)); } + + template<class _Traits> + inline basic_ostream<char, _Traits> & + operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s) + { return (__out << reinterpret_cast<const char*>(__s)); } + //@} + + // [27.6.2.7] standard basic_ostream manipulators + /** + * @brief Write a newline and flush the stream. + * + * This manipulator is often mistakenly used when a simple newline is + * desired, leading to poor buffering performance. See + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 for more + * on this subject. + */ + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT, _Traits>& + endl(basic_ostream<_CharT, _Traits>& __os) + { return flush(__os.put(__os.widen('\n'))); } + + /** + * @brief Write a null character into the output sequence. + * + * "Null character" is @c CharT() by definition. For CharT of @c char, + * this correctly writes the ASCII @c NUL character string terminator. + */ + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT, _Traits>& + ends(basic_ostream<_CharT, _Traits>& __os) + { return __os.put(_CharT()); } + + /** + * @brief Flushes the output stream. + * + * This manipulator simply calls the stream's @c flush() member function. + */ + template<typename _CharT, typename _Traits> + inline basic_ostream<_CharT, _Traits>& + flush(basic_ostream<_CharT, _Traits>& __os) + { return __os.flush(); } + +_GLIBCXX_END_NAMESPACE + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/ostream.tcc> +#endif + +#endif /* _GLIBCXX_OSTREAM */ diff --git a/libstdc++/include/std/std_queue.h b/libstdc++/include/std/std_queue.h new file mode 100644 index 0000000..1242a06 --- /dev/null +++ b/libstdc++/include/std/std_queue.h @@ -0,0 +1,77 @@ +// <queue> -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/queue + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_QUEUE +#define _GLIBCXX_QUEUE 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/functexcept.h> +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_heap.h> +#include <bits/stl_function.h> +#include <deque> +#include <vector> +#include <bits/stl_queue.h> + +#endif /* _GLIBCXX_QUEUE */ diff --git a/libstdc++/include/std/std_set.h b/libstdc++/include/std/std_set.h new file mode 100644 index 0000000..65ebe8a --- /dev/null +++ b/libstdc++/include/std/std_set.h @@ -0,0 +1,73 @@ +// <set> -*- C++ -*- + +// Copyright (C) 2001, 2002 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/set + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_SET +#define _GLIBCXX_SET 1 + +#pragma GCC system_header + +#include <bits/stl_tree.h> +#include <bits/stl_set.h> +#include <bits/stl_multiset.h> + +#ifdef _GLIBCXX_DEBUG +# include <debug/set> +#endif + +#endif /* _GLIBCXX_SET */ diff --git a/libstdc++/include/std/std_sstream.h b/libstdc++/include/std/std_sstream.h new file mode 100644 index 0000000..a09815c --- /dev/null +++ b/libstdc++/include/std/std_sstream.h @@ -0,0 +1,591 @@ +// String based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file sstream + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 27.7 String-based streams +// + +#ifndef _GLIBCXX_SSTREAM +#define _GLIBCXX_SSTREAM 1 + +#pragma GCC system_header + +#include <istream> +#include <ostream> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // [27.7.1] template class basic_stringbuf + /** + * @brief The actual work of input and output (for std::string). + * + * This class associates either or both of its input and output sequences + * with a sequence of characters, which can be initialized from, or made + * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) + * + * For this class, open modes (of type @c ios_base::openmode) have + * @c in set if the input sequence can be read, and @c out set if the + * output sequence can be written. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + class basic_stringbuf : public basic_streambuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type + typedef _Alloc allocator_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + typedef basic_streambuf<char_type, traits_type> __streambuf_type; + typedef basic_string<char_type, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + + protected: + /** + * @if maint + * Place to stash in || out || in | out settings for current stringbuf. + * @endif + */ + ios_base::openmode _M_mode; + + // Data Members: + __string_type _M_string; + + public: + // Constructors: + /** + * @brief Starts with an empty string buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * The default constructor initializes the parent class using its + * own default ctor. + */ + explicit + basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) + : __streambuf_type(), _M_mode(__mode), _M_string() + { } + + /** + * @brief Starts with an existing string buffer. + * @param str A string to copy as a starting buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * This constructor initializes the parent class using its + * own default ctor. + */ + explicit + basic_stringbuf(const __string_type& __str, + ios_base::openmode __mode = ios_base::in | ios_base::out) + : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size()) + { _M_stringbuf_init(__mode); } + + // Get and set: + /** + * @brief Copying out the string buffer. + * @return A copy of one of the underlying sequences. + * + * "If the buffer is only created in input mode, the underlying + * character sequence is equal to the input sequence; otherwise, it + * is equal to the output sequence." [27.7.1.2]/1 + */ + __string_type + str() const + { + __string_type __ret; + if (this->pptr()) + { + // The current egptr() may not be the actual string end. + if (this->pptr() > this->egptr()) + __ret = __string_type(this->pbase(), this->pptr()); + else + __ret = __string_type(this->pbase(), this->egptr()); + } + else + __ret = _M_string; + return __ret; + } + + /** + * @brief Setting a new buffer. + * @param s The string to use as a new sequence. + * + * Deallocates any previous stored sequence, then copies @a s to + * use as a new one. + */ + void + str(const __string_type& __s) + { + // Cannot use _M_string = __s, since v3 strings are COW. + _M_string.assign(__s.data(), __s.size()); + _M_stringbuf_init(_M_mode); + } + + protected: + // Common initialization code goes here. + void + _M_stringbuf_init(ios_base::openmode __mode) + { + _M_mode = __mode; + __size_type __len = 0; + if (_M_mode & (ios_base::ate | ios_base::app)) + __len = _M_string.size(); + _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); + } + + virtual streamsize + showmanyc() + { + streamsize __ret = -1; + if (_M_mode & ios_base::in) + { + _M_update_egptr(); + __ret = this->egptr() - this->gptr(); + } + return __ret; + } + + virtual int_type + underflow(); + + virtual int_type + pbackfail(int_type __c = traits_type::eof()); + + virtual int_type + overflow(int_type __c = traits_type::eof()); + + /** + * @brief Manipulates the buffer. + * @param s Pointer to a buffer area. + * @param n Size of @a s. + * @return @c this + * + * If no buffer has already been created, and both @a s and @a n are + * non-zero, then @c s is used as a buffer; see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 + * for more. + */ + virtual __streambuf_type* + setbuf(char_type* __s, streamsize __n) + { + if (__s && __n >= 0) + { + // This is implementation-defined behavior, and assumes + // that an external char_type array of length __n exists + // and has been pre-allocated. If this is not the case, + // things will quickly blow up. + + // Step 1: Destroy the current internal array. + _M_string.clear(); + + // Step 2: Use the external array. + _M_sync(__s, __n, 0); + } + return this; + } + + virtual pos_type + seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + virtual pos_type + seekpos(pos_type __sp, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + // Internal function for correctly updating the internal buffer + // for a particular _M_string, due to initialization or re-sizing + // of an existing _M_string. + void + _M_sync(char_type* __base, __size_type __i, __size_type __o); + + // Internal function for correctly updating egptr() to the actual + // string end. + void + _M_update_egptr() + { + const bool __testin = _M_mode & ios_base::in; + if (this->pptr() && this->pptr() > this->egptr()) + if (__testin) + this->setg(this->eback(), this->gptr(), this->pptr()); + else + this->setg(this->pptr(), this->pptr(), this->pptr()); + } + }; + + + // [27.7.2] Template class basic_istringstream + /** + * @brief Controlling input for std::string. + * + * This class supports reading from objects of type std::basic_string, + * using the inherited functions from std::basic_istream. To control + * the associated sequence, an instance of std::basic_stringbuf is used, + * which this page refers to as @c sb. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + class basic_istringstream : public basic_istream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type + typedef _Alloc allocator_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; + typedef basic_istream<char_type, traits_type> __istream_type; + + private: + __stringbuf_type _M_stringbuf; + + public: + // Constructors: + /** + * @brief Default constructor starts with an empty string buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * @c ios_base::in is automatically included in @a mode. + * + * Initializes @c sb using @c mode|in, and passes @c &sb to the base + * class initializer. Does not allocate any buffer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_istringstream(ios_base::openmode __mode = ios_base::in) + : __istream_type(), _M_stringbuf(__mode | ios_base::in) + { this->init(&_M_stringbuf); } + + /** + * @brief Starts with an existing string buffer. + * @param str A string to copy as a starting buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * @c ios_base::in is automatically included in @a mode. + * + * Initializes @c sb using @a str and @c mode|in, and passes @c &sb + * to the base class initializer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_istringstream(const __string_type& __str, + ios_base::openmode __mode = ios_base::in) + : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) + { this->init(&_M_stringbuf); } + + /** + * @brief The destructor does nothing. + * + * The buffer is deallocated by the stringbuf object, not the + * formatting stream. + */ + ~basic_istringstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_stringbuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __stringbuf_type* + rdbuf() const + { return const_cast<__stringbuf_type*>(&_M_stringbuf); } + + /** + * @brief Copying out the string buffer. + * @return @c rdbuf()->str() + */ + __string_type + str() const + { return _M_stringbuf.str(); } + + /** + * @brief Setting a new buffer. + * @param s The string to use as a new sequence. + * + * Calls @c rdbuf()->str(s). + */ + void + str(const __string_type& __s) + { _M_stringbuf.str(__s); } + }; + + + // [27.7.3] Template class basic_ostringstream + /** + * @brief Controlling output for std::string. + * + * This class supports writing to objects of type std::basic_string, + * using the inherited functions from std::basic_ostream. To control + * the associated sequence, an instance of std::basic_stringbuf is used, + * which this page refers to as @c sb. + */ + template <typename _CharT, typename _Traits, typename _Alloc> + class basic_ostringstream : public basic_ostream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type + typedef _Alloc allocator_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; + typedef basic_ostream<char_type, traits_type> __ostream_type; + + private: + __stringbuf_type _M_stringbuf; + + public: + // Constructors/destructor: + /** + * @brief Default constructor starts with an empty string buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * @c ios_base::out is automatically included in @a mode. + * + * Initializes @c sb using @c mode|out, and passes @c &sb to the base + * class initializer. Does not allocate any buffer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_ostringstream(ios_base::openmode __mode = ios_base::out) + : __ostream_type(), _M_stringbuf(__mode | ios_base::out) + { this->init(&_M_stringbuf); } + + /** + * @brief Starts with an existing string buffer. + * @param str A string to copy as a starting buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * @c ios_base::out is automatically included in @a mode. + * + * Initializes @c sb using @a str and @c mode|out, and passes @c &sb + * to the base class initializer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_ostringstream(const __string_type& __str, + ios_base::openmode __mode = ios_base::out) + : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) + { this->init(&_M_stringbuf); } + + /** + * @brief The destructor does nothing. + * + * The buffer is deallocated by the stringbuf object, not the + * formatting stream. + */ + ~basic_ostringstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_stringbuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __stringbuf_type* + rdbuf() const + { return const_cast<__stringbuf_type*>(&_M_stringbuf); } + + /** + * @brief Copying out the string buffer. + * @return @c rdbuf()->str() + */ + __string_type + str() const + { return _M_stringbuf.str(); } + + /** + * @brief Setting a new buffer. + * @param s The string to use as a new sequence. + * + * Calls @c rdbuf()->str(s). + */ + void + str(const __string_type& __s) + { _M_stringbuf.str(__s); } + }; + + + // [27.7.4] Template class basic_stringstream + /** + * @brief Controlling input and output for std::string. + * + * This class supports reading from and writing to objects of type + * std::basic_string, using the inherited functions from + * std::basic_iostream. To control the associated sequence, an instance + * of std::basic_stringbuf is used, which this page refers to as @c sb. + */ + template <typename _CharT, typename _Traits, typename _Alloc> + class basic_stringstream : public basic_iostream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type + typedef _Alloc allocator_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard Types: + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; + typedef basic_iostream<char_type, traits_type> __iostream_type; + + private: + __stringbuf_type _M_stringbuf; + + public: + // Constructors/destructors + /** + * @brief Default constructor starts with an empty string buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * Initializes @c sb using @c mode, and passes @c &sb to the base + * class initializer. Does not allocate any buffer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) + : __iostream_type(), _M_stringbuf(__m) + { this->init(&_M_stringbuf); } + + /** + * @brief Starts with an existing string buffer. + * @param str A string to copy as a starting buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * Initializes @c sb using @a str and @c mode, and passes @c &sb + * to the base class initializer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_stringstream(const __string_type& __str, + ios_base::openmode __m = ios_base::out | ios_base::in) + : __iostream_type(), _M_stringbuf(__str, __m) + { this->init(&_M_stringbuf); } + + /** + * @brief The destructor does nothing. + * + * The buffer is deallocated by the stringbuf object, not the + * formatting stream. + */ + ~basic_stringstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_stringbuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __stringbuf_type* + rdbuf() const + { return const_cast<__stringbuf_type*>(&_M_stringbuf); } + + /** + * @brief Copying out the string buffer. + * @return @c rdbuf()->str() + */ + __string_type + str() const + { return _M_stringbuf.str(); } + + /** + * @brief Setting a new buffer. + * @param s The string to use as a new sequence. + * + * Calls @c rdbuf()->str(s). + */ + void + str(const __string_type& __s) + { _M_stringbuf.str(__s); } + }; + +_GLIBCXX_END_NAMESPACE + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/sstream.tcc> +#endif + +#endif /* _GLIBCXX_SSTREAM */ diff --git a/libstdc++/include/std/std_stack.h b/libstdc++/include/std/std_stack.h new file mode 100644 index 0000000..396f62e --- /dev/null +++ b/libstdc++/include/std/std_stack.h @@ -0,0 +1,72 @@ +// <stack> -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/stack + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_STACK +#define _GLIBCXX_STACK 1 + +#pragma GCC system_header + +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <deque> +#include <bits/stl_stack.h> + +#endif /* _GLIBCXX_STACK */ diff --git a/libstdc++/include/std/std_stdexcept.h b/libstdc++/include/std/std_stdexcept.h new file mode 100644 index 0000000..2d56b38 --- /dev/null +++ b/libstdc++/include/std/std_stdexcept.h @@ -0,0 +1,148 @@ +// Standard exception classes -*- C++ -*- + +// Copyright (C) 2001, 2002, 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. + +/** @file stdexcept + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 19.1 Exception classes +// + +#ifndef _GLIBCXX_STDEXCEPT +#define _GLIBCXX_STDEXCEPT 1 + +#pragma GCC system_header + +#include <exception> +#include <string> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** Logic errors represent problems in the internal logic of a program; + * in theory, these are preventable, and even detectable before the + * program runs (e.g., violations of class invariants). + * @brief One of two subclasses of exception. + */ + class logic_error : public exception + { + string _M_msg; + + public: + /** Takes a character string describing the error. */ + explicit + logic_error(const string& __arg); + + virtual + ~logic_error() throw(); + + /** Returns a C-style character string describing the general cause of + * the current error (the same string passed to the ctor). */ + virtual const char* + what() const throw(); + }; + + /** Thrown by the library, or by you, to report domain errors (domain in + * the mathmatical sense). */ + class domain_error : public logic_error + { + public: + explicit domain_error(const string& __arg); + }; + + /** Thrown to report invalid arguments to functions. */ + class invalid_argument : public logic_error + { + public: + explicit invalid_argument(const string& __arg); + }; + + /** Thrown when an object is constructed that would exceed its maximum + * permitted size (e.g., a basic_string instance). */ + class length_error : public logic_error + { + public: + explicit length_error(const string& __arg); + }; + + /** This represents an argument whose value is not within the expected + * range (e.g., boundary checks in basic_string). */ + class out_of_range : public logic_error + { + public: + explicit out_of_range(const string& __arg); + }; + + /** Runtime errors represent problems outside the scope of a program; + * they cannot be easily predicted and can generally only be caught as + * the program executes. + * @brief One of two subclasses of exception. + */ + class runtime_error : public exception + { + string _M_msg; + + public: + /** Takes a character string describing the error. */ + explicit + runtime_error(const string& __arg); + + virtual + ~runtime_error() throw(); + + /** Returns a C-style character string describing the general cause of + * the current error (the same string passed to the ctor). */ + virtual const char* + what() const throw(); + }; + + /** Thrown to indicate range errors in internal computations. */ + class range_error : public runtime_error + { + public: + explicit range_error(const string& __arg); + }; + + /** Thrown to indicate arithmetic overflow. */ + class overflow_error : public runtime_error + { + public: + explicit overflow_error(const string& __arg); + }; + + /** Thrown to indicate arithmetic underflow. */ + class underflow_error : public runtime_error + { + public: + explicit underflow_error(const string& __arg); + }; + +_GLIBCXX_END_NAMESPACE + +#endif /* _GLIBCXX_STDEXCEPT */ diff --git a/libstdc++/include/std/std_streambuf.h b/libstdc++/include/std/std_streambuf.h new file mode 100644 index 0000000..9de7907 --- /dev/null +++ b/libstdc++/include/std/std_streambuf.h @@ -0,0 +1,823 @@ +// Stream buffer classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 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. + +/** @file streambuf + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 27.5 Stream buffers +// + +#ifndef _GLIBXX_STREAMBUF +#define _GLIBXX_STREAMBUF 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <iosfwd> +#include <bits/localefwd.h> +#include <bits/ios_base.h> +#include <bits/cpp_type_traits.h> +#include <ext/type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @if maint + * Does stuff. + * @endif + */ + template<typename _CharT, typename _Traits> + streamsize + __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>*, + basic_streambuf<_CharT, _Traits>*, bool&); + + /** + * @brief The actual work of input and output (interface). + * + * This is a base class. Derived stream buffers each control a + * pair of character sequences: one for input, and one for output. + * + * Section [27.5.1] of the standard describes the requirements and + * behavior of stream buffer classes. That section (three paragraphs) + * is reproduced here, for simplicity and accuracy. + * + * -# Stream buffers can impose various constraints on the sequences + * they control. Some constraints are: + * - The controlled input sequence can be not readable. + * - The controlled output sequence can be not writable. + * - The controlled sequences can be associated with the contents of + * other representations for character sequences, such as external + * files. + * - The controlled sequences can support operations @e directly to or + * from associated sequences. + * - The controlled sequences can impose limitations on how the + * program can read characters from a sequence, write characters to + * a sequence, put characters back into an input sequence, or alter + * the stream position. + * . + * -# Each sequence is characterized by three pointers which, if non-null, + * all point into the same @c charT array object. The array object + * represents, at any moment, a (sub)sequence of characters from the + * sequence. Operations performed on a sequence alter the values + * stored in these pointers, perform reads and writes directly to or + * from associated sequences, and alter "the stream position" and + * conversion state as needed to maintain this subsequence relationship. + * The three pointers are: + * - the <em>beginning pointer</em>, or lowest element address in the + * array (called @e xbeg here); + * - the <em>next pointer</em>, or next element address that is a + * current candidate for reading or writing (called @e xnext here); + * - the <em>end pointer</em>, or first element address beyond the + * end of the array (called @e xend here). + * . + * -# The following semantic constraints shall always apply for any set + * of three pointers for a sequence, using the pointer names given + * immediately above: + * - If @e xnext is not a null pointer, then @e xbeg and @e xend shall + * also be non-null pointers into the same @c charT array, as + * described above; otherwise, @e xbeg and @e xend shall also be null. + * - If @e xnext is not a null pointer and @e xnext < @e xend for an + * output sequence, then a <em>write position</em> is available. + * In this case, @e *xnext shall be assignable as the next element + * to write (to put, or to store a character value, into the sequence). + * - If @e xnext is not a null pointer and @e xbeg < @e xnext for an + * input sequence, then a <em>putback position</em> is available. + * In this case, @e xnext[-1] shall have a defined value and is the + * next (preceding) element to store a character that is put back + * into the input sequence. + * - If @e xnext is not a null pointer and @e xnext< @e xend for an + * input sequence, then a <em>read position</em> is available. + * In this case, @e *xnext shall have a defined value and is the + * next element to read (to get, or to obtain a character value, + * from the sequence). + */ + template<typename _CharT, typename _Traits> + class basic_streambuf + { + public: + //@{ + /** + * These are standard types. They permit a standardized way of + * referring to names of (or names dependant on) the template + * parameters, which are specific to the implementation. + */ + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + //@} + + //@{ + /** + * @if maint + * This is a non-standard type. + * @endif + */ + typedef basic_streambuf<char_type, traits_type> __streambuf_type; + //@} + + friend class basic_ios<char_type, traits_type>; + friend class basic_istream<char_type, traits_type>; + friend class basic_ostream<char_type, traits_type>; + friend class istreambuf_iterator<char_type, traits_type>; + friend class ostreambuf_iterator<char_type, traits_type>; + + friend streamsize + __copy_streambufs_eof<>(__streambuf_type*, __streambuf_type*, bool&); + + template<typename _CharT2> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + _CharT2*>::__type + __copy_aux(istreambuf_iterator<_CharT2>, + istreambuf_iterator<_CharT2>, _CharT2*); + + template<typename _CharT2> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + istreambuf_iterator<_CharT2> >::__type + find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, + const _CharT2&); + + template<typename _CharT2, typename _Traits2> + friend basic_istream<_CharT2, _Traits2>& + operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); + + template<typename _CharT2, typename _Traits2, typename _Alloc> + friend basic_istream<_CharT2, _Traits2>& + operator>>(basic_istream<_CharT2, _Traits2>&, + basic_string<_CharT2, _Traits2, _Alloc>&); + + template<typename _CharT2, typename _Traits2, typename _Alloc> + friend basic_istream<_CharT2, _Traits2>& + getline(basic_istream<_CharT2, _Traits2>&, + basic_string<_CharT2, _Traits2, _Alloc>&, _CharT2); + + protected: + //@{ + /** + * @if maint + * This is based on _IO_FILE, just reordered to be more consistent, + * and is intended to be the most minimal abstraction for an + * internal buffer. + * - get == input == read + * - put == output == write + * @endif + */ + char_type* _M_in_beg; // Start of get area. + char_type* _M_in_cur; // Current read area. + char_type* _M_in_end; // End of get area. + char_type* _M_out_beg; // Start of put area. + char_type* _M_out_cur; // Current put area. + char_type* _M_out_end; // End of put area. + + /** + * @if maint + * Current locale setting. + * @endif + */ + locale _M_buf_locale; + + public: + /// Destructor deallocates no buffer space. + virtual + ~basic_streambuf() + { } + + // [27.5.2.2.1] locales + /** + * @brief Entry point for imbue(). + * @param loc The new locale. + * @return The previous locale. + * + * Calls the derived imbue(loc). + */ + locale + pubimbue(const locale &__loc) + { + locale __tmp(this->getloc()); + this->imbue(__loc); + _M_buf_locale = __loc; + return __tmp; + } + + /** + * @brief Locale access. + * @return The current locale in effect. + * + * If pubimbue(loc) has been called, then the most recent @c loc + * is returned. Otherwise the global locale in effect at the time + * of construction is returned. + */ + locale + getloc() const + { return _M_buf_locale; } + + // [27.5.2.2.2] buffer management and positioning + //@{ + /** + * @brief Entry points for derived buffer functions. + * + * The public versions of @c pubfoo dispatch to the protected + * derived @c foo member functions, passing the arguments (if any) + * and returning the result unchanged. + */ + __streambuf_type* + pubsetbuf(char_type* __s, streamsize __n) + { return this->setbuf(__s, __n); } + + pos_type + pubseekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { return this->seekoff(__off, __way, __mode); } + + pos_type + pubseekpos(pos_type __sp, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { return this->seekpos(__sp, __mode); } + + int + pubsync() { return this->sync(); } + //@} + + // [27.5.2.2.3] get area + /** + * @brief Looking ahead into the stream. + * @return The number of characters available. + * + * If a read position is available, returns the number of characters + * available for reading before the buffer must be refilled. + * Otherwise returns the derived @c showmanyc(). + */ + streamsize + in_avail() + { + const streamsize __ret = this->egptr() - this->gptr(); + return __ret ? __ret : this->showmanyc(); + } + + /** + * @brief Getting the next character. + * @return The next character, or eof. + * + * Calls @c sbumpc(), and if that function returns + * @c traits::eof(), so does this function. Otherwise, @c sgetc(). + */ + int_type + snextc() + { + int_type __ret = traits_type::eof(); + if (__builtin_expect(!traits_type::eq_int_type(this->sbumpc(), + __ret), true)) + __ret = this->sgetc(); + return __ret; + } + + /** + * @brief Getting the next character. + * @return The next character, or eof. + * + * If the input read position is available, returns that character + * and increments the read pointer, otherwise calls and returns + * @c uflow(). + */ + int_type + sbumpc() + { + int_type __ret; + if (__builtin_expect(this->gptr() < this->egptr(), true)) + { + __ret = traits_type::to_int_type(*this->gptr()); + this->gbump(1); + } + else + __ret = this->uflow(); + return __ret; + } + + /** + * @brief Getting the next character. + * @return The next character, or eof. + * + * If the input read position is available, returns that character, + * otherwise calls and returns @c underflow(). Does not move the + * read position after fetching the character. + */ + int_type + sgetc() + { + int_type __ret; + if (__builtin_expect(this->gptr() < this->egptr(), true)) + __ret = traits_type::to_int_type(*this->gptr()); + else + __ret = this->underflow(); + return __ret; + } + + /** + * @brief Entry point for xsgetn. + * @param s A buffer area. + * @param n A count. + * + * Returns xsgetn(s,n). The effect is to fill @a s[0] through + * @a s[n-1] with characters from the input sequence, if possible. + */ + streamsize + sgetn(char_type* __s, streamsize __n) + { return this->xsgetn(__s, __n); } + + // [27.5.2.2.4] putback + /** + * @brief Pushing characters back into the input stream. + * @param c The character to push back. + * @return The previous character, if possible. + * + * Similar to sungetc(), but @a c is pushed onto the stream instead + * of "the previous character". If successful, the next character + * fetched from the input stream will be @a c. + */ + int_type + sputbackc(char_type __c) + { + int_type __ret; + const bool __testpos = this->eback() < this->gptr(); + if (__builtin_expect(!__testpos || + !traits_type::eq(__c, this->gptr()[-1]), false)) + __ret = this->pbackfail(traits_type::to_int_type(__c)); + else + { + this->gbump(-1); + __ret = traits_type::to_int_type(*this->gptr()); + } + return __ret; + } + + /** + * @brief Moving backwards in the input stream. + * @return The previous character, if possible. + * + * If a putback position is available, this function decrements the + * input pointer and returns that character. Otherwise, calls and + * returns pbackfail(). The effect is to "unget" the last character + * "gotten". + */ + int_type + sungetc() + { + int_type __ret; + if (__builtin_expect(this->eback() < this->gptr(), true)) + { + this->gbump(-1); + __ret = traits_type::to_int_type(*this->gptr()); + } + else + __ret = this->pbackfail(); + return __ret; + } + + // [27.5.2.2.5] put area + /** + * @brief Entry point for all single-character output functions. + * @param c A character to output. + * @return @a c, if possible. + * + * One of two public output functions. + * + * If a write position is available for the output sequence (i.e., + * the buffer is not full), stores @a c in that position, increments + * the position, and returns @c traits::to_int_type(c). If a write + * position is not available, returns @c overflow(c). + */ + int_type + sputc(char_type __c) + { + int_type __ret; + if (__builtin_expect(this->pptr() < this->epptr(), true)) + { + *this->pptr() = __c; + this->pbump(1); + __ret = traits_type::to_int_type(__c); + } + else + __ret = this->overflow(traits_type::to_int_type(__c)); + return __ret; + } + + /** + * @brief Entry point for all single-character output functions. + * @param s A buffer read area. + * @param n A count. + * + * One of two public output functions. + * + * + * Returns xsputn(s,n). The effect is to write @a s[0] through + * @a s[n-1] to the output sequence, if possible. + */ + streamsize + sputn(const char_type* __s, streamsize __n) + { return this->xsputn(__s, __n); } + + protected: + /** + * @brief Base constructor. + * + * Only called from derived constructors, and sets up all the + * buffer data to zero, including the pointers described in the + * basic_streambuf class description. Note that, as a result, + * - the class starts with no read nor write positions available, + * - this is not an error + */ + basic_streambuf() + : _M_in_beg(0), _M_in_cur(0), _M_in_end(0), + _M_out_beg(0), _M_out_cur(0), _M_out_end(0), + _M_buf_locale(locale()) + { } + + // [27.5.2.3.1] get area access + //@{ + /** + * @brief Access to the get area. + * + * These functions are only available to other protected functions, + * including derived classes. + * + * - eback() returns the beginning pointer for the input sequence + * - gptr() returns the next pointer for the input sequence + * - egptr() returns the end pointer for the input sequence + */ + char_type* + eback() const { return _M_in_beg; } + + char_type* + gptr() const { return _M_in_cur; } + + char_type* + egptr() const { return _M_in_end; } + //@} + + /** + * @brief Moving the read position. + * @param n The delta by which to move. + * + * This just advances the read position without returning any data. + */ + void + gbump(int __n) { _M_in_cur += __n; } + + /** + * @brief Setting the three read area pointers. + * @param gbeg A pointer. + * @param gnext A pointer. + * @param gend A pointer. + * @post @a gbeg == @c eback(), @a gnext == @c gptr(), and + * @a gend == @c egptr() + */ + void + setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) + { + _M_in_beg = __gbeg; + _M_in_cur = __gnext; + _M_in_end = __gend; + } + + // [27.5.2.3.2] put area access + //@{ + /** + * @brief Access to the put area. + * + * These functions are only available to other protected functions, + * including derived classes. + * + * - pbase() returns the beginning pointer for the output sequence + * - pptr() returns the next pointer for the output sequence + * - epptr() returns the end pointer for the output sequence + */ + char_type* + pbase() const { return _M_out_beg; } + + char_type* + pptr() const { return _M_out_cur; } + + char_type* + epptr() const { return _M_out_end; } + //@} + + /** + * @brief Moving the write position. + * @param n The delta by which to move. + * + * This just advances the write position without returning any data. + */ + void + pbump(int __n) { _M_out_cur += __n; } + + /** + * @brief Setting the three write area pointers. + * @param pbeg A pointer. + * @param pend A pointer. + * @post @a pbeg == @c pbase(), @a pbeg == @c pptr(), and + * @a pend == @c epptr() + */ + void + setp(char_type* __pbeg, char_type* __pend) + { + _M_out_beg = _M_out_cur = __pbeg; + _M_out_end = __pend; + } + + // [27.5.2.4] virtual functions + // [27.5.2.4.1] locales + /** + * @brief Changes translations. + * @param loc A new locale. + * + * Translations done during I/O which depend on the current locale + * are changed by this call. The standard adds, "Between invocations + * of this function a class derived from streambuf can safely cache + * results of calls to locale functions and to members of facets + * so obtained." + * + * @note Base class version does nothing. + */ + virtual void + imbue(const locale&) + { } + + // [27.5.2.4.2] buffer management and positioning + /** + * @brief Maniuplates the buffer. + * + * Each derived class provides its own appropriate behavior. See + * the next-to-last paragraph of + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 for + * more on this function. + * + * @note Base class version does nothing, returns @c this. + */ + virtual basic_streambuf<char_type,_Traits>* + setbuf(char_type*, streamsize) + { return this; } + + /** + * @brief Alters the stream positions. + * + * Each derived class provides its own appropriate behavior. + * @note Base class version does nothing, returns a @c pos_type + * that represents an invalid stream position. + */ + virtual pos_type + seekoff(off_type, ios_base::seekdir, + ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) + { return pos_type(off_type(-1)); } + + /** + * @brief Alters the stream positions. + * + * Each derived class provides its own appropriate behavior. + * @note Base class version does nothing, returns a @c pos_type + * that represents an invalid stream position. + */ + virtual pos_type + seekpos(pos_type, + ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) + { return pos_type(off_type(-1)); } + + /** + * @brief Synchronizes the buffer arrays with the controlled sequences. + * @return -1 on failure. + * + * Each derived class provides its own appropriate behavior, + * including the definition of "failure". + * @note Base class version does nothing, returns zero. + */ + virtual int + sync() { return 0; } + + // [27.5.2.4.3] get area + /** + * @brief Investigating the data available. + * @return An estimate of the number of characters available in the + * input sequence, or -1. + * + * "If it returns a positive value, then successive calls to + * @c underflow() will not return @c traits::eof() until at least that + * number of characters have been supplied. If @c showmanyc() + * returns -1, then calls to @c underflow() or @c uflow() will fail." + * [27.5.2.4.3]/1 + * + * @note Base class version does nothing, returns zero. + * @note The standard adds that "the intention is not only that the + * calls [to underflow or uflow] will not return @c eof() but + * that they will return "immediately". + * @note The standard adds that "the morphemes of @c showmanyc are + * "es-how-many-see", not "show-manic". + */ + virtual streamsize + showmanyc() { return 0; } + + /** + * @brief Multiple character extraction. + * @param s A buffer area. + * @param n Maximum number of characters to assign. + * @return The number of characters assigned. + * + * Fills @a s[0] through @a s[n-1] with characters from the input + * sequence, as if by @c sbumpc(). Stops when either @a n characters + * have been copied, or when @c traits::eof() would be copied. + * + * It is expected that derived classes provide a more efficient + * implementation by overriding this definition. + */ + virtual streamsize + xsgetn(char_type* __s, streamsize __n); + + /** + * @brief Fetches more data from the controlled sequence. + * @return The first character from the <em>pending sequence</em>. + * + * Informally, this function is called when the input buffer is + * exhausted (or does not exist, as buffering need not actually be + * done). If a buffer exists, it is "refilled". In either case, the + * next available character is returned, or @c traits::eof() to + * indicate a null pending sequence. + * + * For a formal definiton of the pending sequence, see a good text + * such as Langer & Kreft, or [27.5.2.4.3]/7-14. + * + * A functioning input streambuf can be created by overriding only + * this function (no buffer area will be used). For an example, see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#6 + * + * @note Base class version does nothing, returns eof(). + */ + virtual int_type + underflow() + { return traits_type::eof(); } + + /** + * @brief Fetches more data from the controlled sequence. + * @return The first character from the <em>pending sequence</em>. + * + * Informally, this function does the same thing as @c underflow(), + * and in fact is required to call that function. It also returns + * the new character, like @c underflow() does. However, this + * function also moves the read position forward by one. + */ + virtual int_type + uflow() + { + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(this->underflow(), + __ret); + if (!__testeof) + { + __ret = traits_type::to_int_type(*this->gptr()); + this->gbump(1); + } + return __ret; + } + + // [27.5.2.4.4] putback + /** + * @brief Tries to back up the input sequence. + * @param c The character to be inserted back into the sequence. + * @return eof() on failure, "some other value" on success + * @post The constraints of @c gptr(), @c eback(), and @c pptr() + * are the same as for @c underflow(). + * + * @note Base class version does nothing, returns eof(). + */ + virtual int_type + pbackfail(int_type /* __c */ = traits_type::eof()) + { return traits_type::eof(); } + + // Put area: + /** + * @brief Multiple character insertion. + * @param s A buffer area. + * @param n Maximum number of characters to write. + * @return The number of characters written. + * + * Writes @a s[0] through @a s[n-1] to the output sequence, as if + * by @c sputc(). Stops when either @a n characters have been + * copied, or when @c sputc() would return @c traits::eof(). + * + * It is expected that derived classes provide a more efficient + * implementation by overriding this definition. + */ + virtual streamsize + xsputn(const char_type* __s, streamsize __n); + + /** + * @brief Consumes data from the buffer; writes to the + * controlled sequence. + * @param c An additional character to consume. + * @return eof() to indicate failure, something else (usually + * @a c, or not_eof()) + * + * Informally, this function is called when the output buffer is full + * (or does not exist, as buffering need not actually be done). If a + * buffer exists, it is "consumed", with "some effect" on the + * controlled sequence. (Typically, the buffer is written out to the + * sequence verbatim.) In either case, the character @a c is also + * written out, if @a c is not @c eof(). + * + * For a formal definiton of this function, see a good text + * such as Langer & Kreft, or [27.5.2.4.5]/3-7. + * + * A functioning output streambuf can be created by overriding only + * this function (no buffer area will be used). + * + * @note Base class version does nothing, returns eof(). + */ + virtual int_type + overflow(int_type /* __c */ = traits_type::eof()) + { return traits_type::eof(); } + +#ifdef _GLIBCXX_DEPRECATED + // Annex D.6 + public: + /** + * @brief Tosses a character. + * + * Advances the read pointer, ignoring the character that would have + * been read. + * + * See http://gcc.gnu.org/ml/libstdc++/2002-05/msg00168.html + * + * @note This function has been deprecated by the standard. You + * must define @c _GLIBCXX_DEPRECATED to make this visible; see + * c++config.h. + */ + void + stossc() + { + if (this->gptr() < this->egptr()) + this->gbump(1); + else + this->uflow(); + } +#endif + + private: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // Side effect of DR 50. + basic_streambuf(const __streambuf_type& __sb) + : _M_in_beg(__sb._M_in_beg), _M_in_cur(__sb._M_in_cur), + _M_in_end(__sb._M_in_end), _M_out_beg(__sb._M_out_beg), + _M_out_cur(__sb._M_out_cur), _M_out_end(__sb._M_out_cur), + _M_buf_locale(__sb._M_buf_locale) + { } + + __streambuf_type& + operator=(const __streambuf_type&) { return *this; }; + }; + + // Explicit specialization declarations, defined in src/streambuf.cc. + template<> + streamsize + __copy_streambufs_eof(basic_streambuf<char>* __sbin, + basic_streambuf<char>* __sbout, bool& __ineof); +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + streamsize + __copy_streambufs_eof(basic_streambuf<wchar_t>* __sbin, + basic_streambuf<wchar_t>* __sbout, bool& __ineof); +#endif + +_GLIBCXX_END_NAMESPACE + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/streambuf.tcc> +#endif + +#endif /* _GLIBCXX_STREAMBUF */ diff --git a/libstdc++/include/std/std_string.h b/libstdc++/include/std/std_string.h new file mode 100644 index 0000000..3046946 --- /dev/null +++ b/libstdc++/include/std/std_string.h @@ -0,0 +1,61 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, +// 2006, 2007 +// 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. + +/** @file include/string + * This is a Standard C++ Library header. + */ + +// +// ISO C++ 14882: 21 Strings library +// + +#ifndef _GLIBCXX_STRING +#define _GLIBCXX_STRING 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/stringfwd.h> +#include <bits/char_traits.h> +#include <memory> // For allocator. +#include <bits/cpp_type_traits.h> +#include <iosfwd> // For operators >>, <<, and getline decls. +#include <bits/ostream_insert.h> +#include <bits/stl_iterator.h> +#include <bits/stl_function.h> // For less +#include <bits/basic_string.h> + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <algorithm> // for find_if +# include <bits/basic_string.tcc> +#endif + +#endif /* _GLIBCXX_STRING */ diff --git a/libstdc++/include/std/std_utility.h b/libstdc++/include/std/std_utility.h new file mode 100644 index 0000000..84c9131 --- /dev/null +++ b/libstdc++/include/std/std_utility.h @@ -0,0 +1,69 @@ +// <utility> -*- C++ -*- + +// Copyright (C) 2001, 2002 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/utility + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_UTILITY +#define _GLIBCXX_UTILITY 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/stl_relops.h> +#include <bits/stl_pair.h> + +#endif /* _GLIBCXX_UTILITY */ diff --git a/libstdc++/include/std/std_valarray.h b/libstdc++/include/std/std_valarray.h new file mode 100644 index 0000000..87f30ec --- /dev/null +++ b/libstdc++/include/std/std_valarray.h @@ -0,0 +1,1039 @@ +// The template and inlines for the -*- C++ -*- valarray class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 +// 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. + +/** @file valarray + * This is a Standard C++ Library header. + */ + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _GLIBCXX_VALARRAY +#define _GLIBCXX_VALARRAY 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <cstddef> +#include <cmath> +#include <cstdlib> +#include <numeric> +#include <algorithm> +#include <debug/debug.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<class _Clos, typename _Tp> + class _Expr; + + template<typename _Tp1, typename _Tp2> + class _ValArray; + + template<class _Oper, template<class, class> class _Meta, class _Dom> + struct _UnClos; + + template<class _Oper, + template<class, class> class _Meta1, + template<class, class> class _Meta2, + class _Dom1, class _Dom2> + class _BinClos; + + template<template<class, class> class _Meta, class _Dom> + class _SClos; + + template<template<class, class> class _Meta, class _Dom> + class _GClos; + + template<template<class, class> class _Meta, class _Dom> + class _IClos; + + template<template<class, class> class _Meta, class _Dom> + class _ValFunClos; + + template<template<class, class> class _Meta, class _Dom> + class _RefFunClos; + + template<class _Tp> class valarray; // An array of type _Tp + class slice; // BLAS-like slice out of an array + template<class _Tp> class slice_array; + class gslice; // generalized slice out of an array + template<class _Tp> class gslice_array; + template<class _Tp> class mask_array; // masked array + template<class _Tp> class indirect_array; // indirected array + +_GLIBCXX_END_NAMESPACE + +#include <bits/valarray_array.h> +#include <bits/valarray_before.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Smart array designed to support numeric processing. + * + * A valarray is an array that provides constraints intended to allow for + * effective optimization of numeric array processing by reducing the + * aliasing that can result from pointer representations. It represents a + * one-dimensional array from which different multidimensional subsets can + * be accessed and modified. + * + * @param Tp Type of object in the array. + */ + template<class _Tp> + class valarray + { + template<class _Op> + struct _UnaryOp + { + typedef typename __fun<_Op, _Tp>::result_type __rt; + typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt; + }; + public: + typedef _Tp value_type; + + // _lib.valarray.cons_ construct/destroy: + /// Construct an empty array. + valarray(); + + /// Construct an array with @a n elements. + explicit valarray(size_t); + + /// Construct an array with @a n elements initialized to @a t. + valarray(const _Tp&, size_t); + + /// Construct an array initialized to the first @a n elements of @a t. + valarray(const _Tp* __restrict__, size_t); + + /// Copy constructor. + valarray(const valarray&); + + /// Construct an array with the same size and values in @a sa. + valarray(const slice_array<_Tp>&); + + /// Construct an array with the same size and values in @a ga. + valarray(const gslice_array<_Tp>&); + + /// Construct an array with the same size and values in @a ma. + valarray(const mask_array<_Tp>&); + + /// Construct an array with the same size and values in @a ia. + valarray(const indirect_array<_Tp>&); + + template<class _Dom> + valarray(const _Expr<_Dom, _Tp>& __e); + + ~valarray(); + + // _lib.valarray.assign_ assignment: + /** + * @brief Assign elements to an array. + * + * Assign elements of array to values in @a v. Results are undefined + * if @a v does not have the same size as this array. + * + * @param v Valarray to get values from. + */ + valarray<_Tp>& operator=(const valarray<_Tp>&); + + /** + * @brief Assign elements to a value. + * + * Assign all elements of array to @a t. + * + * @param t Value for elements. + */ + valarray<_Tp>& operator=(const _Tp&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a sa. Results are undefined + * if @a sa does not have the same size as this array. + * + * @param sa Array slice to get values from. + */ + valarray<_Tp>& operator=(const slice_array<_Tp>&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a ga. Results are undefined + * if @a ga does not have the same size as this array. + * + * @param ga Array slice to get values from. + */ + valarray<_Tp>& operator=(const gslice_array<_Tp>&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a ma. Results are undefined + * if @a ma does not have the same size as this array. + * + * @param ma Array slice to get values from. + */ + valarray<_Tp>& operator=(const mask_array<_Tp>&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a ia. Results are undefined + * if @a ia does not have the same size as this array. + * + * @param ia Array slice to get values from. + */ + valarray<_Tp>& operator=(const indirect_array<_Tp>&); + + template<class _Dom> valarray<_Tp>& + operator= (const _Expr<_Dom, _Tp>&); + + // _lib.valarray.access_ element access: + /** + * Return a reference to the i'th array element. + * + * @param i Index of element to return. + * @return Reference to the i'th element. + */ + _Tp& operator[](size_t); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 389. Const overload of valarray::operator[] returns by value. + const _Tp& operator[](size_t) const; + + // _lib.valarray.sub_ subset operations: + /** + * @brief Return an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the slice argument. The new valarray has the same size + * as the input slice. @see slice. + * + * @param s The source slice. + * @return New valarray containing elements in @a s. + */ + _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the slice argument. The new valarray has the same size + * as the input slice. @see slice. + * + * @param s The source slice. + * @return New valarray containing elements in @a s. + */ + slice_array<_Tp> operator[](slice); + + /** + * @brief Return an array subset. + * + * Returns a slice_array referencing the elements of the array + * indicated by the slice argument. @see gslice. + * + * @param s The source slice. + * @return Slice_array referencing elements indicated by @a s. + */ + _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice&) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the gslice argument. The new valarray has + * the same size as the input gslice. @see gslice. + * + * @param s The source gslice. + * @return New valarray containing elements in @a s. + */ + gslice_array<_Tp> operator[](const gslice&); + + /** + * @brief Return an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the argument. The input is a valarray of bool which + * represents a bitmask indicating which elements should be copied into + * the new valarray. Each element of the array is added to the return + * valarray if the corresponding element of the argument is true. + * + * @param m The valarray bitmask. + * @return New valarray containing elements indicated by @a m. + */ + valarray<_Tp> operator[](const valarray<bool>&) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns a new mask_array referencing the elements of the array + * indicated by the argument. The input is a valarray of bool which + * represents a bitmask indicating which elements are part of the + * subset. Elements of the array are part of the subset if the + * corresponding element of the argument is true. + * + * @param m The valarray bitmask. + * @return New valarray containing elements indicated by @a m. + */ + mask_array<_Tp> operator[](const valarray<bool>&); + + /** + * @brief Return an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the argument. The elements in the argument are + * interpreted as the indices of elements of this valarray to copy to + * the return valarray. + * + * @param i The valarray element index list. + * @return New valarray containing elements in @a s. + */ + _Expr<_IClos<_ValArray, _Tp>, _Tp> + operator[](const valarray<size_t>&) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns an indirect_array referencing the elements of the array + * indicated by the argument. The elements in the argument are + * interpreted as the indices of elements of this valarray to include + * in the subset. The returned indirect_array refers to these + * elements. + * + * @param i The valarray element index list. + * @return Indirect_array referencing elements in @a i. + */ + indirect_array<_Tp> operator[](const valarray<size_t>&); + + // _lib.valarray.unary_ unary operators: + /// Return a new valarray by applying unary + to each element. + typename _UnaryOp<__unary_plus>::_Rt operator+() const; + + /// Return a new valarray by applying unary - to each element. + typename _UnaryOp<__negate>::_Rt operator-() const; + + /// Return a new valarray by applying unary ~ to each element. + typename _UnaryOp<__bitwise_not>::_Rt operator~() const; + + /// Return a new valarray by applying unary ! to each element. + typename _UnaryOp<__logical_not>::_Rt operator!() const; + + // _lib.valarray.cassign_ computed assignment: + /// Multiply each element of array by @a t. + valarray<_Tp>& operator*=(const _Tp&); + + /// Divide each element of array by @a t. + valarray<_Tp>& operator/=(const _Tp&); + + /// Set each element e of array to e % @a t. + valarray<_Tp>& operator%=(const _Tp&); + + /// Add @a t to each element of array. + valarray<_Tp>& operator+=(const _Tp&); + + /// Subtract @a t to each element of array. + valarray<_Tp>& operator-=(const _Tp&); + + /// Set each element e of array to e ^ @a t. + valarray<_Tp>& operator^=(const _Tp&); + + /// Set each element e of array to e & @a t. + valarray<_Tp>& operator&=(const _Tp&); + + /// Set each element e of array to e | @a t. + valarray<_Tp>& operator|=(const _Tp&); + + /// Left shift each element e of array by @a t bits. + valarray<_Tp>& operator<<=(const _Tp&); + + /// Right shift each element e of array by @a t bits. + valarray<_Tp>& operator>>=(const _Tp&); + + /// Multiply elements of array by corresponding elements of @a v. + valarray<_Tp>& operator*=(const valarray<_Tp>&); + + /// Divide elements of array by corresponding elements of @a v. + valarray<_Tp>& operator/=(const valarray<_Tp>&); + + /// Modulo elements of array by corresponding elements of @a v. + valarray<_Tp>& operator%=(const valarray<_Tp>&); + + /// Add corresponding elements of @a v to elements of array. + valarray<_Tp>& operator+=(const valarray<_Tp>&); + + /// Subtract corresponding elements of @a v from elements of array. + valarray<_Tp>& operator-=(const valarray<_Tp>&); + + /// Logical xor corresponding elements of @a v with elements of array. + valarray<_Tp>& operator^=(const valarray<_Tp>&); + + /// Logical or corresponding elements of @a v with elements of array. + valarray<_Tp>& operator|=(const valarray<_Tp>&); + + /// Logical and corresponding elements of @a v with elements of array. + valarray<_Tp>& operator&=(const valarray<_Tp>&); + + /// Left shift elements of array by corresponding elements of @a v. + valarray<_Tp>& operator<<=(const valarray<_Tp>&); + + /// Right shift elements of array by corresponding elements of @a v. + valarray<_Tp>& operator>>=(const valarray<_Tp>&); + + template<class _Dom> + valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&); + template<class _Dom> + valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&); + template<class _Dom> + valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&); + template<class _Dom> + valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&); + template<class _Dom> + valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&); + template<class _Dom> + valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&); + template<class _Dom> + valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&); + template<class _Dom> + valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&); + template<class _Dom> + valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&); + template<class _Dom> + valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&); + + // _lib.valarray.members_ member functions: + /// Return the number of elements in array. + size_t size() const; + + /** + * @brief Return the sum of all elements in the array. + * + * Accumulates the sum of all elements into a Tp using +=. The order + * of adding the elements is unspecified. + */ + _Tp sum() const; + + /// Return the minimum element using operator<(). + _Tp min() const; + + /// Return the maximum element using operator<(). + _Tp max() const; + + /** + * @brief Return a shifted array. + * + * A new valarray is constructed as a copy of this array with elements + * in shifted positions. For an element with index i, the new position + * is i - n. The new valarray has the same size as the current one. + * New elements without a value are set to 0. Elements whose new + * position is outside the bounds of the array are discarded. + * + * Positive arguments shift toward index 0, discarding elements [0, n). + * Negative arguments discard elements from the top of the array. + * + * @param n Number of element positions to shift. + * @return New valarray with elements in shifted positions. + */ + valarray<_Tp> shift (int) const; + + /** + * @brief Return a rotated array. + * + * A new valarray is constructed as a copy of this array with elements + * in shifted positions. For an element with index i, the new position + * is (i - n) % size(). The new valarray has the same size as the + * current one. Elements that are shifted beyond the array bounds are + * shifted into the other end of the array. No elements are lost. + * + * Positive arguments shift toward index 0, wrapping around the top. + * Negative arguments shift towards the top, wrapping around to 0. + * + * @param n Number of element positions to rotate. + * @return New valarray with elements in shifted positions. + */ + valarray<_Tp> cshift(int) const; + + /** + * @brief Apply a function to the array. + * + * Returns a new valarray with elements assigned to the result of + * applying func to the corresponding element of this array. The new + * array has the same size as this one. + * + * @param func Function of Tp returning Tp to apply. + * @return New valarray with transformed elements. + */ + _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(_Tp)) const; + + /** + * @brief Apply a function to the array. + * + * Returns a new valarray with elements assigned to the result of + * applying func to the corresponding element of this array. The new + * array has the same size as this one. + * + * @param func Function of const Tp& returning Tp to apply. + * @return New valarray with transformed elements. + */ + _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(const _Tp&)) const; + + /** + * @brief Resize array. + * + * Resize this array to @a size and set all elements to @a c. All + * references and iterators are invalidated. + * + * @param size New array size. + * @param c New value for all elements. + */ + void resize(size_t __size, _Tp __c = _Tp()); + + private: + size_t _M_size; + _Tp* __restrict__ _M_data; + + friend class _Array<_Tp>; + }; + + template<typename _Tp> + inline const _Tp& + valarray<_Tp>::operator[](size_t __i) const + { + __glibcxx_requires_subscript(__i); + return _M_data[__i]; + } + + template<typename _Tp> + inline _Tp& + valarray<_Tp>::operator[](size_t __i) + { + __glibcxx_requires_subscript(__i); + return _M_data[__i]; + } + +_GLIBCXX_END_NAMESPACE + +#include <bits/valarray_after.h> +#include <bits/slice_array.h> +#include <bits/gslice.h> +#include <bits/gslice_array.h> +#include <bits/mask_array.h> +#include <bits/indirect_array.h> + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _Tp> + inline + valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {} + + template<typename _Tp> + inline + valarray<_Tp>::valarray(size_t __n) + : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) + { std::__valarray_default_construct(_M_data, _M_data + __n); } + + template<typename _Tp> + inline + valarray<_Tp>::valarray(const _Tp& __t, size_t __n) + : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) + { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); } + + template<typename _Tp> + inline + valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) + : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) + { + _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0); + std::__valarray_copy_construct(__p, __p + __n, _M_data); + } + + template<typename _Tp> + inline + valarray<_Tp>::valarray(const valarray<_Tp>& __v) + : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size)) + { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, + _M_data); } + + template<typename _Tp> + inline + valarray<_Tp>::valarray(const slice_array<_Tp>& __sa) + : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz)) + { + std::__valarray_copy_construct + (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); + } + + template<typename _Tp> + inline + valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga) + : _M_size(__ga._M_index.size()), + _M_data(__valarray_get_storage<_Tp>(_M_size)) + { + std::__valarray_copy_construct + (__ga._M_array, _Array<size_t>(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); + } + + template<typename _Tp> + inline + valarray<_Tp>::valarray(const mask_array<_Tp>& __ma) + : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) + { + std::__valarray_copy_construct + (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); + } + + template<typename _Tp> + inline + valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia) + : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) + { + std::__valarray_copy_construct + (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); + } + + template<typename _Tp> template<class _Dom> + inline + valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e) + : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) + { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); } + + template<typename _Tp> + inline + valarray<_Tp>::~valarray() + { + std::__valarray_destroy_elements(_M_data, _M_data + _M_size); + std::__valarray_release_memory(_M_data); + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator=(const valarray<_Tp>& __v) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); + std::__valarray_copy(__v._M_data, _M_size, _M_data); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator=(const _Tp& __t) + { + std::__valarray_fill(_M_data, _M_size, __t); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator=(const slice_array<_Tp>& __sa) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz); + std::__valarray_copy(__sa._M_array, __sa._M_sz, + __sa._M_stride, _Array<_Tp>(_M_data)); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size()); + std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator=(const mask_array<_Tp>& __ma) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz); + std::__valarray_copy(__ma._M_array, __ma._M_mask, + _Array<_Tp>(_M_data), _M_size); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz); + std::__valarray_copy(__ia._M_array, __ia._M_index, + _Array<_Tp>(_M_data), _M_size); + return *this; + } + + template<typename _Tp> template<class _Dom> + inline valarray<_Tp>& + valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size()); + std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); + return *this; + } + + template<typename _Tp> + inline _Expr<_SClos<_ValArray,_Tp>, _Tp> + valarray<_Tp>::operator[](slice __s) const + { + typedef _SClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s)); + } + + template<typename _Tp> + inline slice_array<_Tp> + valarray<_Tp>::operator[](slice __s) + { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); } + + template<typename _Tp> + inline _Expr<_GClos<_ValArray,_Tp>, _Tp> + valarray<_Tp>::operator[](const gslice& __gs) const + { + typedef _GClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> + (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index)); + } + + template<typename _Tp> + inline gslice_array<_Tp> + valarray<_Tp>::operator[](const gslice& __gs) + { + return gslice_array<_Tp> + (_Array<_Tp>(_M_data), __gs._M_index->_M_index); + } + + template<typename _Tp> + inline valarray<_Tp> + valarray<_Tp>::operator[](const valarray<bool>& __m) const + { + size_t __s = 0; + size_t __e = __m.size(); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s, + _Array<bool> (__m))); + } + + template<typename _Tp> + inline mask_array<_Tp> + valarray<_Tp>::operator[](const valarray<bool>& __m) + { + size_t __s = 0; + size_t __e = __m.size(); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m)); + } + + template<typename _Tp> + inline _Expr<_IClos<_ValArray,_Tp>, _Tp> + valarray<_Tp>::operator[](const valarray<size_t>& __i) const + { + typedef _IClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp>(_Closure(*this, __i)); + } + + template<typename _Tp> + inline indirect_array<_Tp> + valarray<_Tp>::operator[](const valarray<size_t>& __i) + { + return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(), + _Array<size_t>(__i)); + } + + template<class _Tp> + inline size_t + valarray<_Tp>::size() const + { return _M_size; } + + template<class _Tp> + inline _Tp + valarray<_Tp>::sum() const + { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); + return std::__valarray_sum(_M_data, _M_data + _M_size); + } + + template<class _Tp> + inline valarray<_Tp> + valarray<_Tp>::shift(int __n) const + { + valarray<_Tp> __ret; + + if (_M_size == 0) + return __ret; + + _Tp* __restrict__ __tmp_M_data = + std::__valarray_get_storage<_Tp>(_M_size); + + if (__n == 0) + std::__valarray_copy_construct(_M_data, + _M_data + _M_size, __tmp_M_data); + else if (__n > 0) // shift left + { + if (size_t(__n) > _M_size) + __n = _M_size; + + std::__valarray_copy_construct(_M_data + __n, + _M_data + _M_size, __tmp_M_data); + std::__valarray_default_construct(__tmp_M_data + _M_size - __n, + __tmp_M_data + _M_size); + } + else // shift right + { + if (size_t(-__n) > _M_size) + __n = -_M_size; + + std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, + __tmp_M_data - __n); + std::__valarray_default_construct(__tmp_M_data, + __tmp_M_data - __n); + } + + __ret._M_size = _M_size; + __ret._M_data = __tmp_M_data; + return __ret; + } + + template<class _Tp> + inline valarray<_Tp> + valarray<_Tp>::cshift(int __n) const + { + valarray<_Tp> __ret; + + if (_M_size == 0) + return __ret; + + _Tp* __restrict__ __tmp_M_data = + std::__valarray_get_storage<_Tp>(_M_size); + + if (__n == 0) + std::__valarray_copy_construct(_M_data, + _M_data + _M_size, __tmp_M_data); + else if (__n > 0) // cshift left + { + if (size_t(__n) > _M_size) + __n = __n % _M_size; + + std::__valarray_copy_construct(_M_data, _M_data + __n, + __tmp_M_data + _M_size - __n); + std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size, + __tmp_M_data); + } + else // cshift right + { + if (size_t(-__n) > _M_size) + __n = -(size_t(-__n) % _M_size); + + std::__valarray_copy_construct(_M_data + _M_size + __n, + _M_data + _M_size, __tmp_M_data); + std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, + __tmp_M_data - __n); + } + + __ret._M_size = _M_size; + __ret._M_data = __tmp_M_data; + return __ret; + } + + template<class _Tp> + inline void + valarray<_Tp>::resize(size_t __n, _Tp __c) + { + // This complication is so to make valarray<valarray<T> > work + // even though it is not required by the standard. Nobody should + // be saying valarray<valarray<T> > anyway. See the specs. + std::__valarray_destroy_elements(_M_data, _M_data + _M_size); + if (_M_size != __n) + { + std::__valarray_release_memory(_M_data); + _M_size = __n; + _M_data = __valarray_get_storage<_Tp>(__n); + } + std::__valarray_fill_construct(_M_data, _M_data + __n, __c); + } + + template<typename _Tp> + inline _Tp + valarray<_Tp>::min() const + { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); + return *std::min_element(_M_data, _M_data+_M_size); + } + + template<typename _Tp> + inline _Tp + valarray<_Tp>::max() const + { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); + return *std::max_element(_M_data, _M_data+_M_size); + } + + template<class _Tp> + inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> + valarray<_Tp>::apply(_Tp func(_Tp)) const + { + typedef _ValFunClos<_ValArray, _Tp> _Closure; + return _Expr<_Closure, _Tp>(_Closure(*this, func)); + } + + template<class _Tp> + inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> + valarray<_Tp>::apply(_Tp func(const _Tp &)) const + { + typedef _RefFunClos<_ValArray, _Tp> _Closure; + return _Expr<_Closure, _Tp>(_Closure(*this, func)); + } + +#define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \ + valarray<_Tp>::operator _Op() const \ + { \ + typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \ + typedef typename __fun<_Name, _Tp>::result_type _Rt; \ + return _Expr<_Closure, _Rt>(_Closure(*this)); \ + } + + _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus) + _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate) + _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not) + _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not) + +#undef _DEFINE_VALARRAY_UNARY_OPERATOR + +#define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template<class _Tp> \ + inline valarray<_Tp>& \ + valarray<_Tp>::operator _Op##=(const _Tp &__t) \ + { \ + _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \ + return *this; \ + } \ + \ + template<class _Tp> \ + inline valarray<_Tp>& \ + valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \ + { \ + _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); \ + _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \ + _Array<_Tp>(__v._M_data)); \ + return *this; \ + } + +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right) + +#undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT + +#define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template<class _Tp> template<class _Dom> \ + inline valarray<_Tp>& \ + valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \ + { \ + _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \ + return *this; \ + } + +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right) + +#undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT + + +#define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \ + typename __fun<_Name, _Tp>::result_type> \ + operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ + { \ + _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size()); \ + typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \ + typedef typename __fun<_Name, _Tp>::result_type _Rt; \ + return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \ + typename __fun<_Name, _Tp>::result_type> \ + operator _Op(const valarray<_Tp>& __v, const _Tp& __t) \ + { \ + typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \ + typedef typename __fun<_Name, _Tp>::result_type _Rt; \ + return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \ + typename __fun<_Name, _Tp>::result_type> \ + operator _Op(const _Tp& __t, const valarray<_Tp>& __v) \ + { \ + typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \ + typedef typename __fun<_Name, _Tp>::result_type _Rt; \ + return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \ + } + +_DEFINE_BINARY_OPERATOR(+, __plus) +_DEFINE_BINARY_OPERATOR(-, __minus) +_DEFINE_BINARY_OPERATOR(*, __multiplies) +_DEFINE_BINARY_OPERATOR(/, __divides) +_DEFINE_BINARY_OPERATOR(%, __modulus) +_DEFINE_BINARY_OPERATOR(^, __bitwise_xor) +_DEFINE_BINARY_OPERATOR(&, __bitwise_and) +_DEFINE_BINARY_OPERATOR(|, __bitwise_or) +_DEFINE_BINARY_OPERATOR(<<, __shift_left) +_DEFINE_BINARY_OPERATOR(>>, __shift_right) +_DEFINE_BINARY_OPERATOR(&&, __logical_and) +_DEFINE_BINARY_OPERATOR(||, __logical_or) +_DEFINE_BINARY_OPERATOR(==, __equal_to) +_DEFINE_BINARY_OPERATOR(!=, __not_equal_to) +_DEFINE_BINARY_OPERATOR(<, __less) +_DEFINE_BINARY_OPERATOR(>, __greater) +_DEFINE_BINARY_OPERATOR(<=, __less_equal) +_DEFINE_BINARY_OPERATOR(>=, __greater_equal) + +#undef _DEFINE_BINARY_OPERATOR + +_GLIBCXX_END_NAMESPACE + +#endif /* _GLIBCXX_VALARRAY */ diff --git a/libstdc++/include/std/std_vector.h b/libstdc++/include/std/std_vector.h new file mode 100644 index 0000000..a4a527e --- /dev/null +++ b/libstdc++/include/std/std_vector.h @@ -0,0 +1,82 @@ +// <vector> -*- C++ -*- + +// Copyright (C) 2001, 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. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file include/vector + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_VECTOR +#define _GLIBCXX_VECTOR 1 + +#pragma GCC system_header + +#include <bits/functexcept.h> +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_vector.h> +#include <bits/stl_bvector.h> + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/vector.tcc> +#endif + +#ifdef _GLIBCXX_DEBUG +# include <debug/vector> +#endif + +#endif /* _GLIBCXX_VECTOR */ + diff --git a/libstdc++/include/tr1/array b/libstdc++/include/tr1/array new file mode 100644 index 0000000..23808b3 --- /dev/null +++ b/libstdc++/include/tr1/array @@ -0,0 +1,251 @@ +// class template array -*- C++ -*- + +// 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. + +/** @file tr1/array + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_ARRAY +#define _TR1_ARRAY 1 + +#include <new> +#include <iterator> +#include <algorithm> +#include <cstddef> +#include <bits/functexcept.h> +#include <ext/type_traits.h> + +//namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + /// @brief struct array [6.2.2]. + /// NB: Requires complete type _Tp. + template<typename _Tp, std::size_t _Nm> + struct array + { + typedef _Tp value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // Support for zero-sized arrays mandatory. + value_type _M_instance[_Nm ? _Nm : 1] __attribute__((__aligned__)); + + // No explicit construct/copy/destroy for aggregate type. + + void + assign(const value_type& __u) + { std::fill_n(begin(), size(), __u); } + + void + swap(array& __other) + { std::swap_ranges(begin(), end(), __other.begin()); } + + // Iterators. + iterator + begin() + { return iterator(&_M_instance[0]); } + + const_iterator + begin() const + { return const_iterator(&_M_instance[0]); } + + iterator + end() + { return iterator(&_M_instance[_Nm]); } + + const_iterator + end() const + { return const_iterator(&_M_instance[_Nm]); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // Capacity. + size_type + size() const { return _Nm; } + + size_type + max_size() const { return _Nm; } + + bool + empty() const { return size() == 0; } + + // Element access. + reference + operator[](size_type __n) + { return _M_instance[__n]; } + + const_reference + operator[](size_type __n) const + { return _M_instance[__n]; } + + reference + at(size_type __n) + { + _M_check<_Nm>(__n); + return _M_instance[__n]; + } + + const_reference + at(size_type __n) const + { + _M_check<_Nm>(__n); + return _M_instance[__n]; + } + + reference + front() + { return *begin(); } + + const_reference + front() const + { return *begin(); } + + reference + back() + { return _Nm ? *(end() - 1) : *end(); } + + const_reference + back() const + { return _Nm ? *(end() - 1) : *end(); } + + _Tp* + data() + { return &_M_instance[0]; } + + const _Tp* + data() const + { return &_M_instance[0]; } + + private: + template<std::size_t _Mm> + typename __gnu_cxx::__enable_if<_Mm, void>::__type + _M_check(size_type __n) const + { + if (__builtin_expect(__n >= _Mm, false)) + std::__throw_out_of_range(__N("array::_M_check")); + } + + // Avoid "unsigned comparison with zero" warnings. + template<std::size_t _Mm> + typename __gnu_cxx::__enable_if<!_Mm, void>::__type + _M_check(size_type) const + { std::__throw_out_of_range(__N("array::_M_check")); } + }; + + // Array comparisons. + template<typename _Tp, std::size_t _Nm> + inline bool + operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return std::equal(__one.begin(), __one.end(), __two.begin()); } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return !(__one == __two); } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) + { + return std::lexicographical_compare(__a.begin(), __a.end(), + __b.begin(), __b.end()); + } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return __two < __one; } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return !(__one > __two); } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return !(__one < __two); } + + // Specialized algorithms [6.2.2.2]. + template<typename _Tp, std::size_t _Nm> + inline void + swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) + { std::swap_ranges(__one.begin(), __one.end(), __two.begin()); } + + // Tuple interface to class template array [6.2.2.5]. + template<typename _Tp> class tuple_size; + template<int _Int, typename _Tp> class tuple_element; + + template<typename _Tp, std::size_t _Nm> + struct tuple_size<array<_Tp, _Nm> > + { static const int value = _Nm; }; + + template<typename _Tp, std::size_t _Nm> + const int tuple_size<array<_Tp, _Nm> >::value; + + template<int _Int, typename _Tp, std::size_t _Nm> + struct tuple_element<_Int, array<_Tp, _Nm> > + { typedef _Tp type; }; + + template<int _Int, typename _Tp, std::size_t _Nm> + inline _Tp& + get(array<_Tp, _Nm>& __arr) + { return __arr[_Int]; } + + template<int _Int, typename _Tp, std::size_t _Nm> + inline const _Tp& + get(const array<_Tp, _Nm>& __arr) + { return __arr[_Int]; } + +_GLIBCXX_END_NAMESPACE +} + +#endif diff --git a/libstdc++/include/tr1/bind_iterate.h b/libstdc++/include/tr1/bind_iterate.h new file mode 100644 index 0000000..3de49a7 --- /dev/null +++ b/libstdc++/include/tr1/bind_iterate.h @@ -0,0 +1,78 @@ +// TR1 functional -*- C++ -*- + +// Copyright (C) 2005 Free Software Foundation, Inc. +// Written by Douglas Gregor <doug.gregor -at- gmail.com> +// +// 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. + +/** @file tr1/bind_iterate.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#if _GLIBCXX_BIND_NUM_ARGS > 0 +template<_GLIBCXX_BIND_TEMPLATE_PARAMS> +#endif +#ifdef _GLIBCXX_BIND_HAS_RESULT_TYPE +result_type +#else +typename result_of<_Functor(_GLIBCXX_BIND_V_TEMPLATE_ARGS())>::type +#endif +operator()(_GLIBCXX_BIND_PARAMS) +{ return _M_f(_GLIBCXX_BIND_V_ARGS); } + +#if _GLIBCXX_BIND_NUM_ARGS > 0 +template<_GLIBCXX_BIND_TEMPLATE_PARAMS> +#endif +#ifdef _GLIBCXX_BIND_HAS_RESULT_TYPE +result_type +#else +typename result_of<const _Functor(_GLIBCXX_BIND_V_TEMPLATE_ARGS(const))>::type +#endif +operator()(_GLIBCXX_BIND_PARAMS) const +{ return _M_f(_GLIBCXX_BIND_V_ARGS); } + +#if _GLIBCXX_BIND_NUM_ARGS > 0 +template<_GLIBCXX_BIND_TEMPLATE_PARAMS> +#endif +#ifdef _GLIBCXX_BIND_HAS_RESULT_TYPE +result_type +#else +typename result_of<volatile _Functor(_GLIBCXX_BIND_V_TEMPLATE_ARGS(volatile))>::type +#endif +operator()(_GLIBCXX_BIND_PARAMS) volatile +{ return _M_f(_GLIBCXX_BIND_V_ARGS); } + +#if _GLIBCXX_BIND_NUM_ARGS > 0 +template<_GLIBCXX_BIND_TEMPLATE_PARAMS> +#endif +#ifdef _GLIBCXX_BIND_HAS_RESULT_TYPE +result_type +#else +typename result_of<const volatile _Functor(_GLIBCXX_BIND_V_TEMPLATE_ARGS(const volatile))>::type +#endif +operator()(_GLIBCXX_BIND_PARAMS) const volatile +{ return _M_f(_GLIBCXX_BIND_V_ARGS); } diff --git a/libstdc++/include/tr1/bind_repeat.h b/libstdc++/include/tr1/bind_repeat.h new file mode 100644 index 0000000..8ec29a2 --- /dev/null +++ b/libstdc++/include/tr1/bind_repeat.h @@ -0,0 +1,192 @@ +// TR1 code repetition for bind -*- C++ -*- + +// Copyright (C) 2005 Free Software Foundation, Inc. +// Written by Douglas Gregor <doug.gregor -at- gmail.com> +// +// 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. + +/** @file tr1/bind_repeat.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_BIND_REPEAT_HEADER +# error Internal error: _GLIBCXX_BIND_REPEAT_HEADER must be set +#endif /* _GLIBCXX_BIND_REPEAT_HEADER */ + +#define _GLIBCXX_BIND_NUM_ARGS 0 +#define _GLIBCXX_BIND_COMMA +#define _GLIBCXX_BIND_TEMPLATE_PARAMS +#define _GLIBCXX_BIND_TEMPLATE_ARGS +#define _GLIBCXX_BIND_PARAMS +#define _GLIBCXX_BIND_ARGS +# include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + +#define _GLIBCXX_BIND_NUM_ARGS 1 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1 +#define _GLIBCXX_BIND_PARAMS _U1& __u1 +#define _GLIBCXX_BIND_ARGS __u1 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS +#define _GLIBCXX_BIND_NUM_ARGS 2 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1, typename _U2 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1, _U2 +#define _GLIBCXX_BIND_PARAMS _U1& __u1, _U2& __u2 +#define _GLIBCXX_BIND_ARGS __u1, __u2 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + +#define _GLIBCXX_BIND_NUM_ARGS 3 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1, typename _U2, typename _U3 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1, _U2, _U3 +#define _GLIBCXX_BIND_PARAMS _U1& __u1, _U2& __u2, _U3& __u3 +#define _GLIBCXX_BIND_ARGS __u1, __u2, __u3 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + +#define _GLIBCXX_BIND_NUM_ARGS 4 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1, typename _U2, typename _U3, typename _U4 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1, _U2, _U3, _U4 +#define _GLIBCXX_BIND_PARAMS _U1& __u1, _U2& __u2, _U3& __u3, _U4& __u4 +#define _GLIBCXX_BIND_ARGS __u1, __u2, __u3, __u4 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + +#define _GLIBCXX_BIND_NUM_ARGS 5 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1, typename _U2, typename _U3, typename _U4, typename _U5 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1, _U2, _U3, _U4, _U5 +#define _GLIBCXX_BIND_PARAMS _U1& __u1, _U2& __u2, _U3& __u3, _U4& __u4, _U5& __u5 +#define _GLIBCXX_BIND_ARGS __u1, __u2, __u3, __u4, __u5 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + +#define _GLIBCXX_BIND_NUM_ARGS 6 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1, _U2, _U3, _U4, _U5, _U6 +#define _GLIBCXX_BIND_PARAMS _U1& __u1, _U2& __u2, _U3& __u3, _U4& __u4, _U5& __u5, _U6& __u6 +#define _GLIBCXX_BIND_ARGS __u1, __u2, __u3, __u4, __u5, __u6 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + +#define _GLIBCXX_BIND_NUM_ARGS 7 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1, _U2, _U3, _U4, _U5, _U6, _U7 +#define _GLIBCXX_BIND_PARAMS _U1& __u1, _U2& __u2, _U3& __u3, _U4& __u4, _U5& __u5, _U6& __u6, _U7& __u7 +#define _GLIBCXX_BIND_ARGS __u1, __u2, __u3, __u4, __u5, __u6, __u7 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + +#define _GLIBCXX_BIND_NUM_ARGS 8 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8 +#define _GLIBCXX_BIND_PARAMS _U1& __u1, _U2& __u2, _U3& __u3, _U4& __u4, _U5& __u5, _U6& __u6, _U7& __u7, _U8& __u8 +#define _GLIBCXX_BIND_ARGS __u1, __u2, __u3, __u4, __u5, __u6, __u7, __u8 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + +#define _GLIBCXX_BIND_NUM_ARGS 9 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9 +#define _GLIBCXX_BIND_PARAMS _U1& __u1, _U2& __u2, _U3& __u3, _U4& __u4, _U5& __u5, _U6& __u6, _U7& __u7, _U8& __u8, _U9& __u9 +#define _GLIBCXX_BIND_ARGS __u1, __u2, __u3, __u4, __u5, __u6, __u7, __u8, __u9 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + +#define _GLIBCXX_BIND_NUM_ARGS 10 +#define _GLIBCXX_BIND_COMMA , +#define _GLIBCXX_BIND_TEMPLATE_PARAMS typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9, typename _U10 +#define _GLIBCXX_BIND_TEMPLATE_ARGS _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9, _U10 +#define _GLIBCXX_BIND_PARAMS _U1& __u1, _U2& __u2, _U3& __u3, _U4& __u4, _U5& __u5, _U6& __u6, _U7& __u7, _U8& __u8, _U9& __u9, _U10& __u10 +#define _GLIBCXX_BIND_ARGS __u1, __u2, __u3, __u4, __u5, __u6, __u7, __u8, __u9, __u10 +#include _GLIBCXX_BIND_REPEAT_HEADER +#undef _GLIBCXX_BIND_ARGS +#undef _GLIBCXX_BIND_PARAMS +#undef _GLIBCXX_BIND_TEMPLATE_ARGS +#undef _GLIBCXX_BIND_TEMPLATE_PARAMS +#undef _GLIBCXX_BIND_COMMA +#undef _GLIBCXX_BIND_NUM_ARGS + diff --git a/libstdc++/include/tr1/boost_shared_ptr.h b/libstdc++/include/tr1/boost_shared_ptr.h new file mode 100644 index 0000000..fc79cfc --- /dev/null +++ b/libstdc++/include/tr1/boost_shared_ptr.h @@ -0,0 +1,1149 @@ +// <tr1/boost_shared_ptr.h> -*- C++ -*- + +// Copyright (C) 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. + +// shared_count.hpp +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. + +// shared_ptr.hpp +// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. +// Copyright (C) 2001, 2002, 2003 Peter Dimov + +// weak_ptr.hpp +// Copyright (C) 2001, 2002, 2003 Peter Dimov + +// enable_shared_from_this.hpp +// Copyright (C) 2002 Peter Dimov + +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// GCC Note: based on version 1.32.0 of the Boost library. + +/** @file tr1/boost_shared_ptr.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BOOST_SHARED_PTR_H +#define _BOOST_SHARED_PTR_H 1 + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + class bad_weak_ptr : public std::exception + { + public: + virtual char const* + what() const throw() + { return "tr1::bad_weak_ptr"; } + }; + + // Substitute for bad_weak_ptr object in the case of -fno-exceptions. + inline void + __throw_bad_weak_ptr() + { +#if __EXCEPTIONS + throw bad_weak_ptr(); +#else + std::abort(); +#endif + } + + using __gnu_cxx::_Lock_policy; + using __gnu_cxx::__default_lock_policy; + using __gnu_cxx::_S_single; + using __gnu_cxx::_S_mutex; + using __gnu_cxx::_S_atomic; + + template<typename _Tp> + struct _Sp_deleter + { + typedef void result_type; + typedef _Tp* argument_type; + + void + operator()(_Tp* __p) const + { delete __p; } + }; + + // Empty helper class except when the template argument is _S_mutex. + template<_Lock_policy _Lp> + class _Mutex_base + { }; + + template<> + class _Mutex_base<_S_mutex> + : public __gnu_cxx::__mutex + { }; + + template<_Lock_policy _Lp = __default_lock_policy> + class _Sp_counted_base + : public _Mutex_base<_Lp> + { + public: + _Sp_counted_base() + : _M_use_count(1), _M_weak_count(1) { } + + virtual + ~_Sp_counted_base() // nothrow + { } + + // Called when _M_use_count drops to zero, to release the resources + // managed by *this. + virtual void + _M_dispose() = 0; // nothrow + + // Called when _M_weak_count drops to zero. + virtual void + _M_destroy() // nothrow + { delete this; } + + virtual void* + _M_get_deleter(const std::type_info&) = 0; + + void + _M_add_ref_copy() + { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } + + void + _M_add_ref_lock(); + + void + _M_release() // nothrow + { + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, + -1) == 1) + { + _M_dispose(); +#ifdef __GTHREADS + _GLIBCXX_READ_MEM_BARRIER; + _GLIBCXX_WRITE_MEM_BARRIER; +#endif + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, + -1) == 1) + _M_destroy(); + } + } + + void + _M_weak_add_ref() // nothrow + { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } + + void + _M_weak_release() // nothrow + { + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) + { +#ifdef __GTHREADS + _GLIBCXX_READ_MEM_BARRIER; + _GLIBCXX_WRITE_MEM_BARRIER; +#endif + _M_destroy(); + } + } + + long + _M_get_use_count() const // nothrow + { return _M_use_count; } // XXX is this MT safe? + + private: + _Sp_counted_base(_Sp_counted_base const&); + _Sp_counted_base& operator=(_Sp_counted_base const&); + + _Atomic_word _M_use_count; // #shared + _Atomic_word _M_weak_count; // #weak + (#shared != 0) + }; + + template<> + inline void + _Sp_counted_base<_S_single>:: + _M_add_ref_lock() + { + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) + { + _M_use_count = 0; + __throw_bad_weak_ptr(); + } + } + +#ifdef __GTHREADS + template<> + inline void + _Sp_counted_base<_S_mutex>:: + _M_add_ref_lock() + { + __gnu_cxx::__scoped_lock sentry(*this); + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) + { + _M_use_count = 0; + __throw_bad_weak_ptr(); + } + } +#endif + + template<> + inline void + _Sp_counted_base<_S_atomic>:: + _M_add_ref_lock() + { + // Perform lock-free add-if-not-zero operation. + _Atomic_word __count; + do + { + __count = _M_use_count; + if (__count == 0) + __throw_bad_weak_ptr(); + + // Replace the current counter value with the old value + 1, as + // long as it's not changed meanwhile. + } + while (!__sync_bool_compare_and_swap(&_M_use_count, __count, + __count + 1)); + } + + template<typename _Ptr, typename _Deleter, _Lock_policy _Lp> + class _Sp_counted_base_impl + : public _Sp_counted_base<_Lp> + { + public: + /** + * @brief + * @pre __d(__p) must not throw. + */ + _Sp_counted_base_impl(_Ptr __p, _Deleter __d) + : _M_ptr(__p), _M_del(__d) { } + + virtual void + _M_dispose() // nothrow + { _M_del(_M_ptr); } + + virtual void* + _M_get_deleter(const std::type_info& __ti) + { return __ti == typeid(_Deleter) ? &_M_del : 0; } + + private: + _Sp_counted_base_impl(const _Sp_counted_base_impl&); + _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&); + + _Ptr _M_ptr; // copy constructor must not throw + _Deleter _M_del; // copy constructor must not throw + }; + + template<_Lock_policy _Lp = __default_lock_policy> + class __weak_count; + + template<_Lock_policy _Lp = __default_lock_policy> + class __shared_count + { + public: + __shared_count() + : _M_pi(0) // nothrow + { } + + template<typename _Ptr, typename _Deleter> + __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) + { + try + { + _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d); + } + catch(...) + { + __d(__p); // Call _Deleter on __p. + __throw_exception_again; + } + } + + // Special case for auto_ptr<_Tp> to provide the strong guarantee. + template<typename _Tp> + explicit + __shared_count(std::auto_ptr<_Tp>& __r) + : _M_pi(new _Sp_counted_base_impl<_Tp*, + _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>())) + { __r.release(); } + + // Throw bad_weak_ptr when __r._M_get_use_count() == 0. + explicit + __shared_count(const __weak_count<_Lp>& __r); + + ~__shared_count() // nothrow + { + if (_M_pi != 0) + _M_pi->_M_release(); + } + + __shared_count(const __shared_count& __r) + : _M_pi(__r._M_pi) // nothrow + { + if (_M_pi != 0) + _M_pi->_M_add_ref_copy(); + } + + __shared_count& + operator=(const __shared_count& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + if (__tmp != _M_pi) + { + if (__tmp != 0) + __tmp->_M_add_ref_copy(); + if (_M_pi != 0) + _M_pi->_M_release(); + _M_pi = __tmp; + } + return *this; + } + + void + _M_swap(__shared_count& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + __r._M_pi = _M_pi; + _M_pi = __tmp; + } + + long + _M_get_use_count() const // nothrow + { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } + + bool + _M_unique() const // nothrow + { return this->_M_get_use_count() == 1; } + + friend inline bool + operator==(const __shared_count& __a, const __shared_count& __b) + { return __a._M_pi == __b._M_pi; } + + friend inline bool + operator<(const __shared_count& __a, const __shared_count& __b) + { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } + + void* + _M_get_deleter(const std::type_info& __ti) const + { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } + + private: + friend class __weak_count<_Lp>; + + _Sp_counted_base<_Lp>* _M_pi; + }; + + template<_Lock_policy _Lp> + class __weak_count + { + public: + __weak_count() + : _M_pi(0) // nothrow + { } + + __weak_count(const __shared_count<_Lp>& __r) + : _M_pi(__r._M_pi) // nothrow + { + if (_M_pi != 0) + _M_pi->_M_weak_add_ref(); + } + + __weak_count(const __weak_count<_Lp>& __r) + : _M_pi(__r._M_pi) // nothrow + { + if (_M_pi != 0) + _M_pi->_M_weak_add_ref(); + } + + ~__weak_count() // nothrow + { + if (_M_pi != 0) + _M_pi->_M_weak_release(); + } + + __weak_count<_Lp>& + operator=(const __shared_count<_Lp>& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + if (__tmp != 0) + __tmp->_M_weak_add_ref(); + if (_M_pi != 0) + _M_pi->_M_weak_release(); + _M_pi = __tmp; + return *this; + } + + __weak_count<_Lp>& + operator=(const __weak_count<_Lp>& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + if (__tmp != 0) + __tmp->_M_weak_add_ref(); + if (_M_pi != 0) + _M_pi->_M_weak_release(); + _M_pi = __tmp; + return *this; + } + + void + _M_swap(__weak_count<_Lp>& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + __r._M_pi = _M_pi; + _M_pi = __tmp; + } + + long + _M_get_use_count() const // nothrow + { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } + + friend inline bool + operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) + { return __a._M_pi == __b._M_pi; } + + friend inline bool + operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) + { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } + + private: + friend class __shared_count<_Lp>; + + _Sp_counted_base<_Lp>* _M_pi; + }; + + template<_Lock_policy _Lp> + inline + __shared_count<_Lp>:: + __shared_count(const __weak_count<_Lp>& __r) + : _M_pi(__r._M_pi) + { + if (_M_pi != 0) + _M_pi->_M_add_ref_lock(); + else + __throw_bad_weak_ptr(); + } + + + // Forward declarations. + template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> + class __shared_ptr; + + template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> + class __weak_ptr; + + template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> + class __enable_shared_from_this; + + template<typename _Tp> + class shared_ptr; + + template<typename _Tp> + class weak_ptr; + + template<typename _Tp> + class enable_shared_from_this; + + // Support for enable_shared_from_this. + + // Friend of __enable_shared_from_this. + template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> + void + __enable_shared_from_this_helper(const __shared_count<_Lp>&, + const __enable_shared_from_this<_Tp1, + _Lp>*, const _Tp2*); + + // Friend of enable_shared_from_this. + template<typename _Tp1, typename _Tp2> + void + __enable_shared_from_this_helper(const __shared_count<>&, + const enable_shared_from_this<_Tp1>*, + const _Tp2*); + + template<_Lock_policy _Lp> + inline void + __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) + { } + + + struct __static_cast_tag { }; + struct __const_cast_tag { }; + struct __dynamic_cast_tag { }; + + /** + * @class shared_ptr <tr1/memory> + * + * A smart pointer with reference-counted copy semantics. + * The object pointed to is deleted when the last shared_ptr pointing to + * it is destroyed or reset. + */ + template<typename _Tp, _Lock_policy _Lp> + class __shared_ptr + { + public: + typedef _Tp element_type; + + /** @brief Construct an empty %__shared_ptr. + * @post use_count()==0 && get()==0 + */ + __shared_ptr() + : _M_ptr(0), _M_refcount() // never throws + { } + + /** @brief Construct a %__shared_ptr that owns the pointer @a __p. + * @param __p A pointer that is convertible to element_type*. + * @post use_count() == 1 && get() == __p + * @throw std::bad_alloc, in which case @c delete @a __p is called. + */ + template<typename _Tp1> + explicit + __shared_ptr(_Tp1* __p) + : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>()) + { + __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) + // __glibcxx_function_requires(_CompleteConcept<_Tp1*>) + __enable_shared_from_this_helper(_M_refcount, __p, __p); + } + + // + // Requirements: _Deleter' copy constructor and destructor must not throw + // + // __shared_ptr will release __p by calling __d(__p) + // + /** @brief Construct a %__shared_ptr that owns the pointer @a __p + * and the deleter @a __d. + * @param __p A pointer. + * @param __d A deleter. + * @post use_count() == 1 && get() == __p + * @throw std::bad_alloc, in which case @a __d(__p) is called. + */ + template<typename _Tp1, typename _Deleter> + __shared_ptr(_Tp1* __p, _Deleter __d) + : _M_ptr(__p), _M_refcount(__p, __d) + { + __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) + // TODO requires _Deleter CopyConstructible and __d(__p) well-formed + __enable_shared_from_this_helper(_M_refcount, __p, __p); + } + + // generated copy constructor, assignment, destructor are fine. + + /** @brief If @a __r is empty, constructs an empty %__shared_ptr; + * otherwise construct a %__shared_ptr that shares ownership + * with @a __r. + * @param __r A %__shared_ptr. + * @post get() == __r.get() && use_count() == __r.use_count() + * @throw std::bad_alloc, in which case + */ + template<typename _Tp1> + __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) + : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws + { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } + + /** @brief Constructs a %__shared_ptr that shares ownership with @a __r + * and stores a copy of the pointer stored in @a __r. + * @param __r A weak_ptr. + * @post use_count() == __r.use_count() + * @throw bad_weak_ptr when __r.expired(), + * in which case the constructor has no effect. + */ + template<typename _Tp1> + explicit + __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) + : _M_refcount(__r._M_refcount) // may throw + { + __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) + // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount) + // did not throw. + _M_ptr = __r._M_ptr; + } + + /** + * @post use_count() == 1 and __r.get() == 0 + */ + template<typename _Tp1> + explicit + __shared_ptr(std::auto_ptr<_Tp1>& __r) + : _M_ptr(__r.get()), _M_refcount() + { + // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete, + // delete __r.release() well-formed + _Tp1* __tmp = __r.get(); + _M_refcount = __shared_count<_Lp>(__r); + __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); + } + + template<typename _Tp1> + __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag) + : _M_ptr(static_cast<element_type*>(__r._M_ptr)), + _M_refcount(__r._M_refcount) + { } + + template<typename _Tp1> + __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag) + : _M_ptr(const_cast<element_type*>(__r._M_ptr)), + _M_refcount(__r._M_refcount) + { } + + template<typename _Tp1> + __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag) + : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)), + _M_refcount(__r._M_refcount) + { + if (_M_ptr == 0) // need to allocate new counter -- the cast failed + _M_refcount = __shared_count<_Lp>(); + } + + template<typename _Tp1> + __shared_ptr& + operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws + { + _M_ptr = __r._M_ptr; + _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw + return *this; + } + + template<typename _Tp1> + __shared_ptr& + operator=(std::auto_ptr<_Tp1>& __r) + { + __shared_ptr(__r).swap(*this); + return *this; + } + + void + reset() // never throws + { __shared_ptr().swap(*this); } + + template<typename _Tp1> + void + reset(_Tp1* __p) // _Tp1 must be complete. + { + // Catch self-reset errors. + _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); + __shared_ptr(__p).swap(*this); + } + + template<typename _Tp1, typename _Deleter> + void + reset(_Tp1* __p, _Deleter __d) + { __shared_ptr(__p, __d).swap(*this); } + + // Allow class instantiation when _Tp is [cv-qual] void. + typename add_reference<_Tp>::type + operator*() const // never throws + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return *_M_ptr; + } + + _Tp* + operator->() const // never throws + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return _M_ptr; + } + + _Tp* + get() const // never throws + { return _M_ptr; } + + // Implicit conversion to "bool" + private: + typedef _Tp* __shared_ptr::*__unspecified_bool_type; + + public: + operator __unspecified_bool_type() const // never throws + { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; } + + bool + unique() const // never throws + { return _M_refcount._M_unique(); } + + long + use_count() const // never throws + { return _M_refcount._M_get_use_count(); } + + void + swap(__shared_ptr<_Tp, _Lp>& __other) // never throws + { + std::swap(_M_ptr, __other._M_ptr); + _M_refcount._M_swap(__other._M_refcount); + } + + private: + void* + _M_get_deleter(const std::type_info& __ti) const + { return _M_refcount._M_get_deleter(__ti); } + + template<typename _Tp1, _Lock_policy _Lp1> + bool + _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const + { return _M_refcount < __rhs._M_refcount; } + + template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; + template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; + + template<typename _Del, typename _Tp1, _Lock_policy _Lp1> + friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&); + + // Friends injected into enclosing namespace and found by ADL: + template<typename _Tp1> + friend inline bool + operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) + { return __a.get() == __b.get(); } + + template<typename _Tp1> + friend inline bool + operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) + { return __a.get() != __b.get(); } + + template<typename _Tp1> + friend inline bool + operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) + { return __a._M_less(__b); } + + _Tp* _M_ptr; // Contained pointer. + __shared_count<_Lp> _M_refcount; // Reference counter. + }; + + // 2.2.3.8 shared_ptr specialized algorithms. + template<typename _Tp, _Lock_policy _Lp> + inline void + swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) + { __a.swap(__b); } + + // 2.2.3.9 shared_ptr casts + /** @warning The seemingly equivalent + * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code> + * will eventually result in undefined behaviour, + * attempting to delete the same object twice. + */ + template<typename _Tp, typename _Tp1, _Lock_policy _Lp> + __shared_ptr<_Tp, _Lp> + static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) + { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); } + + /** @warning The seemingly equivalent + * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code> + * will eventually result in undefined behaviour, + * attempting to delete the same object twice. + */ + template<typename _Tp, typename _Tp1, _Lock_policy _Lp> + __shared_ptr<_Tp, _Lp> + const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) + { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); } + + /** @warning The seemingly equivalent + * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code> + * will eventually result in undefined behaviour, + * attempting to delete the same object twice. + */ + template<typename _Tp, typename _Tp1, _Lock_policy _Lp> + __shared_ptr<_Tp, _Lp> + dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) + { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); } + + // 2.2.3.7 shared_ptr I/O + template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> + std::basic_ostream<_Ch, _Tr>& + operator<<(std::basic_ostream<_Ch, _Tr>& __os, + const __shared_ptr<_Tp, _Lp>& __p) + { + __os << __p.get(); + return __os; + } + + // 2.2.3.10 shared_ptr get_deleter (experimental) + template<typename _Del, typename _Tp, _Lock_policy _Lp> + inline _Del* + get_deleter(const __shared_ptr<_Tp, _Lp>& __p) + { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); } + + + template<typename _Tp, _Lock_policy _Lp> + class __weak_ptr + { + public: + typedef _Tp element_type; + + __weak_ptr() + : _M_ptr(0), _M_refcount() // never throws + { } + + // Generated copy constructor, assignment, destructor are fine. + + // The "obvious" converting constructor implementation: + // + // template<typename _Tp1> + // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) + // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws + // { } + // + // has a serious problem. + // + // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) + // conversion may require access to *__r._M_ptr (virtual inheritance). + // + // It is not possible to avoid spurious access violations since + // in multithreaded programs __r._M_ptr may be invalidated at any point. + template<typename _Tp1> + __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) + : _M_refcount(__r._M_refcount) // never throws + { + __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) + _M_ptr = __r.lock().get(); + } + + template<typename _Tp1> + __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) + : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws + { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } + + template<typename _Tp1> + __weak_ptr& + operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws + { + _M_ptr = __r.lock().get(); + _M_refcount = __r._M_refcount; + return *this; + } + + template<typename _Tp1> + __weak_ptr& + operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws + { + _M_ptr = __r._M_ptr; + _M_refcount = __r._M_refcount; + return *this; + } + + __shared_ptr<_Tp, _Lp> + lock() const // never throws + { +#ifdef __GTHREADS + // Optimization: avoid throw overhead. + if (expired()) + return __shared_ptr<element_type, _Lp>(); + + try + { + return __shared_ptr<element_type, _Lp>(*this); + } + catch(const bad_weak_ptr&) + { + // Q: How can we get here? + // A: Another thread may have invalidated r after the + // use_count test above. + return __shared_ptr<element_type>(); + } + +#else + // Optimization: avoid try/catch overhead when single threaded. + return expired() ? __shared_ptr<element_type, _Lp>() + : __shared_ptr<element_type, _Lp>(*this); + +#endif + } // XXX MT + + long + use_count() const // never throws + { return _M_refcount._M_get_use_count(); } + + bool + expired() const // never throws + { return _M_refcount._M_get_use_count() == 0; } + + void + reset() // never throws + { __weak_ptr().swap(*this); } + + void + swap(__weak_ptr& __s) // never throws + { + std::swap(_M_ptr, __s._M_ptr); + _M_refcount._M_swap(__s._M_refcount); + } + + private: + // Used by __enable_shared_from_this. + void + _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) + { + _M_ptr = __ptr; + _M_refcount = __refcount; + } + + template<typename _Tp1> + bool + _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const + { return _M_refcount < __rhs._M_refcount; } + + template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; + template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; + friend class __enable_shared_from_this<_Tp, _Lp>; + friend class enable_shared_from_this<_Tp>; + + // Friend injected into namespace and found by ADL. + template<typename _Tp1> + friend inline bool + operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs) + { return __lhs._M_less(__rhs); } + + _Tp* _M_ptr; // Contained pointer. + __weak_count<_Lp> _M_refcount; // Reference counter. + }; + + // 2.2.4.7 weak_ptr specialized algorithms. + template<typename _Tp, _Lock_policy _Lp> + inline void + swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) + { __a.swap(__b); } + + + template<typename _Tp, _Lock_policy _Lp> + class __enable_shared_from_this + { + protected: + __enable_shared_from_this() { } + + __enable_shared_from_this(const __enable_shared_from_this&) { } + + __enable_shared_from_this& + operator=(const __enable_shared_from_this&) + { return *this; } + + ~__enable_shared_from_this() { } + + public: + __shared_ptr<_Tp, _Lp> + shared_from_this() + { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } + + __shared_ptr<const _Tp, _Lp> + shared_from_this() const + { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } + + private: + template<typename _Tp1> + void + _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const + { _M_weak_this._M_assign(__p, __n); } + + template<typename _Tp1> + friend void + __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, + const __enable_shared_from_this* __pe, + const _Tp1* __px) + { + if (__pe != 0) + __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); + } + + mutable __weak_ptr<_Tp, _Lp> _M_weak_this; + }; + + + // The actual TR1 shared_ptr, with forwarding constructors and + // assignment operators. + template<typename _Tp> + class shared_ptr + : public __shared_ptr<_Tp> + { + public: + shared_ptr() + : __shared_ptr<_Tp>() { } + + template<typename _Tp1> + explicit + shared_ptr(_Tp1* __p) + : __shared_ptr<_Tp>(__p) { } + + template<typename _Tp1, typename _Deleter> + shared_ptr(_Tp1* __p, _Deleter __d) + : __shared_ptr<_Tp>(__p, __d) { } + + template<typename _Tp1> + shared_ptr(const shared_ptr<_Tp1>& __r) + : __shared_ptr<_Tp>(__r) { } + + template<typename _Tp1> + explicit + shared_ptr(const weak_ptr<_Tp1>& __r) + : __shared_ptr<_Tp>(__r) { } + + template<typename _Tp1> + explicit + shared_ptr(std::auto_ptr<_Tp1>& __r) + : __shared_ptr<_Tp>(__r) { } + + template<typename _Tp1> + shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag) + : __shared_ptr<_Tp>(__r, __static_cast_tag()) { } + + template<typename _Tp1> + shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag) + : __shared_ptr<_Tp>(__r, __const_cast_tag()) { } + + template<typename _Tp1> + shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag) + : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { } + + template<typename _Tp1> + shared_ptr& + operator=(const shared_ptr<_Tp1>& __r) // never throws + { + this->__shared_ptr<_Tp>::operator=(__r); + return *this; + } + + template<typename _Tp1> + shared_ptr& + operator=(std::auto_ptr<_Tp1>& __r) + { + this->__shared_ptr<_Tp>::operator=(__r); + return *this; + } + }; + + template<typename _Tp, typename _Tp1> + shared_ptr<_Tp> + static_pointer_cast(const shared_ptr<_Tp1>& __r) + { return shared_ptr<_Tp>(__r, __static_cast_tag()); } + + template<typename _Tp, typename _Tp1> + shared_ptr<_Tp> + const_pointer_cast(const shared_ptr<_Tp1>& __r) + { return shared_ptr<_Tp>(__r, __const_cast_tag()); } + + template<typename _Tp, typename _Tp1> + shared_ptr<_Tp> + dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) + { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); } + + + // The actual TR1 weak_ptr, with forwarding constructors and + // assignment operators. + template<typename _Tp> + class weak_ptr + : public __weak_ptr<_Tp> + { + public: + weak_ptr() + : __weak_ptr<_Tp>() { } + + template<typename _Tp1> + weak_ptr(const weak_ptr<_Tp1>& __r) + : __weak_ptr<_Tp>(__r) { } + + template<typename _Tp1> + weak_ptr(const shared_ptr<_Tp1>& __r) + : __weak_ptr<_Tp>(__r) { } + + template<typename _Tp1> + weak_ptr& + operator=(const weak_ptr<_Tp1>& __r) // never throws + { + this->__weak_ptr<_Tp>::operator=(__r); + return *this; + } + + template<typename _Tp1> + weak_ptr& + operator=(const shared_ptr<_Tp1>& __r) // never throws + { + this->__weak_ptr<_Tp>::operator=(__r); + return *this; + } + + shared_ptr<_Tp> + lock() const // never throws + { +#ifdef __GTHREADS + if (this->expired()) + return shared_ptr<_Tp>(); + + try + { + return shared_ptr<_Tp>(*this); + } + catch(const bad_weak_ptr&) + { + return shared_ptr<_Tp>(); + } +#else + return this->expired() ? shared_ptr<_Tp>() + : shared_ptr<_Tp>(*this); +#endif + } + }; + + + template<typename _Tp> + class enable_shared_from_this + { + protected: + enable_shared_from_this() { } + + enable_shared_from_this(const enable_shared_from_this&) { } + + enable_shared_from_this& + operator=(const enable_shared_from_this&) + { return *this; } + + ~enable_shared_from_this() { } + + public: + shared_ptr<_Tp> + shared_from_this() + { return shared_ptr<_Tp>(this->_M_weak_this); } + + shared_ptr<const _Tp> + shared_from_this() const + { return shared_ptr<const _Tp>(this->_M_weak_this); } + + private: + template<typename _Tp1> + void + _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const + { _M_weak_this._M_assign(__p, __n); } + + template<typename _Tp1> + friend void + __enable_shared_from_this_helper(const __shared_count<>& __pn, + const enable_shared_from_this* __pe, + const _Tp1* __px) + { + if (__pe != 0) + __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); + } + + mutable weak_ptr<_Tp> _M_weak_this; + }; + +_GLIBCXX_END_NAMESPACE +} // namespace std + +#endif diff --git a/libstdc++/include/tr1/cctype b/libstdc++/include/tr1/cctype new file mode 100644 index 0000000..8ddfa89 --- /dev/null +++ b/libstdc++/include/tr1/cctype @@ -0,0 +1,56 @@ +// TR1 cctype -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cctype + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CCTYPE +#define _TR1_CCTYPE 1 + +#include <bits/c++config.h> +#include <cctype> + +#if _GLIBCXX_USE_C99_CTYPE_TR1 + +#undef isblank + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + using ::isblank; + +_GLIBCXX_END_NAMESPACE +} + +#endif + +#endif diff --git a/libstdc++/include/tr1/cfenv b/libstdc++/include/tr1/cfenv new file mode 100644 index 0000000..ddcce74c --- /dev/null +++ b/libstdc++/include/tr1/cfenv @@ -0,0 +1,84 @@ +// TR1 cctype -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cfenv + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CFENV +#define _TR1_CFENV 1 + +#include <bits/c++config.h> + +#if _GLIBCXX_USE_C99_FENV_TR1 + +#include <fenv.h> + +#undef feclearexcept +#undef fegetexceptflag +#undef feraiseexcept +#undef fesetexceptflag +#undef fetestexcept +#undef fegetround +#undef fesetround +#undef fegetenv +#undef feholdexcept +#undef fesetenv +#undef feupdateenv + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // types + using ::fenv_t; + using ::fexcept_t; + + // functions + using ::feclearexcept; + using ::fegetexceptflag; + using ::feraiseexcept; + using ::fesetexceptflag; + using ::fetestexcept; + + using ::fegetround; + using ::fesetround; + + using ::fegetenv; + using ::feholdexcept; + using ::fesetenv; + using ::feupdateenv; + +_GLIBCXX_END_NAMESPACE +} + +#endif + +#endif diff --git a/libstdc++/include/tr1/cfloat b/libstdc++/include/tr1/cfloat new file mode 100644 index 0000000..1514ff7 --- /dev/null +++ b/libstdc++/include/tr1/cfloat @@ -0,0 +1,47 @@ +// TR1 cfloat -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cfloat + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CFLOAT +#define _TR1_CFLOAT 1 + +#include <cfloat> + +#ifndef DECIMAL_DIG +#define DECIMAL_DIG __DECIMAL_DIG__ +#endif + +#ifndef FLT_EVAL_METHOD +#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ +#endif + +#endif diff --git a/libstdc++/include/tr1/cinttypes b/libstdc++/include/tr1/cinttypes new file mode 100644 index 0000000..03bdd30 --- /dev/null +++ b/libstdc++/include/tr1/cinttypes @@ -0,0 +1,81 @@ +// TR1 cinttypes -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cinttypes + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CINTTYPES +#define _TR1_CINTTYPES 1 + +#include <bits/c++config.h> +#include <tr1/cstdint> + +#if _GLIBCXX_USE_C99_INTTYPES_TR1 + +// For 8.11.1/1 (see C99, Note 184) +#define __STDC_FORMAT_MACROS +#include <inttypes.h> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // types + using ::imaxdiv_t; + + // functions + using ::imaxabs; + + // May collide with _Longlong abs(_Longlong), and is not described + // anywhere outside the synopsis. Likely, a defect. + // + // intmax_t abs(intmax_t) + + using ::imaxdiv; + + // Likewise, with lldiv_t div(_Longlong, _Longlong). + // + // imaxdiv_t div(intmax_t, intmax_t) + + using ::strtoimax; + using ::strtoumax; + +#ifdef _GLIBCXX_USE_WCHAR_T + using ::wcstoimax; + using ::wcstoumax; +#endif + +_GLIBCXX_END_NAMESPACE +} + +#endif + +#endif diff --git a/libstdc++/include/tr1/climits b/libstdc++/include/tr1/climits new file mode 100644 index 0000000..dc04729 --- /dev/null +++ b/libstdc++/include/tr1/climits @@ -0,0 +1,51 @@ +// TR1 climits -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/climits + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CLIMITS +#define _TR1_CLIMITS 1 + +#include <climits> + +#ifndef LLONG_MIN +#define LLONG_MIN -__LONG_LONG_MAX__ - 1 +#endif + +#ifndef LLONG_MAX +#define LLONG_MAX __LONG_LONG_MAX__ +#endif + +#ifndef ULLONG_MAX +#define ULLONG_MAX __LONG_LONG_MAX__ * 2ULL + 1 +#endif + +#endif diff --git a/libstdc++/include/tr1/cmath b/libstdc++/include/tr1/cmath new file mode 100644 index 0000000..f08e86f --- /dev/null +++ b/libstdc++/include/tr1/cmath @@ -0,0 +1,943 @@ +// TR1 cmath -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cmath + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CMATH +#define _TR1_CMATH 1 + +#include <bits/c++config.h> +#include <cmath> +#include <tr1/common.h> + +#if _GLIBCXX_USE_C99_MATH_TR1 + +#undef acosh +#undef acoshf +#undef acoshl +#undef asinh +#undef asinhf +#undef asinhl +#undef atanh +#undef atanhf +#undef atanhl +#undef cbrt +#undef cbrtf +#undef cbrtl +#undef copysign +#undef copysignf +#undef copysignl +#undef erf +#undef erff +#undef erfl +#undef erfc +#undef erfcf +#undef erfcl +#undef exp2 +#undef exp2f +#undef exp2l +#undef expm1 +#undef expm1f +#undef expm1l +#undef fdim +#undef fdimf +#undef fdiml +#undef fma +#undef fmaf +#undef fmal +#undef fmax +#undef fmaxf +#undef fmaxl +#undef fmin +#undef fminf +#undef fminl +#undef hypot +#undef hypotf +#undef hypotl +#undef ilogb +#undef ilogbf +#undef ilogbl +#undef lgamma +#undef lgammaf +#undef lgammal +#undef llrint +#undef llrintf +#undef llrintl +#undef llround +#undef llroundf +#undef llroundl +#undef log1p +#undef log1pf +#undef log1pl +#undef log2 +#undef log2f +#undef log2l +#undef logb +#undef logbf +#undef logbl +#undef lrint +#undef lrintf +#undef lrintl +#undef lround +#undef lroundf +#undef lroundl +#undef nan +#undef nanf +#undef nanl +#undef nearbyint +#undef nearbyintf +#undef nearbyintl +#undef nextafter +#undef nextafterf +#undef nextafterl +#undef nexttoward +#undef nexttowardf +#undef nexttowardl +#undef remainder +#undef remainderf +#undef remainderl +#undef remquo +#undef remquo +#undef remquo +#undef rint +#undef rintf +#undef rintl +#undef round +#undef roundf +#undef roundl +#undef scalbln +#undef scalblnf +#undef scalblnl +#undef scalbn +#undef scalbnf +#undef scalbnl +#undef tgamma +#undef tgammaf +#undef tgammal +#undef trunc +#undef truncf +#undef truncl + +#endif + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + +#if _GLIBCXX_USE_C99_MATH_TR1 + + // types + using ::double_t; + using ::float_t; + + // functions + using ::acosh; + using ::acoshf; + using ::acoshl; + + using ::asinh; + using ::asinhf; + using ::asinhl; + + using ::atanh; + using ::atanhf; + using ::atanhl; + + using ::cbrt; + using ::cbrtf; + using ::cbrtl; + + using ::copysign; + using ::copysignf; + using ::copysignl; + + using ::erf; + using ::erff; + using ::erfl; + + using ::erfc; + using ::erfcf; + using ::erfcl; + + using ::exp2; + using ::exp2f; + using ::exp2l; + + using ::expm1; + using ::expm1f; + using ::expm1l; + + using ::fdim; + using ::fdimf; + using ::fdiml; + + using ::fma; + using ::fmaf; + using ::fmal; + + using ::fmax; + using ::fmaxf; + using ::fmaxl; + + using ::fmin; + using ::fminf; + using ::fminl; + + using ::hypot; + using ::hypotf; + using ::hypotl; + + using ::ilogb; + using ::ilogbf; + using ::ilogbl; + + using ::lgamma; + using ::lgammaf; + using ::lgammal; + + using ::llrint; + using ::llrintf; + using ::llrintl; + + using ::llround; + using ::llroundf; + using ::llroundl; + + using ::log1p; + using ::log1pf; + using ::log1pl; + + using ::log2; + using ::log2f; + using ::log2l; + + using ::logb; + using ::logbf; + using ::logbl; + + using ::lrint; + using ::lrintf; + using ::lrintl; + + using ::lround; + using ::lroundf; + using ::lroundl; + + using ::nan; + using ::nanf; + using ::nanl; + + using ::nearbyint; + using ::nearbyintf; + using ::nearbyintl; + + using ::nextafter; + using ::nextafterf; + using ::nextafterl; + + using ::nexttoward; + using ::nexttowardf; + using ::nexttowardl; + + using ::remainder; + using ::remainderf; + using ::remainderl; + + using ::remquo; + using ::remquo; + using ::remquo; + + using ::rint; + using ::rintf; + using ::rintl; + + using ::round; + using ::roundf; + using ::roundl; + + using ::scalbln; + using ::scalblnf; + using ::scalblnl; + + using ::scalbn; + using ::scalbnf; + using ::scalbnl; + + using ::tgamma; + using ::tgammaf; + using ::tgammal; + + using ::trunc; + using ::truncf; + using ::truncl; + +#endif + +#if _GLIBCXX_USE_C99_MATH +#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC + + /// @brief Function template definitions [8.16.3]. + // + using std::signbit; + + using std::fpclassify; + + using std::isfinite; + using std::isinf; + using std::isnan; + using std::isnormal; + + using std::isgreater; + using std::isgreaterequal; + using std::isless; + using std::islessequal; + using std::islessgreater; + using std::isunordered; +#endif +#endif + +#if _GLIBCXX_USE_C99_MATH_TR1 + + /// @brief Additional overloads [8.16.4]. + // + using std::acos; + + inline float + acosh(float __x) + { return __builtin_acoshf(__x); } + + inline long double + acosh(long double __x) + { return __builtin_acoshl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + acosh(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return acosh(__type(__x)); + } + + using std::asin; + + inline float + asinh(float __x) + { return __builtin_asinhf(__x); } + + inline long double + asinh(long double __x) + { return __builtin_asinhl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + asinh(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return asinh(__type(__x)); + } + + using std::atan; + + // Workaround for c++/21682. + namespace __detail + { + template<typename _Tp, typename _Up> + inline typename + __gnu_cxx::__enable_if<std::__is_floating<_Tp>::__value + || std::__is_floating<_Up>::__value, + typename + std::tr1::__promote_2<_Tp, _Up>::__type>::__type + atan2(_Tp __y, _Up __x) + { + typedef typename std::tr1::__promote_2<_Tp, _Up>::__type __type; + return std::atan2(__type(__y), __type(__x)); + } + } // namespace __detail + + using std::atan2; + using __detail::atan2; + + inline float + atanh(float __x) + { return __builtin_atanhf(__x); } + + inline long double + atanh(long double __x) + { return __builtin_atanhl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + atanh(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return atanh(__type(__x)); + } + + inline float + cbrt(float __x) + { return __builtin_cbrtf(__x); } + + inline long double + cbrt(long double __x) + { return __builtin_cbrtl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + cbrt(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return cbrt(__type(__x)); + } + + using std::ceil; + + inline float + copysign(float __x, float __y) + { return __builtin_copysignf(__x, __y); } + + inline long double + copysign(long double __x, long double __y) + { return __builtin_copysignl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __promote_2<_Tp, _Up>::__type + copysign(_Tp __x, _Up __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return copysign(__type(__x), __type(__y)); + } + + using std::cos; + using std::cosh; + + inline float + erf(float __x) + { return __builtin_erff(__x); } + + inline long double + erf(long double __x) + { return __builtin_erfl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + erf(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return erf(__type(__x)); + } + + inline float + erfc(float __x) + { return __builtin_erfcf(__x); } + + inline long double + erfc(long double __x) + { return __builtin_erfcl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + erfc(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return erfc(__type(__x)); + } + + using std::exp; + + inline float + exp2(float __x) + { return __builtin_exp2f(__x); } + + inline long double + exp2(long double __x) + { return __builtin_exp2l(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + exp2(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return exp2(__type(__x)); + } + + inline float + expm1(float __x) + { return __builtin_expm1f(__x); } + + inline long double + expm1(long double __x) + { return __builtin_expm1l(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + expm1(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return expm1(__type(__x)); + } + + using std::fabs; + + inline float + fdim(float __x, float __y) + { return __builtin_fdimf(__x, __y); } + + inline long double + fdim(long double __x, long double __y) + { return __builtin_fdiml(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __promote_2<_Tp, _Up>::__type + fdim(_Tp __x, _Up __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return fdim(__type(__x), __type(__y)); + } + + using std::floor; + + inline float + fma(float __x, float __y, float __z) + { return __builtin_fmaf(__x, __y, __z); } + + inline long double + fma(long double __x, long double __y, long double __z) + { return __builtin_fmal(__x, __y, __z); } + + template<typename _Tp, typename _Up, typename _Vp> + inline typename __promote_3<_Tp, _Up, _Vp>::__type + fma(_Tp __x, _Up __y, _Vp __z) + { + typedef typename __promote_3<_Tp, _Up, _Vp>::__type __type; + return fma(__type(__x), __type(__y), __type(__z)); + } + + inline float + fmax(float __x, float __y) + { return __builtin_fmaxf(__x, __y); } + + inline long double + fmax(long double __x, long double __y) + { return __builtin_fmaxl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __promote_2<_Tp, _Up>::__type + fmax(_Tp __x, _Up __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return fmax(__type(__x), __type(__y)); + } + + inline float + fmin(float __x, float __y) + { return __builtin_fminf(__x, __y); } + + inline long double + fmin(long double __x, long double __y) + { return __builtin_fminl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __promote_2<_Tp, _Up>::__type + fmin(_Tp __x, _Up __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return fmin(__type(__x), __type(__y)); + } + + using std::fmod; + using std::frexp; + + inline float + hypot(float __x, float __y) + { return __builtin_hypotf(__x, __y); } + + inline long double + hypot(long double __x, long double __y) + { return __builtin_hypotl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __promote_2<_Tp, _Up>::__type + hypot(_Tp __x, _Up __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return hypot(__type(__x), __type(__y)); + } + + inline int + ilogb(float __x) + { return __builtin_ilogbf(__x); } + + inline int + ilogb(long double __x) + { return __builtin_ilogbl(__x); } + + template<typename _Tp> + inline int + ilogb(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return ilogb(__type(__x)); + } + + using std::ldexp; + + inline float + lgamma(float __x) + { return __builtin_lgammaf(__x); } + + inline long double + lgamma(long double __x) + { return __builtin_lgammal(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + lgamma(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return lgamma(__type(__x)); + } + + inline long long + llrint(float __x) + { return __builtin_llrintf(__x); } + + inline long long + llrint(long double __x) + { return __builtin_llrintl(__x); } + + template<typename _Tp> + inline long long + llrint(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return llrint(__type(__x)); + } + + inline long long + llround(float __x) + { return __builtin_llroundf(__x); } + + inline long long + llround(long double __x) + { return __builtin_llroundl(__x); } + + template<typename _Tp> + inline long long + llround(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return llround(__type(__x)); + } + + using std::log; + using std::log10; + + inline float + log1p(float __x) + { return __builtin_log1pf(__x); } + + inline long double + log1p(long double __x) + { return __builtin_log1pl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + log1p(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return log1p(__type(__x)); + } + + // DR 568. + inline float + log2(float __x) + { return __builtin_log2f(__x); } + + inline long double + log2(long double __x) + { return __builtin_log2l(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + log2(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return log2(__type(__x)); + } + + inline float + logb(float __x) + { return __builtin_logbf(__x); } + + inline long double + logb(long double __x) + { return __builtin_logbl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + logb(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return logb(__type(__x)); + } + + inline long + lrint(float __x) + { return __builtin_lrintf(__x); } + + inline long + lrint(long double __x) + { return __builtin_lrintl(__x); } + + template<typename _Tp> + inline long + lrint(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return lrint(__type(__x)); + } + + inline long + lround(float __x) + { return __builtin_lroundf(__x); } + + inline long + lround(long double __x) + { return __builtin_lroundl(__x); } + + template<typename _Tp> + inline long + lround(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return lround(__type(__x)); + } + + inline float + nearbyint(float __x) + { return __builtin_nearbyintf(__x); } + + inline long double + nearbyint(long double __x) + { return __builtin_nearbyintl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + nearbyint(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return nearbyint(__type(__x)); + } + + inline float + nextafter(float __x, float __y) + { return __builtin_nextafterf(__x, __y); } + + inline long double + nextafter(long double __x, long double __y) + { return __builtin_nextafterl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __promote_2<_Tp, _Up>::__type + nextafter(_Tp __x, _Up __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return nextafter(__type(__x), __type(__y)); + } + + inline float + nexttoward(float __x, long double __y) + { return __builtin_nexttowardf(__x, __y); } + + inline long double + nexttoward(long double __x, long double __y) + { return __builtin_nexttowardl(__x, __y); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + nexttoward(_Tp __x, long double __y) + { + typedef typename __promote<_Tp>::__type __type; + return nexttoward(__type(__x), __y); + } + + using std::pow; + + // DR 550. + template<typename _Tp, typename _Up> + inline typename __promote_2<_Tp, _Up>::__type + pow(_Tp __x, _Up __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return pow(__type(__x), __type(__y)); + } + + inline float + remainder(float __x, float __y) + { return __builtin_remainderf(__x, __y); } + + inline long double + remainder(long double __x, long double __y) + { return __builtin_remainderl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __promote_2<_Tp, _Up>::__type + remainder(_Tp __x, _Up __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return remainder(__type(__x), __type(__y)); + } + + inline float + remquo(float __x, float __y, int* __pquo) + { return __builtin_remquof(__x, __y, __pquo); } + + inline long double + remquo(long double __x, long double __y, int* __pquo) + { return __builtin_remquol(__x, __y, __pquo); } + + template<typename _Tp, typename _Up> + inline typename __promote_2<_Tp, _Up>::__type + remquo(_Tp __x, _Up __y, int* __pquo) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return remquo(__type(__x), __type(__y), __pquo); + } + + inline float + rint(float __x) + { return __builtin_rintf(__x); } + + inline long double + rint(long double __x) + { return __builtin_rintl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + rint(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return rint(__type(__x)); + } + + inline float + round(float __x) + { return __builtin_roundf(__x); } + + inline long double + round(long double __x) + { return __builtin_roundl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + round(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return round(__type(__x)); + } + + inline float + scalbln(float __x, long __ex) + { return __builtin_scalblnf(__x, __ex); } + + inline long double + scalbln(long double __x, long __ex) + { return __builtin_scalblnl(__x, __ex); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + scalbln(_Tp __x, long __ex) + { + typedef typename __promote<_Tp>::__type __type; + return scalbln(__type(__x), __ex); + } + + inline float + scalbn(float __x, int __ex) + { return __builtin_scalbnf(__x, __ex); } + + inline long double + scalbn(long double __x, int __ex) + { return __builtin_scalbnl(__x, __ex); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + scalbn(_Tp __x, int __ex) + { + typedef typename __promote<_Tp>::__type __type; + return scalbn(__type(__x), __ex); + } + + using std::sin; + using std::sinh; + using std::sqrt; + using std::tan; + using std::tanh; + + inline float + tgamma(float __x) + { return __builtin_tgammaf(__x); } + + inline long double + tgamma(long double __x) + { return __builtin_tgammal(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + tgamma(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return tgamma(__type(__x)); + } + + inline float + trunc(float __x) + { return __builtin_truncf(__x); } + + inline long double + trunc(long double __x) + { return __builtin_truncl(__x); } + + template<typename _Tp> + inline typename __promote<_Tp>::__type + trunc(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return trunc(__type(__x)); + } + +#endif + +_GLIBCXX_END_NAMESPACE +} + +#endif diff --git a/libstdc++/include/tr1/common.h b/libstdc++/include/tr1/common.h new file mode 100644 index 0000000..7d098f8 --- /dev/null +++ b/libstdc++/include/tr1/common.h @@ -0,0 +1,78 @@ +// Internal header for TR1 complex -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/common.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_COMMON_H +#define _TR1_COMMON_H 1 + +#include <tr1/type_traits> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + template<typename _Tp, bool = is_integral<_Tp>::value> + struct __promote + { typedef double __type; }; + + template<typename _Tp> + struct __promote<_Tp, false> + { typedef _Tp __type; }; + + template<typename _Tp, typename _Up> + struct __promote_2 + { + private: + typedef typename __promote<_Tp>::__type __type1; + typedef typename __promote<_Up>::__type __type2; + + public: + typedef __typeof__(__type1() + __type2()) __type; + }; + + template<typename _Tp, typename _Up, typename _Vp> + struct __promote_3 + { + private: + typedef typename __promote<_Tp>::__type __type1; + typedef typename __promote<_Up>::__type __type2; + typedef typename __promote<_Vp>::__type __type3; + + public: + typedef __typeof__(__type1() + __type2() + __type3()) __type; + }; + +_GLIBCXX_END_NAMESPACE +} // namespace std + +#endif diff --git a/libstdc++/include/tr1/complex b/libstdc++/include/tr1/complex new file mode 100644 index 0000000..0817ef7 --- /dev/null +++ b/libstdc++/include/tr1/complex @@ -0,0 +1,409 @@ +// TR1 complex -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/complex + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_COMPLEX +#define _TR1_COMPLEX 1 + +#include "../complex" +#include <tr1/common.h> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // Forward declarations. + template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); + template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); + template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); + + template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); + template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); + template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); + template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&); + + /// @brief acos(__z) [8.1.2]. + // Effects: Behaves the same as C99 function cacos, defined + // in subclause 7.3.5.1. + template<typename _Tp> + inline std::complex<_Tp> + __complex_acos(const std::complex<_Tp>& __z) + { + const std::complex<_Tp> __t = std::tr1::asin(__z); + const _Tp __pi_2 = 1.5707963267948966192313216916397514L; + return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_acos(__complex__ float __z) + { return __builtin_cacosf(__z); } + + inline __complex__ double + __complex_acos(__complex__ double __z) + { return __builtin_cacos(__z); } + + inline __complex__ long double + __complex_acos(const __complex__ long double& __z) + { return __builtin_cacosl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + acos(const std::complex<_Tp>& __z) + { return __complex_acos(__z.__rep()); } +#else + template<typename _Tp> + inline std::complex<_Tp> + acos(const std::complex<_Tp>& __z) + { return __complex_acos(__z); } +#endif + + /// @brief asin(__z) [8.1.3]. + // Effects: Behaves the same as C99 function casin, defined + // in subclause 7.3.5.2. + template<typename _Tp> + inline std::complex<_Tp> + __complex_asin(const std::complex<_Tp>& __z) + { + std::complex<_Tp> __t(-__z.imag(), __z.real()); + __t = std::tr1::asinh(__t); + return std::complex<_Tp>(__t.imag(), -__t.real()); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_asin(__complex__ float __z) + { return __builtin_casinf(__z); } + + inline __complex__ double + __complex_asin(__complex__ double __z) + { return __builtin_casin(__z); } + + inline __complex__ long double + __complex_asin(const __complex__ long double& __z) + { return __builtin_casinl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + asin(const std::complex<_Tp>& __z) + { return __complex_asin(__z.__rep()); } +#else + template<typename _Tp> + inline std::complex<_Tp> + asin(const std::complex<_Tp>& __z) + { return __complex_asin(__z); } +#endif + + /// @brief atan(__z) [8.1.4]. + // Effects: Behaves the same as C99 function catan, defined + // in subclause 7.3.5.3. + template<typename _Tp> + std::complex<_Tp> + __complex_atan(const std::complex<_Tp>& __z) + { + const _Tp __r2 = __z.real() * __z.real(); + const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); + + _Tp __num = __z.imag() + _Tp(1.0); + _Tp __den = __z.imag() - _Tp(1.0); + + __num = __r2 + __num * __num; + __den = __r2 + __den * __den; + + return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), + _Tp(0.25) * log(__num / __den)); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_atan(__complex__ float __z) + { return __builtin_catanf(__z); } + + inline __complex__ double + __complex_atan(__complex__ double __z) + { return __builtin_catan(__z); } + + inline __complex__ long double + __complex_atan(const __complex__ long double& __z) + { return __builtin_catanl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + atan(const std::complex<_Tp>& __z) + { return __complex_atan(__z.__rep()); } +#else + template<typename _Tp> + inline std::complex<_Tp> + atan(const std::complex<_Tp>& __z) + { return __complex_atan(__z); } +#endif + + /// @brief acosh(__z) [8.1.5]. + // Effects: Behaves the same as C99 function cacosh, defined + // in subclause 7.3.6.1. + template<typename _Tp> + std::complex<_Tp> + __complex_acosh(const std::complex<_Tp>& __z) + { + std::complex<_Tp> __t((__z.real() - __z.imag()) + * (__z.real() + __z.imag()) - _Tp(1.0), + _Tp(2.0) * __z.real() * __z.imag()); + __t = std::sqrt(__t); + + return std::log(__t + __z); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_acosh(__complex__ float __z) + { return __builtin_cacoshf(__z); } + + inline __complex__ double + __complex_acosh(__complex__ double __z) + { return __builtin_cacosh(__z); } + + inline __complex__ long double + __complex_acosh(const __complex__ long double& __z) + { return __builtin_cacoshl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + acosh(const std::complex<_Tp>& __z) + { return __complex_acosh(__z.__rep()); } +#else + template<typename _Tp> + inline std::complex<_Tp> + acosh(const std::complex<_Tp>& __z) + { return __complex_acosh(__z); } +#endif + + /// @brief asinh(__z) [8.1.6]. + // Effects: Behaves the same as C99 function casin, defined + // in subclause 7.3.6.2. + template<typename _Tp> + std::complex<_Tp> + __complex_asinh(const std::complex<_Tp>& __z) + { + std::complex<_Tp> __t((__z.real() - __z.imag()) + * (__z.real() + __z.imag()) + _Tp(1.0), + _Tp(2.0) * __z.real() * __z.imag()); + __t = std::sqrt(__t); + + return std::log(__t + __z); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_asinh(__complex__ float __z) + { return __builtin_casinhf(__z); } + + inline __complex__ double + __complex_asinh(__complex__ double __z) + { return __builtin_casinh(__z); } + + inline __complex__ long double + __complex_asinh(const __complex__ long double& __z) + { return __builtin_casinhl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + asinh(const std::complex<_Tp>& __z) + { return __complex_asinh(__z.__rep()); } +#else + template<typename _Tp> + inline std::complex<_Tp> + asinh(const std::complex<_Tp>& __z) + { return __complex_asinh(__z); } +#endif + + /// @brief atanh(__z) [8.1.7]. + // Effects: Behaves the same as C99 function catanh, defined + // in subclause 7.3.6.3. + template<typename _Tp> + std::complex<_Tp> + __complex_atanh(const std::complex<_Tp>& __z) + { + const _Tp __i2 = __z.imag() * __z.imag(); + const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); + + _Tp __num = _Tp(1.0) + __z.real(); + _Tp __den = _Tp(1.0) - __z.real(); + + __num = __i2 + __num * __num; + __den = __i2 + __den * __den; + + return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), + _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_atanh(__complex__ float __z) + { return __builtin_catanhf(__z); } + + inline __complex__ double + __complex_atanh(__complex__ double __z) + { return __builtin_catanh(__z); } + + inline __complex__ long double + __complex_atanh(const __complex__ long double& __z) + { return __builtin_catanhl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + atanh(const std::complex<_Tp>& __z) + { return __complex_atanh(__z.__rep()); } +#else + template<typename _Tp> + inline std::complex<_Tp> + atanh(const std::complex<_Tp>& __z) + { return __complex_atanh(__z); } +#endif + + /// @brief fabs(__z) [8.1.8]. + // Effects: Behaves the same as C99 function cabs, defined + // in subclause 7.3.8.1. + template<typename _Tp> + inline std::complex<_Tp> + fabs(const std::complex<_Tp>& __z) + { return std::abs(__z); } + + + /// @brief Additional overloads [8.1.9]. + // + + // See common.h for the primary template. + template<typename _Tp, typename _Up> + struct __promote_2<std::complex<_Tp>, _Up> + { + public: + typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; + }; + + template<typename _Tp, typename _Up> + struct __promote_2<_Tp, std::complex<_Up> > + { + public: + typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; + }; + + template<typename _Tp, typename _Up> + struct __promote_2<std::complex<_Tp>, std::complex<_Up> > + { + public: + typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; + }; + + + using std::arg; + + template<typename _Tp> + inline typename __promote<_Tp>::__type + arg(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return std::arg(std::complex<__type>(__x)); + } + + using std::conj; + + template<typename _Tp> + inline std::complex<typename __promote<_Tp>::__type> + conj(_Tp __x) + { return __x; } + + using std::imag; + + template<typename _Tp> + inline typename __promote<_Tp>::__type + imag(_Tp) + { return _Tp(); } + + using std::norm; + + template<typename _Tp> + inline typename __promote<_Tp>::__type + norm(_Tp __x) + { + typedef typename __promote<_Tp>::__type __type; + return __type(__x) * __type(__x); + } + + using std::polar; + + template<typename _Tp, typename _Up> + inline std::complex<typename __promote_2<_Tp, _Up>::__type> + polar(const _Tp& __rho, const _Up& __theta) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return std::polar(__type(__rho), __type(__theta)); + } + + using std::pow; + + template<typename _Tp, typename _Up> + inline std::complex<typename __promote_2<_Tp, _Up>::__type> + pow(const std::complex<_Tp>& __x, const _Up& __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return std::pow(std::complex<__type>(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + inline std::complex<typename __promote_2<_Tp, _Up>::__type> + pow(const _Tp& __x, const std::complex<_Up>& __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return std::pow(__type(__x), std::complex<__type>(__y)); + } + + template<typename _Tp, typename _Up> + inline std::complex<typename __promote_2<_Tp, _Up>::__type> + pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) + { + typedef typename __promote_2<_Tp, _Up>::__type __type; + return std::pow(std::complex<__type>(__x), + std::complex<__type>(__y)); + } + + using std::real; + + template<typename _Tp> + inline typename __promote<_Tp>::__type + real(_Tp __x) + { return __x; } + +_GLIBCXX_END_NAMESPACE +} + +#endif diff --git a/libstdc++/include/tr1/cstdarg b/libstdc++/include/tr1/cstdarg new file mode 100644 index 0000000..e70130e --- /dev/null +++ b/libstdc++/include/tr1/cstdarg @@ -0,0 +1,39 @@ +// TR1 cstdarg -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cstdarg + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CSTDARG +#define _TR1_CSTDARG 1 + +#include <cstdarg> + +#endif diff --git a/libstdc++/include/tr1/cstdbool b/libstdc++/include/tr1/cstdbool new file mode 100644 index 0000000..2406f9e --- /dev/null +++ b/libstdc++/include/tr1/cstdbool @@ -0,0 +1,43 @@ +// TR1 cstdbool -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cstdbool + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CSTDBOOL +#define _TR1_CSTDBOOL 1 + +#include <bits/c++config.h> + +#if _GLIBCXX_HAVE_STDBOOL_H +#include <stdbool.h> +#endif + +#endif diff --git a/libstdc++/include/tr1/cstdint b/libstdc++/include/tr1/cstdint new file mode 100644 index 0000000..af5a90f --- /dev/null +++ b/libstdc++/include/tr1/cstdint @@ -0,0 +1,92 @@ +// TR1 cstdint -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cstdint + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CSTDINT +#define _TR1_CSTDINT 1 + +#include <bits/c++config.h> + +#if _GLIBCXX_USE_C99_STDINT_TR1 + +// For 8.22.1/1 (see C99, Notes 219, 220, 222) +#define __STDC_LIMIT_MACROS +#define __STDC_CONSTANT_MACROS +#include <stdint.h> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + using ::int8_t; + using ::int16_t; + using ::int32_t; + using ::int64_t; + + using ::int_fast8_t; + using ::int_fast16_t; + using ::int_fast32_t; + using ::int_fast64_t; + + using ::int_least8_t; + using ::int_least16_t; + using ::int_least32_t; + using ::int_least64_t; + + using ::intmax_t; + using ::intptr_t; + + using ::uint8_t; + using ::uint16_t; + using ::uint32_t; + using ::uint64_t; + + using ::uint_fast8_t; + using ::uint_fast16_t; + using ::uint_fast32_t; + using ::uint_fast64_t; + + using ::uint_least8_t; + using ::uint_least16_t; + using ::uint_least32_t; + using ::uint_least64_t; + + using ::uintmax_t; + using ::uintptr_t; + +_GLIBCXX_END_NAMESPACE +} + +#endif + +#endif diff --git a/libstdc++/include/tr1/cstdio b/libstdc++/include/tr1/cstdio new file mode 100644 index 0000000..1cf41b5 --- /dev/null +++ b/libstdc++/include/tr1/cstdio @@ -0,0 +1,57 @@ +// TR1 cstdio -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cstdio + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CSTDIO +#define _TR1_CSTDIO 1 + +#include <bits/c++config.h> +#include <cstdio> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + +#if _GLIBCXX_USE_C99 + using std::snprintf; + using std::vsnprintf; + + using std::vfscanf; + using std::vscanf; + using std::vsscanf; +#endif + +_GLIBCXX_END_NAMESPACE +} + +#endif diff --git a/libstdc++/include/tr1/cstdlib b/libstdc++/include/tr1/cstdlib new file mode 100644 index 0000000..f7f8d7d --- /dev/null +++ b/libstdc++/include/tr1/cstdlib @@ -0,0 +1,79 @@ +// TR1 cstdlib -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cstdlib + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CSTDLIB +#define _TR1_CSTDLIB 1 + +#include <bits/c++config.h> + +#if _GLIBCXX_HOSTED + +#include <cstdlib> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + +#if _GLIBCXX_USE_C99 + +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + // types + using std::lldiv_t; + + // functions + using std::llabs; + using std::lldiv; +#endif + + using std::atoll; + using std::strtoll; + using std::strtoull; + + using std::strtof; + using std::strtold; + + // overloads + using std::abs; +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using std::div; +#endif + +#endif + +_GLIBCXX_END_NAMESPACE +} + +#endif + +#endif diff --git a/libstdc++/include/tr1/ctgmath b/libstdc++/include/tr1/ctgmath new file mode 100644 index 0000000..eb91185 --- /dev/null +++ b/libstdc++/include/tr1/ctgmath @@ -0,0 +1,39 @@ +// TR1 ctgmath -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/ctgmath + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CTGMATH +#define _TR1_CTGMATH 1 + +#include <tr1/cmath> + +#endif diff --git a/libstdc++/include/tr1/ctime b/libstdc++/include/tr1/ctime new file mode 100644 index 0000000..45e0839 --- /dev/null +++ b/libstdc++/include/tr1/ctime @@ -0,0 +1,39 @@ +// TR1 ctime -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/ctime + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CTIME +#define _TR1_CTIME 1 + +#include <ctime> + +#endif diff --git a/libstdc++/include/tr1/ctype.h b/libstdc++/include/tr1/ctype.h new file mode 100644 index 0000000..945b13b --- /dev/null +++ b/libstdc++/include/tr1/ctype.h @@ -0,0 +1,39 @@ +// TR1 ctype.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/ctype.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CTYPE_H +#define _TR1_CTYPE_H 1 + +#include <tr1/cctype> + +#endif diff --git a/libstdc++/include/tr1/cwchar b/libstdc++/include/tr1/cwchar new file mode 100644 index 0000000..b918b37d --- /dev/null +++ b/libstdc++/include/tr1/cwchar @@ -0,0 +1,72 @@ +// TR1 cwchar -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cwchar + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CWCHAR +#define _TR1_CWCHAR 1 + +#include <bits/c++config.h> + +#if _GLIBCXX_USE_WCHAR_T + +#include <cwchar> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + +#if _GLIBCXX_HAVE_WCSTOF + using std::wcstof; +#endif +#if _GLIBCXX_HAVE_VFWSCANF + using std::vfwscanf; +#endif +#if _GLIBCXX_HAVE_VSWSCANF + using std::vswscanf; +#endif +#if _GLIBCXX_HAVE_VWSCANF + using std::vwscanf; +#endif + +#if _GLIBCXX_USE_C99 + using std::wcstold; + using std::wcstoll; + using std::wcstoull; +#endif + +_GLIBCXX_END_NAMESPACE +} + +#endif + +#endif diff --git a/libstdc++/include/tr1/cwctype b/libstdc++/include/tr1/cwctype new file mode 100644 index 0000000..7cc7a36 --- /dev/null +++ b/libstdc++/include/tr1/cwctype @@ -0,0 +1,57 @@ +// TR1 cwctype -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/cwctype + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CWCTYPE +#define _TR1_CWCTYPE 1 + +#include <bits/c++config.h> + +#if _GLIBCXX_USE_WCHAR_T + +#include <cwctype> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + +#if _GLIBCXX_HAVE_ISWBLANK + using std::iswblank; +#endif + +_GLIBCXX_END_NAMESPACE +} + +#endif + +#endif diff --git a/libstdc++/include/tr1/fenv.h b/libstdc++/include/tr1/fenv.h new file mode 100644 index 0000000..91fa40f --- /dev/null +++ b/libstdc++/include/tr1/fenv.h @@ -0,0 +1,39 @@ +// TR1 fenv.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/fenv.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_FENV_H +#define _TR1_FENV_H 1 + +#include <tr1/cfenv> + +#endif diff --git a/libstdc++/include/tr1/float.h b/libstdc++/include/tr1/float.h new file mode 100644 index 0000000..5e99fe5 --- /dev/null +++ b/libstdc++/include/tr1/float.h @@ -0,0 +1,39 @@ +// TR1 float.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/float.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_FLOAT_H +#define _TR1_FLOAT_H 1 + +#include <tr1/cfloat> + +#endif diff --git a/libstdc++/include/tr1/functional b/libstdc++/include/tr1/functional new file mode 100644 index 0000000..f3cc78d --- /dev/null +++ b/libstdc++/include/tr1/functional @@ -0,0 +1,1106 @@ +// TR1 functional header -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006, 2007 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. + +/** @file tr1/functional + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_FUNCTIONAL +#define _TR1_FUNCTIONAL 1 + +#pragma GCC system_header + +#include "../functional" +#include <typeinfo> +#include <tr1/type_traits> +#include <ext/type_traits.h> +#include <cstdlib> // for std::abort +#include <tr1/tuple> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + template<typename _MemberPointer> + class _Mem_fn; + + /** + * @if maint + * Actual implementation of _Has_result_type, which uses SFINAE to + * determine if the type _Tp has a publicly-accessible member type + * result_type. + * @endif + */ + template<typename _Tp> + class _Has_result_type_helper : __sfinae_types + { + template<typename _Up> + struct _Wrap_type + { }; + + template<typename _Up> + static __one __test(_Wrap_type<typename _Up::result_type>*); + + template<typename _Up> + static __two __test(...); + + public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; + }; + + template<typename _Tp> + struct _Has_result_type + : integral_constant< + bool, + _Has_result_type_helper<typename remove_cv<_Tp>::type>::value> + { }; + + /** + * @if maint + * If we have found a result_type, extract it. + * @endif + */ + template<bool _Has_result_type, typename _Functor> + struct _Maybe_get_result_type + { }; + + template<typename _Functor> + struct _Maybe_get_result_type<true, _Functor> + { + typedef typename _Functor::result_type result_type; + }; + + /** + * @if maint + * Base class for any function object that has a weak result type, as + * defined in 3.3/3 of TR1. + * @endif + */ + template<typename _Functor> + struct _Weak_result_type_impl + : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor> + { + }; + + /** + * @if maint + * Strip top-level cv-qualifiers from the function object and let + * _Weak_result_type_impl perform the real work. + * @endif + */ + template<typename _Functor> + struct _Weak_result_type + : _Weak_result_type_impl<typename remove_cv<_Functor>::type> + { + }; + + template<typename _Signature> + class result_of; + + /** + * @if maint + * Actual implementation of result_of. When _Has_result_type is + * true, gets its result from _Weak_result_type. Otherwise, uses + * the function object's member template result to extract the + * result type. + * @endif + */ + template<bool _Has_result_type, typename _Signature> + struct _Result_of_impl; + + // Handle member data pointers using _Mem_fn's logic + template<typename _Res, typename _Class, typename _T1> + struct _Result_of_impl<false, _Res _Class::*(_T1)> + { + typedef typename _Mem_fn<_Res _Class::*> + ::template _Result_type<_T1>::type type; + }; + + /** + * @if maint + * Determines if the type _Tp derives from unary_function. + * @endif + */ + template<typename _Tp> + struct _Derives_from_unary_function : __sfinae_types + { + private: + template<typename _T1, typename _Res> + static __one __test(const volatile unary_function<_T1, _Res>*); + + // It's tempting to change "..." to const volatile void*, but + // that fails when _Tp is a function type. + static __two __test(...); + + public: + static const bool value = sizeof(__test((_Tp*)0)) == 1; + }; + + /** + * @if maint + * Determines if the type _Tp derives from binary_function. + * @endif + */ + template<typename _Tp> + struct _Derives_from_binary_function : __sfinae_types + { + private: + template<typename _T1, typename _T2, typename _Res> + static __one __test(const volatile binary_function<_T1, _T2, _Res>*); + + // It's tempting to change "..." to const volatile void*, but + // that fails when _Tp is a function type. + static __two __test(...); + + public: + static const bool value = sizeof(__test((_Tp*)0)) == 1; + }; + + /** + * @if maint + * Turns a function type into a function pointer type + * @endif + */ + template<typename _Tp, bool _IsFunctionType = is_function<_Tp>::value> + struct _Function_to_function_pointer + { + typedef _Tp type; + }; + + template<typename _Tp> + struct _Function_to_function_pointer<_Tp, true> + { + typedef _Tp* type; + }; + + /** + * @if maint + * Knowing which of unary_function and binary_function _Tp derives + * from, derives from the same and ensures that reference_wrapper + * will have a weak result type. See cases below. + * @endif + */ + template<bool _Unary, bool _Binary, typename _Tp> + struct _Reference_wrapper_base_impl; + + // Not a unary_function or binary_function, so try a weak result type + template<typename _Tp> + struct _Reference_wrapper_base_impl<false, false, _Tp> + : _Weak_result_type<_Tp> + { }; + + // unary_function but not binary_function + template<typename _Tp> + struct _Reference_wrapper_base_impl<true, false, _Tp> + : unary_function<typename _Tp::argument_type, + typename _Tp::result_type> + { }; + + // binary_function but not unary_function + template<typename _Tp> + struct _Reference_wrapper_base_impl<false, true, _Tp> + : binary_function<typename _Tp::first_argument_type, + typename _Tp::second_argument_type, + typename _Tp::result_type> + { }; + + // both unary_function and binary_function. import result_type to + // avoid conflicts. + template<typename _Tp> + struct _Reference_wrapper_base_impl<true, true, _Tp> + : unary_function<typename _Tp::argument_type, + typename _Tp::result_type>, + binary_function<typename _Tp::first_argument_type, + typename _Tp::second_argument_type, + typename _Tp::result_type> + { + typedef typename _Tp::result_type result_type; + }; + + /** + * @if maint + * Derives from unary_function or binary_function when it + * can. Specializations handle all of the easy cases. The primary + * template determines what to do with a class type, which may + * derive from both unary_function and binary_function. + * @endif + */ + template<typename _Tp> + struct _Reference_wrapper_base + : _Reference_wrapper_base_impl< + _Derives_from_unary_function<_Tp>::value, + _Derives_from_binary_function<_Tp>::value, + _Tp> + { }; + + // - a function type (unary) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res(_T1)> + : unary_function<_T1, _Res> + { }; + + // - a function type (binary) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res(_T1, _T2)> + : binary_function<_T1, _T2, _Res> + { }; + + // - a function pointer type (unary) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res(*)(_T1)> + : unary_function<_T1, _Res> + { }; + + // - a function pointer type (binary) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res(*)(_T1, _T2)> + : binary_function<_T1, _T2, _Res> + { }; + + // - a pointer to member function type (unary, no qualifiers) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res (_T1::*)()> + : unary_function<_T1*, _Res> + { }; + + // - a pointer to member function type (binary, no qualifiers) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res (_T1::*)(_T2)> + : binary_function<_T1*, _T2, _Res> + { }; + + // - a pointer to member function type (unary, const) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res (_T1::*)() const> + : unary_function<const _T1*, _Res> + { }; + + // - a pointer to member function type (binary, const) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const> + : binary_function<const _T1*, _T2, _Res> + { }; + + // - a pointer to member function type (unary, volatile) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res (_T1::*)() volatile> + : unary_function<volatile _T1*, _Res> + { }; + + // - a pointer to member function type (binary, volatile) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile> + : binary_function<volatile _T1*, _T2, _Res> + { }; + + // - a pointer to member function type (unary, const volatile) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res (_T1::*)() const volatile> + : unary_function<const volatile _T1*, _Res> + { }; + + // - a pointer to member function type (binary, const volatile) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile> + : binary_function<const volatile _T1*, _T2, _Res> + { }; + + template<typename _Tp> + class reference_wrapper + : public _Reference_wrapper_base<typename remove_cv<_Tp>::type> + { + // If _Tp is a function type, we can't form result_of<_Tp(...)>, + // so turn it into a function pointer type. + typedef typename _Function_to_function_pointer<_Tp>::type + _M_func_type; + + _Tp* _M_data; + public: + typedef _Tp type; + explicit reference_wrapper(_Tp& __indata): _M_data(&__indata) + { } + + reference_wrapper(const reference_wrapper<_Tp>& __inref): + _M_data(__inref._M_data) + { } + + reference_wrapper& + operator=(const reference_wrapper<_Tp>& __inref) + { + _M_data = __inref._M_data; + return *this; + } + + operator _Tp&() const + { return this->get(); } + + _Tp& + get() const + { return *_M_data; } + +#define _GLIBCXX_REPEAT_HEADER <tr1/ref_wrap_iterate.h> +#include <tr1/repeat.h> +#undef _GLIBCXX_REPEAT_HEADER + }; + + + // Denotes a reference should be taken to a variable. + template<typename _Tp> + inline reference_wrapper<_Tp> + ref(_Tp& __t) + { return reference_wrapper<_Tp>(__t); } + + // Denotes a const reference should be taken to a variable. + template<typename _Tp> + inline reference_wrapper<const _Tp> + cref(const _Tp& __t) + { return reference_wrapper<const _Tp>(__t); } + + template<typename _Tp> + inline reference_wrapper<_Tp> + ref(reference_wrapper<_Tp> __t) + { return ref(__t.get()); } + + template<typename _Tp> + inline reference_wrapper<const _Tp> + cref(reference_wrapper<_Tp> __t) + { return cref(__t.get()); } + + template<typename _Tp, bool> + struct _Mem_fn_const_or_non + { + typedef const _Tp& type; + }; + + template<typename _Tp> + struct _Mem_fn_const_or_non<_Tp, false> + { + typedef _Tp& type; + }; + + template<typename _Res, typename _Class> + class _Mem_fn<_Res _Class::*> + { + // This bit of genius is due to Peter Dimov, improved slightly by + // Douglas Gregor. + template<typename _Tp> + _Res& + _M_call(_Tp& __object, _Class *) const + { return __object.*__pm; } + + template<typename _Tp, typename _Up> + _Res& + _M_call(_Tp& __object, _Up * const *) const + { return (*__object).*__pm; } + + template<typename _Tp, typename _Up> + const _Res& + _M_call(_Tp& __object, const _Up * const *) const + { return (*__object).*__pm; } + + template<typename _Tp> + const _Res& + _M_call(_Tp& __object, const _Class *) const + { return __object.*__pm; } + + template<typename _Tp> + const _Res& + _M_call(_Tp& __ptr, const volatile void*) const + { return (*__ptr).*__pm; } + + template<typename _Tp> static _Tp& __get_ref(); + + template<typename _Tp> + static __sfinae_types::__one __check_const(_Tp&, _Class*); + template<typename _Tp, typename _Up> + static __sfinae_types::__one __check_const(_Tp&, _Up * const *); + template<typename _Tp, typename _Up> + static __sfinae_types::__two __check_const(_Tp&, const _Up * const *); + template<typename _Tp> + static __sfinae_types::__two __check_const(_Tp&, const _Class*); + template<typename _Tp> + static __sfinae_types::__two __check_const(_Tp&, const volatile void*); + + public: + template<typename _Tp> + struct _Result_type + : _Mem_fn_const_or_non< + _Res, + (sizeof(__sfinae_types::__two) + == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))> + { }; + + template<typename _Signature> + struct result; + + template<typename _CVMem, typename _Tp> + struct result<_CVMem(_Tp)> + : public _Result_type<_Tp> { }; + + template<typename _CVMem, typename _Tp> + struct result<_CVMem(_Tp&)> + : public _Result_type<_Tp> { }; + + explicit _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { } + + // Handle objects + _Res& operator()(_Class& __object) const + { return __object.*__pm; } + + const _Res& operator()(const _Class& __object) const + { return __object.*__pm; } + + // Handle pointers + _Res& operator()(_Class* __object) const + { return __object->*__pm; } + + const _Res& + operator()(const _Class* __object) const + { return __object->*__pm; } + + // Handle smart pointers and derived + template<typename _Tp> + typename _Result_type<_Tp>::type + operator()(_Tp& __unknown) const + { return _M_call(__unknown, &__unknown); } + + private: + _Res _Class::*__pm; + }; + + /** + * @brief Returns a function object that forwards to the member + * pointer @a pm. + */ + template<typename _Tp, typename _Class> + inline _Mem_fn<_Tp _Class::*> + mem_fn(_Tp _Class::* __pm) + { + return _Mem_fn<_Tp _Class::*>(__pm); + } + + /** + * @brief Determines if the given type _Tp is a function object + * should be treated as a subexpression when evaluating calls to + * function objects returned by bind(). [TR1 3.6.1] + */ + template<typename _Tp> + struct is_bind_expression + { static const bool value = false; }; + + template<typename _Tp> + const bool is_bind_expression<_Tp>::value; + + /** + * @brief Determines if the given type _Tp is a placeholder in a + * bind() expression and, if so, which placeholder it is. [TR1 3.6.2] + */ + template<typename _Tp> + struct is_placeholder + { static const int value = 0; }; + + template<typename _Tp> + const int is_placeholder<_Tp>::value; + + /** + * @if maint + * The type of placeholder objects defined by libstdc++. + * @endif + */ + template<int _Num> struct _Placeholder { }; + + /** + * @if maint + * Partial specialization of is_placeholder that provides the placeholder + * number for the placeholder objects defined by libstdc++. + * @endif + */ + template<int _Num> + struct is_placeholder<_Placeholder<_Num> > + { static const int value = _Num; }; + + template<int _Num> + const int is_placeholder<_Placeholder<_Num> >::value; + + /** + * @if maint + * Maps an argument to bind() into an actual argument to the bound + * function object [TR1 3.6.3/5]. Only the first parameter should + * be specified: the rest are used to determine among the various + * implementations. Note that, although this class is a function + * object, isn't not entirely normal because it takes only two + * parameters regardless of the number of parameters passed to the + * bind expression. The first parameter is the bound argument and + * the second parameter is a tuple containing references to the + * rest of the arguments. + * @endif + */ + template<typename _Arg, + bool _IsBindExp = is_bind_expression<_Arg>::value, + bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)> + class _Mu; + + /** + * @if maint + * If the argument is reference_wrapper<_Tp>, returns the + * underlying reference. [TR1 3.6.3/5 bullet 1] + * @endif + */ + template<typename _Tp> + class _Mu<reference_wrapper<_Tp>, false, false> + { + public: + typedef _Tp& result_type; + + /* Note: This won't actually work for const volatile + * reference_wrappers, because reference_wrapper::get() is const + * but not volatile-qualified. This might be a defect in the TR. + */ + template<typename _CVRef, typename _Tuple> + result_type + operator()(_CVRef& __arg, const _Tuple&) const volatile + { return __arg.get(); } + }; + + /** + * @if maint + * If the argument is a bind expression, we invoke the underlying + * function object with the same cv-qualifiers as we are given and + * pass along all of our arguments (unwrapped). [TR1 3.6.3/5 bullet 2] + * @endif + */ + template<typename _Arg> + class _Mu<_Arg, true, false> + { + public: + template<typename _Signature> class result; + +#define _GLIBCXX_REPEAT_HEADER <tr1/mu_iterate.h> +# include <tr1/repeat.h> +#undef _GLIBCXX_REPEAT_HEADER + }; + + /** + * @if maint + * If the argument is a placeholder for the Nth argument, returns + * a reference to the Nth argument to the bind function object. + * [TR1 3.6.3/5 bullet 3] + * @endif + */ + template<typename _Arg> + class _Mu<_Arg, false, true> + { + public: + template<typename _Signature> class result; + + template<typename _CVMu, typename _CVArg, typename _Tuple> + class result<_CVMu(_CVArg, _Tuple)> + { + // Add a reference, if it hasn't already been done for us. + // This allows us to be a little bit sloppy in constructing + // the tuple that we pass to result_of<...>. + typedef typename tuple_element<(is_placeholder<_Arg>::value - 1), + _Tuple>::type __base_type; + + public: + typedef typename add_reference<__base_type>::type type; + }; + + template<typename _Tuple> + typename result<_Mu(_Arg, _Tuple)>::type + operator()(const volatile _Arg&, const _Tuple& __tuple) const volatile + { + return ::std::tr1::get<(is_placeholder<_Arg>::value - 1)>(__tuple); + } + }; + + /** + * @if maint + * If the argument is just a value, returns a reference to that + * value. The cv-qualifiers on the reference are the same as the + * cv-qualifiers on the _Mu object. [TR1 3.6.3/5 bullet 4] + * @endif + */ + template<typename _Arg> + class _Mu<_Arg, false, false> + { + public: + template<typename _Signature> struct result; + + template<typename _CVMu, typename _CVArg, typename _Tuple> + struct result<_CVMu(_CVArg, _Tuple)> + { + typedef typename add_reference<_CVArg>::type type; + }; + + // Pick up the cv-qualifiers of the argument + template<typename _CVArg, typename _Tuple> + _CVArg& operator()(_CVArg& __arg, const _Tuple&) const volatile + { return __arg; } + }; + + /** + * @if maint + * Maps member pointers into instances of _Mem_fn but leaves all + * other function objects untouched. Used by tr1::bind(). The + * primary template handles the non--member-pointer case. + * @endif + */ + template<typename _Tp> + struct _Maybe_wrap_member_pointer + { + typedef _Tp type; + static const _Tp& __do_wrap(const _Tp& __x) { return __x; } + }; + + /** + * @if maint + * Maps member pointers into instances of _Mem_fn but leaves all + * other function objects untouched. Used by tr1::bind(). This + * partial specialization handles the member pointer case. + * @endif + */ + template<typename _Tp, typename _Class> + struct _Maybe_wrap_member_pointer<_Tp _Class::*> + { + typedef _Mem_fn<_Tp _Class::*> type; + static type __do_wrap(_Tp _Class::* __pm) { return type(__pm); } + }; + + /** + * @if maint + * Type of the function object returned from bind(). + * @endif + */ + template<typename _Signature> + struct _Bind; + + /** + * @if maint + * Type of the function object returned from bind<R>(). + * @endif + */ + template<typename _Result, typename _Signature> + struct _Bind_result; + + /** + * @if maint + * Class template _Bind is always a bind expression. + * @endif + */ + template<typename _Signature> + struct is_bind_expression<_Bind<_Signature> > + { static const bool value = true; }; + + template<typename _Signature> + const bool is_bind_expression<_Bind<_Signature> >::value; + + /** + * @if maint + * Class template _Bind_result is always a bind expression. + * @endif + */ + template<typename _Result, typename _Signature> + struct is_bind_expression<_Bind_result<_Result, _Signature> > + { static const bool value = true; }; + + template<typename _Result, typename _Signature> + const bool is_bind_expression<_Bind_result<_Result, _Signature> >::value; + + /** + * @brief Exception class thrown when class template function's + * operator() is called with an empty target. + * + */ + class bad_function_call : public std::exception { }; + + /** + * @if maint + * The integral constant expression 0 can be converted into a + * pointer to this type. It is used by the function template to + * accept NULL pointers. + * @endif + */ + struct _M_clear_type; + + /** + * @if maint + * Trait identifying "location-invariant" types, meaning that the + * address of the object (or any of its members) will not escape. + * Also implies a trivial copy constructor and assignment operator. + * @endif + */ + template<typename _Tp> + struct __is_location_invariant + : integral_constant<bool, + (is_pointer<_Tp>::value + || is_member_pointer<_Tp>::value)> + { + }; + + class _Undefined_class; + + union _Nocopy_types + { + void* _M_object; + const void* _M_const_object; + void (*_M_function_pointer)(); + void (_Undefined_class::*_M_member_pointer)(); + }; + + union _Any_data { + void* _M_access() { return &_M_pod_data[0]; } + const void* _M_access() const { return &_M_pod_data[0]; } + + template<typename _Tp> _Tp& _M_access() + { return *static_cast<_Tp*>(_M_access()); } + + template<typename _Tp> const _Tp& _M_access() const + { return *static_cast<const _Tp*>(_M_access()); } + + _Nocopy_types _M_unused; + char _M_pod_data[sizeof(_Nocopy_types)]; + }; + + enum _Manager_operation + { + __get_type_info, + __get_functor_ptr, + __clone_functor, + __destroy_functor + }; + + /* Simple type wrapper that helps avoid annoying const problems + when casting between void pointers and pointers-to-pointers. */ + template<typename _Tp> + struct _Simple_type_wrapper + { + _Simple_type_wrapper(_Tp __value) : __value(__value) { } + + _Tp __value; + }; + + template<typename _Tp> + struct __is_location_invariant<_Simple_type_wrapper<_Tp> > + : __is_location_invariant<_Tp> + { + }; + + // Converts a reference to a function object into a callable + // function object. + template<typename _Functor> + inline _Functor& __callable_functor(_Functor& __f) { return __f; } + + template<typename _Member, typename _Class> + inline _Mem_fn<_Member _Class::*> + __callable_functor(_Member _Class::* &__p) + { return mem_fn(__p); } + + template<typename _Member, typename _Class> + inline _Mem_fn<_Member _Class::*> + __callable_functor(_Member _Class::* const &__p) + { return mem_fn(__p); } + + template<typename _Signature, typename _Functor> + class _Function_handler; + + template<typename _Signature> + class function; + + + /** + * @if maint + * Base class of all polymorphic function object wrappers. + * @endif + */ + class _Function_base + { + public: + static const std::size_t _M_max_size = sizeof(_Nocopy_types); + static const std::size_t _M_max_align = __alignof__(_Nocopy_types); + + template<typename _Functor> + class _Base_manager + { + protected: + static const bool __stored_locally = + (__is_location_invariant<_Functor>::value + && sizeof(_Functor) <= _M_max_size + && __alignof__(_Functor) <= _M_max_align + && (_M_max_align % __alignof__(_Functor) == 0)); + typedef integral_constant<bool, __stored_locally> _Local_storage; + + // Retrieve a pointer to the function object + static _Functor* _M_get_pointer(const _Any_data& __source) + { + const _Functor* __ptr = + __stored_locally? &__source._M_access<_Functor>() + /* have stored a pointer */ : __source._M_access<_Functor*>(); + return const_cast<_Functor*>(__ptr); + } + + // Clone a location-invariant function object that fits within + // an _Any_data structure. + static void + _M_clone(_Any_data& __dest, const _Any_data& __source, true_type) + { + new (__dest._M_access()) _Functor(__source._M_access<_Functor>()); + } + + // Clone a function object that is not location-invariant or + // that cannot fit into an _Any_data structure. + static void + _M_clone(_Any_data& __dest, const _Any_data& __source, false_type) + { + __dest._M_access<_Functor*>() = + new _Functor(*__source._M_access<_Functor*>()); + } + + // Destroying a location-invariant object may still require + // destruction. + static void + _M_destroy(_Any_data& __victim, true_type) + { + __victim._M_access<_Functor>().~_Functor(); + } + + // Destroying an object located on the heap. + static void + _M_destroy(_Any_data& __victim, false_type) + { + delete __victim._M_access<_Functor*>(); + } + + public: + static bool + _M_manager(_Any_data& __dest, const _Any_data& __source, + _Manager_operation __op) + { + switch (__op) { + case __get_type_info: + __dest._M_access<const type_info*>() = &typeid(_Functor); + break; + + case __get_functor_ptr: + __dest._M_access<_Functor*>() = _M_get_pointer(__source); + break; + + case __clone_functor: + _M_clone(__dest, __source, _Local_storage()); + break; + + case __destroy_functor: + _M_destroy(__dest, _Local_storage()); + break; + } + return false; + } + + static void + _M_init_functor(_Any_data& __functor, const _Functor& __f) + { + _M_init_functor(__functor, __f, _Local_storage()); + } + + template<typename _Signature> + static bool + _M_not_empty_function(const function<_Signature>& __f) + { + return __f; + } + + template<typename _Tp> + static bool + _M_not_empty_function(const _Tp*& __fp) + { + return __fp; + } + + template<typename _Class, typename _Tp> + static bool + _M_not_empty_function(_Tp _Class::* const& __mp) + { + return __mp; + } + + template<typename _Tp> + static bool + _M_not_empty_function(const _Tp&) + { + return true; + } + + private: + static void + _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type) + { + new (__functor._M_access()) _Functor(__f); + } + + static void + _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type) + { + __functor._M_access<_Functor*>() = new _Functor(__f); + } + }; + + template<typename _Functor> + class _Ref_manager : public _Base_manager<_Functor*> + { + typedef _Function_base::_Base_manager<_Functor*> _Base; + + public: + static bool + _M_manager(_Any_data& __dest, const _Any_data& __source, + _Manager_operation __op) + { + switch (__op) { + case __get_type_info: + __dest._M_access<const type_info*>() = &typeid(_Functor); + break; + + case __get_functor_ptr: + __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source); + return is_const<_Functor>::value; + break; + + default: + _Base::_M_manager(__dest, __source, __op); + } + return false; + } + + static void + _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f) + { + // TBD: Use address_of function instead + _Base::_M_init_functor(__functor, &__f.get()); + } + }; + + _Function_base() : _M_manager(0) { } + + ~_Function_base() + { + if (_M_manager) + { + _M_manager(_M_functor, _M_functor, __destroy_functor); + } + } + + + bool _M_empty() const { return !_M_manager; } + + typedef bool (*_Manager_type)(_Any_data&, const _Any_data&, + _Manager_operation); + + _Any_data _M_functor; + _Manager_type _M_manager; + }; + + // [3.7.2.7] null pointer comparisons + + /** + * @brief Compares a polymorphic function object wrapper against 0 + * (the NULL pointer). + * @returns @c true if the wrapper has no target, @c false otherwise + * + * This function will not throw an exception. + */ + template<typename _Signature> + inline bool + operator==(const function<_Signature>& __f, _M_clear_type*) + { + return !__f; + } + + /** + * @overload + */ + template<typename _Signature> + inline bool + operator==(_M_clear_type*, const function<_Signature>& __f) + { + return !__f; + } + + /** + * @brief Compares a polymorphic function object wrapper against 0 + * (the NULL pointer). + * @returns @c false if the wrapper has no target, @c true otherwise + * + * This function will not throw an exception. + */ + template<typename _Signature> + inline bool + operator!=(const function<_Signature>& __f, _M_clear_type*) + { + return __f; + } + + /** + * @overload + */ + template<typename _Signature> + inline bool + operator!=(_M_clear_type*, const function<_Signature>& __f) + { + return __f; + } + + // [3.7.2.8] specialized algorithms + + /** + * @brief Swap the targets of two polymorphic function object wrappers. + * + * This function will not throw an exception. + */ + template<typename _Signature> + inline void + swap(function<_Signature>& __x, function<_Signature>& __y) + { + __x.swap(__y); + } + +_GLIBCXX_END_NAMESPACE +} + +#define _GLIBCXX_JOIN(X,Y) _GLIBCXX_JOIN2( X , Y ) +#define _GLIBCXX_JOIN2(X,Y) _GLIBCXX_JOIN3(X,Y) +#define _GLIBCXX_JOIN3(X,Y) X##Y +#define _GLIBCXX_REPEAT_HEADER <tr1/functional_iterate.h> +#include <tr1/repeat.h> +#undef _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_JOIN3 +#undef _GLIBCXX_JOIN2 +#undef _GLIBCXX_JOIN + +#include <tr1/functional_hash.h> + +#endif diff --git a/libstdc++/include/tr1/functional_hash.h b/libstdc++/include/tr1/functional_hash.h new file mode 100644 index 0000000..3e592b4 --- /dev/null +++ b/libstdc++/include/tr1/functional_hash.h @@ -0,0 +1,232 @@ +// TR1 functional -*- C++ -*- + +// Copyright (C) 2007 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. + +/** @file tr1/functional_hash.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TR1_FUNCTIONAL_HASH_H +#define _TR1_FUNCTIONAL_HASH_H 1 + +#include <string> +#include <cmath> // for std::frexp + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // Definition of default hash function std::tr1::hash<>. The types for + // which std::tr1::hash<T> is defined is in clause 6.3.3. of the PDTR. + template<typename T> + struct hash; + +#define _TR1_hashtable_define_trivial_hash(_Tp) \ + template<> \ + struct hash<_Tp> \ + : public std::unary_function<_Tp, std::size_t> \ + { \ + std::size_t \ + operator()(_Tp __val) const \ + { return static_cast<std::size_t>(__val); } \ + } + + _TR1_hashtable_define_trivial_hash(bool); + _TR1_hashtable_define_trivial_hash(char); + _TR1_hashtable_define_trivial_hash(signed char); + _TR1_hashtable_define_trivial_hash(unsigned char); + _TR1_hashtable_define_trivial_hash(wchar_t); + _TR1_hashtable_define_trivial_hash(short); + _TR1_hashtable_define_trivial_hash(int); + _TR1_hashtable_define_trivial_hash(long); + _TR1_hashtable_define_trivial_hash(long long); + _TR1_hashtable_define_trivial_hash(unsigned short); + _TR1_hashtable_define_trivial_hash(unsigned int); + _TR1_hashtable_define_trivial_hash(unsigned long); + _TR1_hashtable_define_trivial_hash(unsigned long long); + +#undef _TR1_hashtable_define_trivial_hash + + template<typename _Tp> + struct hash<_Tp*> + : public std::unary_function<_Tp*, std::size_t> + { + std::size_t + operator()(_Tp* __p) const + { return reinterpret_cast<std::size_t>(__p); } + }; + + // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) + // (used by the next specializations of std::tr1::hash<>) + + // Dummy generic implementation (for sizeof(size_t) != 4, 8). + template<std::size_t = sizeof(std::size_t)> + struct _Fnv_hash + { + static std::size_t + hash(const char* __first, std::size_t __length) + { + std::size_t __result = 0; + for (; __length > 0; --__length) + __result = (__result * 131) + *__first++; + return __result; + } + }; + + template<> + struct _Fnv_hash<4> + { + static std::size_t + hash(const char* __first, std::size_t __length) + { + std::size_t __result = static_cast<std::size_t>(2166136261UL); + for (; __length > 0; --__length) + { + __result ^= static_cast<std::size_t>(*__first++); + __result *= static_cast<std::size_t>(16777619UL); + } + return __result; + } + }; + + template<> + struct _Fnv_hash<8> + { + static std::size_t + hash(const char* __first, std::size_t __length) + { + std::size_t __result = + static_cast<std::size_t>(14695981039346656037ULL); + for (; __length > 0; --__length) + { + __result ^= static_cast<std::size_t>(*__first++); + __result *= static_cast<std::size_t>(1099511628211ULL); + } + return __result; + } + }; + + // XXX String and floating point hashes probably shouldn't be inline + // member functions, since are nontrivial. Once we have the framework + // for TR1 .cc files, these should go in one. + template<> + struct hash<std::string> + : public std::unary_function<std::string, std::size_t> + { + std::size_t + operator()(const std::string& __s) const + { return _Fnv_hash<>::hash(__s.data(), __s.length()); } + }; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + struct hash<std::wstring> + : public std::unary_function<std::wstring, std::size_t> + { + std::size_t + operator()(const std::wstring& __s) const + { + return _Fnv_hash<>::hash(reinterpret_cast<const char*>(__s.data()), + __s.length() * sizeof(wchar_t)); + } + }; +#endif + + template<> + struct hash<float> + : public std::unary_function<float, std::size_t> + { + std::size_t + operator()(float __fval) const + { + std::size_t __result = 0; + + // 0 and -0 both hash to zero. + if (__fval != 0.0f) + __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__fval), + sizeof(__fval)); + return __result; + } + }; + + template<> + struct hash<double> + : public std::unary_function<double, std::size_t> + { + std::size_t + operator()(double __dval) const + { + std::size_t __result = 0; + + // 0 and -0 both hash to zero. + if (__dval != 0.0) + __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__dval), + sizeof(__dval)); + return __result; + } + }; + + // For long double, careful with random padding bits (e.g., on x86, + // 10 bytes -> 12 bytes) and resort to frexp. + template<> + struct hash<long double> + : public std::unary_function<long double, std::size_t> + { + std::size_t + operator()(long double __ldval) const + { + std::size_t __result = 0; + + int __exponent; + __ldval = std::frexp(__ldval, &__exponent); + __ldval = __ldval < 0.0l ? -(__ldval + 0.5l) : __ldval; + + const long double __mult = + std::numeric_limits<std::size_t>::max() + 1.0l; + __ldval *= __mult; + + // Try to use all the bits of the mantissa (really necessary only + // on 32-bit targets, at least for 80-bit floating point formats). + const std::size_t __hibits = (std::size_t)__ldval; + __ldval = (__ldval - (long double)__hibits) * __mult; + + const std::size_t __coeff = + (std::numeric_limits<std::size_t>::max() + / std::numeric_limits<long double>::max_exponent); + + __result = __hibits + (std::size_t)__ldval + __coeff * __exponent; + + return __result; + } + }; + +_GLIBCXX_END_NAMESPACE +} + +#endif diff --git a/libstdc++/include/tr1/functional_iterate.h b/libstdc++/include/tr1/functional_iterate.h new file mode 100644 index 0000000..c9c1e83 --- /dev/null +++ b/libstdc++/include/tr1/functional_iterate.h @@ -0,0 +1,922 @@ +// TR1 functional -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// Written by Douglas Gregor <doug.gregor -at- gmail.com> +// +// 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. + +/** @file tr1/functional_iterate.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + struct _Weak_result_type_impl<_Res(_GLIBCXX_TEMPLATE_ARGS)> + { + typedef _Res result_type; + }; + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + struct _Weak_result_type_impl<_Res (&)(_GLIBCXX_TEMPLATE_ARGS)> + { + typedef _Res result_type; + }; + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + struct _Weak_result_type_impl<_Res (*)(_GLIBCXX_TEMPLATE_ARGS)> + { + typedef _Res result_type; + }; + +#if _GLIBCXX_NUM_ARGS > 0 +template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_TEMPLATE_PARAMS_SHIFTED> + struct _Weak_result_type_impl< + _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)> + { + typedef _Res result_type; + }; + +template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_TEMPLATE_PARAMS_SHIFTED> + struct _Weak_result_type_impl< + _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const> + { + typedef _Res result_type; + }; + +template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_TEMPLATE_PARAMS_SHIFTED> + struct _Weak_result_type_impl< + _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile> + { + typedef _Res result_type; + }; + +template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_TEMPLATE_PARAMS_SHIFTED> + struct _Weak_result_type_impl< + _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile> + { + typedef _Res result_type; + }; +#endif + +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + class result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)> + : public _Result_of_impl< + _Has_result_type<_Weak_result_type<_Functor> >::value, + _Functor(_GLIBCXX_TEMPLATE_ARGS)> + { }; + +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + struct _Result_of_impl<true, _Functor(_GLIBCXX_TEMPLATE_ARGS)> + { + typedef typename _Weak_result_type<_Functor>::result_type type; + }; + +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + struct _Result_of_impl<false, _Functor(_GLIBCXX_TEMPLATE_ARGS)> + { +#if _GLIBCXX_NUM_ARGS > 0 + typedef typename _Functor + ::template result<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type type; +#else + typedef void type; +#endif + }; + +/** + * @if maint + * Invoke a function object, which may be either a member pointer or a + * function object. The first parameter will tell which. + * @endif + */ +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + inline + typename __gnu_cxx::__enable_if<(!is_member_pointer<_Functor>::value + && !is_function<_Functor>::value + && !is_function<typename remove_pointer<_Functor>::type>::value), + typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type>::__type + __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS) + { + return __f(_GLIBCXX_ARGS); + } + +#if _GLIBCXX_NUM_ARGS > 0 +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + inline + typename __gnu_cxx::__enable_if<(is_member_pointer<_Functor>::value + && !is_function<_Functor>::value + && !is_function<typename remove_pointer<_Functor>::type>::value), + typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type + >::__type + __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS) + { + return mem_fn(__f)(_GLIBCXX_ARGS); + } +#endif + +// To pick up function references (that will become function pointers) +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + inline + typename __gnu_cxx::__enable_if<(is_pointer<_Functor>::value + && is_function<typename remove_pointer<_Functor>::type>::value), + typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type + >::__type + __invoke(_Functor __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS) + { + return __f(_GLIBCXX_ARGS); + } + +/** + * @if maint + * Implementation of reference_wrapper::operator() + * @endif +*/ +#if _GLIBCXX_NUM_ARGS > 0 +template<typename _Tp> +template<_GLIBCXX_TEMPLATE_PARAMS> + typename result_of< + typename reference_wrapper<_Tp>::_M_func_type(_GLIBCXX_TEMPLATE_ARGS)>::type + reference_wrapper<_Tp>::operator()(_GLIBCXX_REF_PARAMS) const + { + return __invoke(get(), _GLIBCXX_ARGS); + } +#endif + +#if _GLIBCXX_NUM_ARGS > 0 +template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_TEMPLATE_PARAMS_SHIFTED> + class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)> +#if _GLIBCXX_NUM_ARGS == 1 + : public unary_function<_Class*, _Res> +#elif _GLIBCXX_NUM_ARGS == 2 + : public binary_function<_Class*, _T1, _Res> +#endif + { + typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED); + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + public: + typedef _Res result_type; + + explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { } + + // Handle objects + _Res + operator()(_Class& __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + // Handle pointers + _Res + operator()(_Class* __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res + operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { + return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_ARGS_SHIFTED); + } + + private: + _Functor __pmf; + }; + +template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_TEMPLATE_PARAMS_SHIFTED> + class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const> +#if _GLIBCXX_NUM_ARGS == 1 + : public unary_function<const _Class*, _Res> +#elif _GLIBCXX_NUM_ARGS == 2 + : public binary_function<const _Class*, _T1, _Res> +#endif + { + typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const; + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + public: + typedef _Res result_type; + + explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { } + + // Handle objects + _Res + operator()(const _Class& __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + // Handle pointers + _Res + operator()(const _Class* __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res + operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { + return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_ARGS_SHIFTED); + } + + private: + _Functor __pmf; + }; + +template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_TEMPLATE_PARAMS_SHIFTED> + class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile> +#if _GLIBCXX_NUM_ARGS == 1 + : public unary_function<volatile _Class*, _Res> +#elif _GLIBCXX_NUM_ARGS == 2 + : public binary_function<volatile _Class*, _T1, _Res> +#endif + { + typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile; + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + public: + typedef _Res result_type; + + explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { } + + // Handle objects + _Res + operator()(volatile _Class& __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + // Handle pointers + _Res + operator()(volatile _Class* __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res + operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { + return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_ARGS_SHIFTED); + } + private: + _Functor __pmf; + }; + +template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_TEMPLATE_PARAMS_SHIFTED> + class _Mem_fn<_Res(_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile> +#if _GLIBCXX_NUM_ARGS == 1 + : public unary_function<const volatile _Class*, _Res> +#elif _GLIBCXX_NUM_ARGS == 2 + : public binary_function<const volatile _Class*, _T1, _Res> +#endif + { + typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) + const volatile; + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + public: + typedef _Res result_type; + + explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { } + + // Handle objects + _Res + operator()(const volatile _Class& __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + // Handle pointers + _Res + operator()(const volatile _Class* __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res + operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_PARAMS_SHIFTED) const + { + return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED + _GLIBCXX_ARGS_SHIFTED); + } + + private: + _Functor __pmf; + }; +#endif + +#if _GLIBCXX_NUM_ARGS > 0 +namespace placeholders +{ +namespace +{ + _Placeholder<_GLIBCXX_NUM_ARGS> _GLIBCXX_JOIN(_,_GLIBCXX_NUM_ARGS); +} // anonymous namespace +} +#endif + +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +class _Bind<_Functor(_GLIBCXX_TEMPLATE_ARGS)> + : public _Weak_result_type<_Functor> +{ + typedef _Bind __self_type; + + _Functor _M_f; + _GLIBCXX_BIND_MEMBERS + + public: +#if _GLIBCXX_NUM_ARGS == 0 + explicit +#endif + _Bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS) + : _M_f(__f) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT { } + +#define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h> +#include <tr1/bind_repeat.h> +#undef _GLIBCXX_BIND_REPEAT_HEADER +}; + +template<typename _Result, typename _Functor + _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +class _Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)> +{ + _Functor _M_f; + _GLIBCXX_BIND_MEMBERS + + public: + typedef _Result result_type; + +#if _GLIBCXX_NUM_ARGS == 0 + explicit +#endif + _Bind_result(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS) + : _M_f(__f) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT { } + +#define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h> +#define _GLIBCXX_BIND_HAS_RESULT_TYPE +#include <tr1/bind_repeat.h> +#undef _GLIBCXX_BIND_HAS_RESULT_TYPE +#undef _GLIBCXX_BIND_REPEAT_HEADER +}; + +// Handle arbitrary function objects +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +inline +_Bind<typename _Maybe_wrap_member_pointer<_Functor>::type + (_GLIBCXX_TEMPLATE_ARGS)> +bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS) +{ + typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type; + typedef typename __maybe_type::type __functor_type; + typedef _Bind<__functor_type(_GLIBCXX_TEMPLATE_ARGS)> __result_type; + return __result_type(__maybe_type::__do_wrap(__f) + _GLIBCXX_COMMA _GLIBCXX_ARGS); +} + +template<typename _Result, typename _Functor + _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +inline +_Bind_result<_Result, + typename _Maybe_wrap_member_pointer<_Functor>::type + (_GLIBCXX_TEMPLATE_ARGS)> +bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS) +{ + typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type; + typedef typename __maybe_type::type __functor_type; + typedef _Bind_result<_Result, __functor_type(_GLIBCXX_TEMPLATE_ARGS)> + __result_type; + return __result_type(__maybe_type::__do_wrap(__f) + _GLIBCXX_COMMA _GLIBCXX_ARGS); +} + +template<typename _Res, typename _Functor _GLIBCXX_COMMA + _GLIBCXX_TEMPLATE_PARAMS> +class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Functor> + : public _Function_base::_Base_manager<_Functor> +{ + typedef _Function_base::_Base_manager<_Functor> _Base; + + public: + static _Res + _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS) + { + return (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS); + } +}; + +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Functor> + : public _Function_base::_Base_manager<_Functor> +{ + typedef _Function_base::_Base_manager<_Functor> _Base; + + public: + static void + _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS) + { + (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS); + } +}; + +template<typename _Res, typename _Functor _GLIBCXX_COMMA + _GLIBCXX_TEMPLATE_PARAMS> +class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), + reference_wrapper<_Functor> > + : public _Function_base::_Ref_manager<_Functor> +{ + typedef _Function_base::_Ref_manager<_Functor> _Base; + + public: + static _Res + _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS) + { + return __callable_functor(**_Base::_M_get_pointer(__functor)) + (_GLIBCXX_ARGS); + } +}; + +template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), + reference_wrapper<_Functor> > + : public _Function_base::_Ref_manager<_Functor> +{ + typedef _Function_base::_Ref_manager<_Functor> _Base; + + public: + static void + _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS) + { + __callable_functor(**_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS); + } +}; + +template<typename _Class, typename _Member, typename _Res + _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*> + : public _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*> +{ + typedef _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*> + _Base; + + public: + static _Res + _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS) + { + return std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value) + (_GLIBCXX_ARGS); + } +}; + +template<typename _Class, typename _Member + _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*> + : public _Function_base::_Base_manager< + _Simple_type_wrapper< _Member _Class::* > > +{ + typedef _Member _Class::* _Functor; + typedef _Simple_type_wrapper< _Functor > _Wrapper; + typedef _Function_base::_Base_manager<_Wrapper> _Base; + + public: + static bool + _M_manager(_Any_data& __dest, const _Any_data& __source, + _Manager_operation __op) + { + switch (__op) { + case __get_type_info: + __dest._M_access<const type_info*>() = &typeid(_Functor); + break; + + case __get_functor_ptr: + __dest._M_access<_Functor*>() = + &_Base::_M_get_pointer(__source)->__value; + break; + + default: + _Base::_M_manager(__dest, __source, __op); + } + return false; + } + + static void + _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS) + { + std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value) + (_GLIBCXX_ARGS); + } +}; + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +class function<_Res(_GLIBCXX_TEMPLATE_ARGS)> +#if _GLIBCXX_NUM_ARGS == 1 + : public unary_function<_T1, _Res>, private _Function_base +#elif _GLIBCXX_NUM_ARGS == 2 + : public binary_function<_T1, _T2, _Res>, private _Function_base +#else + : private _Function_base +#endif +{ + /** + * @if maint + * This class is used to implement the safe_bool idiom. + * @endif + */ + struct _Hidden_type + { + _Hidden_type* _M_bool; + }; + + /** + * @if maint + * This typedef is used to implement the safe_bool idiom. + * @endif + */ + typedef _Hidden_type* _Hidden_type::* _Safe_bool; + + typedef _Res _Signature_type(_GLIBCXX_TEMPLATE_ARGS); + + struct _Useless {}; + + public: + typedef _Res result_type; + + // [3.7.2.1] construct/copy/destroy + + /** + * @brief Default construct creates an empty function call wrapper. + * @post @c !(bool)*this + */ + function() : _Function_base() { } + + /** + * @brief Default construct creates an empty function call wrapper. + * @post @c !(bool)*this + */ + function(_M_clear_type*) : _Function_base() { } + + /** + * @brief %Function copy constructor. + * @param x A %function object with identical call signature. + * @pre @c (bool)*this == (bool)x + * + * The newly-created %function contains a copy of the target of @a + * x (if it has one). + */ + function(const function& __x); + + /** + * @brief Builds a %function that targets a copy of the incoming + * function object. + * @param f A %function object that is callable with parameters of + * type @c T1, @c T2, ..., @c TN and returns a value convertible + * to @c Res. + * + * The newly-created %function object will target a copy of @a + * f. If @a f is @c reference_wrapper<F>, then this function + * object will contain a reference to the function object @c + * f.get(). If @a f is a NULL function pointer or NULL + * pointer-to-member, the newly-created object will be empty. + * + * If @a f is a non-NULL function pointer or an object of type @c + * reference_wrapper<F>, this function will not throw. + */ + template<typename _Functor> + function(_Functor __f, + typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, _Useless>::__type = _Useless()); + + /** + * @brief %Function assignment operator. + * @param x A %function with identical call signature. + * @post @c (bool)*this == (bool)x + * @returns @c *this + * + * The target of @a x is copied to @c *this. If @a x has no + * target, then @c *this will be empty. + * + * If @a x targets a function pointer or a reference to a function + * object, then this operation will not throw an exception. + */ + function& operator=(const function& __x) + { + function(__x).swap(*this); + return *this; + } + + /** + * @brief %Function assignment to zero. + * @post @c !(bool)*this + * @returns @c *this + * + * The target of @a *this is deallocated, leaving it empty. + */ + function& operator=(_M_clear_type*) + { + if (_M_manager) { + _M_manager(_M_functor, _M_functor, __destroy_functor); + _M_manager = 0; + _M_invoker = 0; + } + return *this; + } + + /** + * @brief %Function assignment to a new target. + * @param f A %function object that is callable with parameters of + * type @c T1, @c T2, ..., @c TN and returns a value convertible + * to @c Res. + * @return @c *this + * + * This %function object wrapper will target a copy of @a + * f. If @a f is @c reference_wrapper<F>, then this function + * object will contain a reference to the function object @c + * f.get(). If @a f is a NULL function pointer or NULL + * pointer-to-member, @c this object will be empty. + * + * If @a f is a non-NULL function pointer or an object of type @c + * reference_wrapper<F>, this function will not throw. + */ + template<typename _Functor> + typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, function&>::__type + operator=(_Functor __f) + { + function(__f).swap(*this); + return *this; + } + + // [3.7.2.2] function modifiers + + /** + * @brief Swap the targets of two %function objects. + * @param f A %function with identical call signature. + * + * Swap the targets of @c this function object and @a f. This + * function will not throw an exception. + */ + void swap(function& __x) + { + _Any_data __old_functor = _M_functor; + _M_functor = __x._M_functor; + __x._M_functor = __old_functor; + _Manager_type __old_manager = _M_manager; + _M_manager = __x._M_manager; + __x._M_manager = __old_manager; + _Invoker_type __old_invoker = _M_invoker; + _M_invoker = __x._M_invoker; + __x._M_invoker = __old_invoker; + } + + // [3.7.2.3] function capacity + + /** + * @brief Determine if the %function wrapper has a target. + * + * @return @c true when this %function object contains a target, + * or @c false when it is empty. + * + * This function will not throw an exception. + */ + operator _Safe_bool() const + { + if (_M_empty()) + { + return 0; + } + else + { + return &_Hidden_type::_M_bool; + } + } + + // [3.7.2.4] function invocation + + /** + * @brief Invokes the function targeted by @c *this. + * @returns the result of the target. + * @throws bad_function_call when @c !(bool)*this + * + * The function call operator invokes the target function object + * stored by @c this. + */ + _Res operator()(_GLIBCXX_PARAMS) const; + + // [3.7.2.5] function target access + /** + * @brief Determine the type of the target of this function object + * wrapper. + * + * @returns the type identifier of the target function object, or + * @c typeid(void) if @c !(bool)*this. + * + * This function will not throw an exception. + */ + const type_info& target_type() const; + + /** + * @brief Access the stored target function object. + * + * @return Returns a pointer to the stored target function object, + * if @c typeid(Functor).equals(target_type()); otherwise, a NULL + * pointer. + * + * This function will not throw an exception. + */ + template<typename _Functor> _Functor* target(); + + /** + * @overload + */ + template<typename _Functor> const _Functor* target() const; + + private: + // [3.7.2.6] undefined operators + template<typename _Function> + void operator==(const function<_Function>&) const; + template<typename _Function> + void operator!=(const function<_Function>&) const; + + typedef _Res (*_Invoker_type)(const _Any_data& _GLIBCXX_COMMA + _GLIBCXX_PARAMS); + _Invoker_type _M_invoker; +}; + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::function(const function& __x) + : _Function_base() + { + if (__x) { + _M_invoker = __x._M_invoker; + _M_manager = __x._M_manager; + __x._M_manager(_M_functor, __x._M_functor, __clone_functor); + } + } + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +template<typename _Functor> + function<_Res(_GLIBCXX_TEMPLATE_ARGS)> + ::function(_Functor __f, + typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, _Useless>::__type) + : _Function_base() +{ + typedef _Function_handler<_Signature_type, _Functor> _My_handler; + if (_My_handler::_M_not_empty_function(__f)) { + _M_invoker = &_My_handler::_M_invoke; + _M_manager = &_My_handler::_M_manager; + _My_handler::_M_init_functor(_M_functor, __f); + } +} + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + _Res + function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const + { + if (_M_empty()) + { +#if __EXCEPTIONS + throw bad_function_call(); +#else + std::abort(); +#endif + } + return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS); + } + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> + const type_info& + function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target_type() const + { + if (_M_manager) + { + _Any_data __typeinfo_result; + _M_manager(__typeinfo_result, _M_functor, __get_type_info); + return *__typeinfo_result._M_access<const type_info*>(); + } + else + { + return typeid(void); + } + } + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +template<typename _Functor> + _Functor* + function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() + { + if (typeid(_Functor) == target_type() && _M_manager) + { + _Any_data __ptr; + if (_M_manager(__ptr, _M_functor, __get_functor_ptr) + && !is_const<_Functor>::value) + return 0; + else + return __ptr._M_access<_Functor*>(); + } + else + { + return 0; + } + } + +template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +template<typename _Functor> + const _Functor* + function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() const + { + if (typeid(_Functor) == target_type() && _M_manager) + { + _Any_data __ptr; + _M_manager(__ptr, _M_functor, __get_functor_ptr); + return __ptr._M_access<const _Functor*>(); + } + else + { + return 0; + } + } + +_GLIBCXX_END_NAMESPACE +} diff --git a/libstdc++/include/tr1/hashtable b/libstdc++/include/tr1/hashtable new file mode 100644 index 0000000..0d760ee --- /dev/null +++ b/libstdc++/include/tr1/hashtable @@ -0,0 +1,1182 @@ +// Internal header for TR1 unordered_set and unordered_map -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/hashtable + * This is a TR1 C++ Library header. + */ + +// This header file defines std::tr1::hashtable, which is used to +// implement std::tr1::unordered_set, std::tr1::unordered_map, +// std::tr1::unordered_multiset, and std::tr1::unordered_multimap. +// hashtable has many template parameters, partly to accommodate +// the differences between those four classes and partly to +// accommodate policy choices that go beyond what TR1 calls for. + +// Class template hashtable attempts to encapsulate all reasonable +// variation among hash tables that use chaining. It does not handle +// open addressing. + +// References: +// M. Austern, "A Proposal to Add Hash Tables to the Standard +// Library (revision 4)," WG21 Document N1456=03-0039, 2003. +// D. E. Knuth, The Art of Computer Programming, v. 3, Sorting and Searching. +// A. Tavori and V. Dreizin, "Policy-Based Data Structures", 2004. +// http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/index.html + +#ifndef _TR1_HASHTABLE +#define _TR1_HASHTABLE 1 + +#include <utility> // For std::pair +#include <memory> +#include <iterator> +#include <cstddef> +#include <cstdlib> +#include <cmath> +#include <bits/functexcept.h> +#include <tr1/type_traits> // For true_type and false_type +#include <tr1/hashtable_policy.h> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // Class template _Hashtable, class definition. + + // Meaning of class template _Hashtable's template parameters + + // _Key and _Value: arbitrary CopyConstructible types. + + // _Allocator: an allocator type ([lib.allocator.requirements]) whose + // value type is Value. As a conforming extension, we allow for + // value type != Value. + + // _ExtractKey: function object that takes a object of type Value + // and returns a value of type _Key. + + // _Equal: function object that takes two objects of type k and returns + // a bool-like value that is true if the two objects are considered equal. + + // _H1: the hash function. A unary function object with argument type + // Key and result type size_t. Return values should be distributed + // over the entire range [0, numeric_limits<size_t>:::max()]. + + // _H2: the range-hashing function (in the terminology of Tavori and + // Dreizin). A binary function object whose argument types and result + // type are all size_t. Given arguments r and N, the return value is + // in the range [0, N). + + // _Hash: the ranged hash function (Tavori and Dreizin). A binary function + // whose argument types are _Key and size_t and whose result type is + // size_t. Given arguments k and N, the return value is in the range + // [0, N). Default: hash(k, N) = h2(h1(k), N). If _Hash is anything other + // than the default, _H1 and _H2 are ignored. + + // _RehashPolicy: Policy class with three members, all of which govern + // the bucket count. _M_next_bkt(n) returns a bucket count no smaller + // than n. _M_bkt_for_elements(n) returns a bucket count appropriate + // for an element count of n. _M_need_rehash(n_bkt, n_elt, n_ins) + // determines whether, if the current bucket count is n_bkt and the + // current element count is n_elt, we need to increase the bucket + // count. If so, returns make_pair(true, n), where n is the new + // bucket count. If not, returns make_pair(false, <anything>). + + // ??? Right now it is hard-wired that the number of buckets never + // shrinks. Should we allow _RehashPolicy to change that? + + // __cache_hash_code: bool. true if we store the value of the hash + // function along with the value. This is a time-space tradeoff. + // Storing it may improve lookup speed by reducing the number of times + // we need to call the Equal function. + + // __constant_iterators: bool. true if iterator and const_iterator are + // both constant iterator types. This is true for unordered_set and + // unordered_multiset, false for unordered_map and unordered_multimap. + + // __unique_keys: bool. true if the return value of _Hashtable::count(k) + // is always at most one, false if it may be an arbitrary number. This + // true for unordered_set and unordered_map, false for unordered_multiset + // and unordered_multimap. + + template<typename _Key, typename _Value, typename _Allocator, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, + typename _RehashPolicy, + bool __cache_hash_code, + bool __constant_iterators, + bool __unique_keys> + class _Hashtable + : public __detail::_Rehash_base<_RehashPolicy, + _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, + __cache_hash_code, + __constant_iterators, + __unique_keys> >, + public __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __cache_hash_code>, + public __detail::_Map_base<_Key, _Value, _ExtractKey, __unique_keys, + _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, + __cache_hash_code, + __constant_iterators, + __unique_keys> > + { + public: + typedef _Allocator allocator_type; + typedef _Value value_type; + typedef _Key key_type; + typedef _Equal key_equal; + // mapped_type, if present, comes from _Map_base. + // hasher, if present, comes from _Hash_code_base. + typedef typename _Allocator::difference_type difference_type; + typedef typename _Allocator::size_type size_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __detail::_Node_iterator<value_type, __constant_iterators, + __cache_hash_code> + local_iterator; + typedef __detail::_Node_const_iterator<value_type, + __constant_iterators, + __cache_hash_code> + const_local_iterator; + + typedef __detail::_Hashtable_iterator<value_type, __constant_iterators, + __cache_hash_code> + iterator; + typedef __detail::_Hashtable_const_iterator<value_type, + __constant_iterators, + __cache_hash_code> + const_iterator; + + template<typename _Key2, typename _Pair, typename _Hashtable> + friend struct __detail::_Map_base; + + private: + typedef __detail::_Hash_node<_Value, __cache_hash_code> _Node; + typedef typename _Allocator::template rebind<_Node>::other + _Node_allocator_type; + typedef typename _Allocator::template rebind<_Node*>::other + _Bucket_allocator_type; + + typedef typename _Allocator::template rebind<_Value>::other + _Value_allocator_type; + + _Node_allocator_type _M_node_allocator; + _Node** _M_buckets; + size_type _M_bucket_count; + size_type _M_element_count; + _RehashPolicy _M_rehash_policy; + + _Node* + _M_allocate_node(const value_type& __v); + + void + _M_deallocate_node(_Node* __n); + + void + _M_deallocate_nodes(_Node**, size_type); + + _Node** + _M_allocate_buckets(size_type __n); + + void + _M_deallocate_buckets(_Node**, size_type __n); + + public: + // Constructor, destructor, assignment, swap + _Hashtable(size_type __bucket_hint, + const _H1&, const _H2&, const _Hash&, + const _Equal&, const _ExtractKey&, + const allocator_type&); + + template<typename _InputIterator> + _Hashtable(_InputIterator __first, _InputIterator __last, + size_type __bucket_hint, + const _H1&, const _H2&, const _Hash&, + const _Equal&, const _ExtractKey&, + const allocator_type&); + + _Hashtable(const _Hashtable&); + + _Hashtable& + operator=(const _Hashtable&); + + ~_Hashtable(); + + void swap(_Hashtable&); + + // Basic container operations + iterator + begin() + { + iterator __i(_M_buckets); + if (!__i._M_cur_node) + __i._M_incr_bucket(); + return __i; + } + + const_iterator + begin() const + { + const_iterator __i(_M_buckets); + if (!__i._M_cur_node) + __i._M_incr_bucket(); + return __i; + } + + iterator + end() + { return iterator(_M_buckets + _M_bucket_count); } + + const_iterator + end() const + { return const_iterator(_M_buckets + _M_bucket_count); } + + size_type + size() const + { return _M_element_count; } + + bool + empty() const + { return size() == 0; } + + allocator_type + get_allocator() const + { return allocator_type(_M_node_allocator); } + + _Value_allocator_type + _M_get_Value_allocator() const + { return _Value_allocator_type(_M_node_allocator); } + + size_type + max_size() const + { return _M_get_Value_allocator().max_size(); } + + // Observers + key_equal + key_eq() const + { return this->_M_eq; } + + // hash_function, if present, comes from _Hash_code_base. + + // Bucket operations + size_type + bucket_count() const + { return _M_bucket_count; } + + size_type + max_bucket_count() const + { return max_size(); } + + size_type + bucket_size(size_type __n) const + { return std::distance(begin(__n), end(__n)); } + + size_type + bucket(const key_type& __k) const + { + return this->_M_bucket_index(__k, this->_M_hash_code(__k), + bucket_count()); + } + + local_iterator + begin(size_type __n) + { return local_iterator(_M_buckets[__n]); } + + local_iterator + end(size_type) + { return local_iterator(0); } + + const_local_iterator + begin(size_type __n) const + { return const_local_iterator(_M_buckets[__n]); } + + const_local_iterator + end(size_type) const + { return const_local_iterator(0); } + + float + load_factor() const + { + return static_cast<float>(size()) / static_cast<float>(bucket_count()); + } + + // max_load_factor, if present, comes from _Rehash_base. + + // Generalization of max_load_factor. Extension, not found in TR1. Only + // useful if _RehashPolicy is something other than the default. + const _RehashPolicy& + __rehash_policy() const + { return _M_rehash_policy; } + + void + __rehash_policy(const _RehashPolicy&); + + // Lookup. + iterator + find(const key_type& __k); + + const_iterator + find(const key_type& __k) const; + + size_type + count(const key_type& __k) const; + + std::pair<iterator, iterator> + equal_range(const key_type& __k); + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __k) const; + + private: // Find, insert and erase helper functions + // ??? This dispatching is a workaround for the fact that we don't + // have partial specialization of member templates; it would be + // better to just specialize insert on __unique_keys. There may be a + // cleaner workaround. + typedef typename __gnu_cxx::__conditional_type<__unique_keys, + std::pair<iterator, bool>, iterator>::__type + _Insert_Return_Type; + + typedef typename __gnu_cxx::__conditional_type<__unique_keys, + std::_Select1st<_Insert_Return_Type>, + std::_Identity<_Insert_Return_Type> + >::__type + _Insert_Conv_Type; + + _Node* + _M_find_node(_Node*, const key_type&, + typename _Hashtable::_Hash_code_type) const; + + iterator + _M_insert_bucket(const value_type&, size_type, + typename _Hashtable::_Hash_code_type); + + std::pair<iterator, bool> + _M_insert(const value_type&, std::tr1::true_type); + + iterator + _M_insert(const value_type&, std::tr1::false_type); + + void + _M_erase_node(_Node*, _Node**); + + public: + // Insert and erase + _Insert_Return_Type + insert(const value_type& __v) + { return _M_insert(__v, std::tr1::integral_constant<bool, + __unique_keys>()); } + + iterator + insert(iterator, const value_type& __v) + { return iterator(_Insert_Conv_Type()(this->insert(__v))); } + + const_iterator + insert(const_iterator, const value_type& __v) + { return const_iterator(_Insert_Conv_Type()(this->insert(__v))); } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last); + + iterator + erase(iterator); + + const_iterator + erase(const_iterator); + + size_type + erase(const key_type&); + + iterator + erase(iterator, iterator); + + const_iterator + erase(const_iterator, const_iterator); + + void + clear(); + + // Set number of buckets to be appropriate for container of n element. + void rehash(size_type __n); + + private: + // Unconditionally change size of bucket array to n. + void _M_rehash(size_type __n); + }; + + + // Definitions of class template _Hashtable's out-of-line member functions. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::_Node* + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_allocate_node(const value_type& __v) + { + _Node* __n = _M_node_allocator.allocate(1); + try + { + _M_get_Value_allocator().construct(&__n->_M_v, __v); + __n->_M_next = 0; + return __n; + } + catch(...) + { + _M_node_allocator.deallocate(__n, 1); + __throw_exception_again; + } + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_deallocate_node(_Node* __n) + { + _M_get_Value_allocator().destroy(&__n->_M_v); + _M_node_allocator.deallocate(__n, 1); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_deallocate_nodes(_Node** __array, size_type __n) + { + for (size_type __i = 0; __i < __n; ++__i) + { + _Node* __p = __array[__i]; + while (__p) + { + _Node* __tmp = __p; + __p = __p->_M_next; + _M_deallocate_node(__tmp); + } + __array[__i] = 0; + } + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::_Node** + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_allocate_buckets(size_type __n) + { + _Bucket_allocator_type __alloc(_M_node_allocator); + + // We allocate one extra bucket to hold a sentinel, an arbitrary + // non-null pointer. Iterator increment relies on this. + _Node** __p = __alloc.allocate(__n + 1); + std::fill(__p, __p + __n, (_Node*) 0); + __p[__n] = reinterpret_cast<_Node*>(0x1000); + return __p; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_deallocate_buckets(_Node** __p, size_type __n) + { + _Bucket_allocator_type __alloc(_M_node_allocator); + __alloc.deallocate(__p, __n + 1); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _Hashtable(size_type __bucket_hint, + const _H1& __h1, const _H2& __h2, const _Hash& __h, + const _Equal& __eq, const _ExtractKey& __exk, + const allocator_type& __a) + : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(), + __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __chc>(__exk, __eq, + __h1, __h2, __h), + __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(), + _M_node_allocator(__a), + _M_bucket_count(0), + _M_element_count(0), + _M_rehash_policy() + { + _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint); + _M_buckets = _M_allocate_buckets(_M_bucket_count); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + template<typename _InputIterator> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _Hashtable(_InputIterator __f, _InputIterator __l, + size_type __bucket_hint, + const _H1& __h1, const _H2& __h2, const _Hash& __h, + const _Equal& __eq, const _ExtractKey& __exk, + const allocator_type& __a) + : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(), + __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __chc>(__exk, __eq, + __h1, __h2, __h), + __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(), + _M_node_allocator(__a), + _M_bucket_count(0), + _M_element_count(0), + _M_rehash_policy() + { + _M_bucket_count = std::max(_M_rehash_policy._M_next_bkt(__bucket_hint), + _M_rehash_policy. + _M_bkt_for_elements(__detail:: + __distance_fw(__f, + __l))); + _M_buckets = _M_allocate_buckets(_M_bucket_count); + try + { + for (; __f != __l; ++__f) + this->insert(*__f); + } + catch(...) + { + clear(); + _M_deallocate_buckets(_M_buckets, _M_bucket_count); + __throw_exception_again; + } + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _Hashtable(const _Hashtable& __ht) + : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht), + __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __chc>(__ht), + __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht), + _M_node_allocator(__ht._M_node_allocator), + _M_bucket_count(__ht._M_bucket_count), + _M_element_count(__ht._M_element_count), + _M_rehash_policy(__ht._M_rehash_policy) + { + _M_buckets = _M_allocate_buckets(_M_bucket_count); + try + { + for (size_type __i = 0; __i < __ht._M_bucket_count; ++__i) + { + _Node* __n = __ht._M_buckets[__i]; + _Node** __tail = _M_buckets + __i; + while (__n) + { + *__tail = _M_allocate_node(__n->_M_v); + this->_M_copy_code(*__tail, __n); + __tail = &((*__tail)->_M_next); + __n = __n->_M_next; + } + } + } + catch(...) + { + clear(); + _M_deallocate_buckets(_M_buckets, _M_bucket_count); + __throw_exception_again; + } + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>& + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + operator=(const _Hashtable& __ht) + { + _Hashtable __tmp(__ht); + this->swap(__tmp); + return *this; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + ~_Hashtable() + { + clear(); + _M_deallocate_buckets(_M_buckets, _M_bucket_count); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + swap(_Hashtable& __x) + { + // The only base class with member variables is hash_code_base. We + // define _Hash_code_base::_M_swap because different specializations + // have different members. + __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __chc>::_M_swap(__x); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<_Node_allocator_type>::_S_do_it(_M_node_allocator, + __x._M_node_allocator); + + std::swap(_M_rehash_policy, __x._M_rehash_policy); + std::swap(_M_buckets, __x._M_buckets); + std::swap(_M_bucket_count, __x._M_bucket_count); + std::swap(_M_element_count, __x._M_element_count); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + __rehash_policy(const _RehashPolicy& __pol) + { + _M_rehash_policy = __pol; + size_type __n_bkt = __pol._M_bkt_for_elements(_M_element_count); + if (__n_bkt > _M_bucket_count) + _M_rehash(__n_bkt); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + find(const key_type& __k) + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + _Node* __p = _M_find_node(_M_buckets[__n], __k, __code); + return __p ? iterator(__p, _M_buckets + __n) : this->end(); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + find(const key_type& __k) const + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + _Node* __p = _M_find_node(_M_buckets[__n], __k, __code); + return __p ? const_iterator(__p, _M_buckets + __n) : this->end(); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::size_type + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + count(const key_type& __k) const + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + std::size_t __result = 0; + for (_Node* __p = _M_buckets[__n]; __p; __p = __p->_M_next) + if (this->_M_compare(__k, __code, __p)) + ++__result; + return __result; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + std::pair<typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator, + typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + equal_range(const key_type& __k) + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + _Node** __head = _M_buckets + __n; + _Node* __p = _M_find_node(*__head, __k, __code); + + if (__p) + { + _Node* __p1 = __p->_M_next; + for (; __p1; __p1 = __p1->_M_next) + if (!this->_M_compare(__k, __code, __p1)) + break; + + iterator __first(__p, __head); + iterator __last(__p1, __head); + if (!__p1) + __last._M_incr_bucket(); + return std::make_pair(__first, __last); + } + else + return std::make_pair(this->end(), this->end()); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + std::pair<typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator, + typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + equal_range(const key_type& __k) const + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + _Node** __head = _M_buckets + __n; + _Node* __p = _M_find_node(*__head, __k, __code); + + if (__p) + { + _Node* __p1 = __p->_M_next; + for (; __p1; __p1 = __p1->_M_next) + if (!this->_M_compare(__k, __code, __p1)) + break; + + const_iterator __first(__p, __head); + const_iterator __last(__p1, __head); + if (!__p1) + __last._M_incr_bucket(); + return std::make_pair(__first, __last); + } + else + return std::make_pair(this->end(), this->end()); + } + + // Find the node whose key compares equal to k, beginning the search + // at p (usually the head of a bucket). Return nil if no node is found. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, + _Equal, _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::_Node* + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_find_node(_Node* __p, const key_type& __k, + typename _Hashtable::_Hash_code_type __code) const + { + for (; __p; __p = __p->_M_next) + if (this->_M_compare(__k, __code, __p)) + return __p; + return false; + } + + // Insert v in bucket n (assumes no element with its key already present). + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_insert_bucket(const value_type& __v, size_type __n, + typename _Hashtable::_Hash_code_type __code) + { + std::pair<bool, std::size_t> __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, + _M_element_count, 1); + + // Allocate the new node before doing the rehash so that we don't + // do a rehash if the allocation throws. + _Node* __new_node = _M_allocate_node(__v); + + try + { + if (__do_rehash.first) + { + const key_type& __k = this->_M_extract(__v); + __n = this->_M_bucket_index(__k, __code, __do_rehash.second); + _M_rehash(__do_rehash.second); + } + + __new_node->_M_next = _M_buckets[__n]; + this->_M_store_code(__new_node, __code); + _M_buckets[__n] = __new_node; + ++_M_element_count; + return iterator(__new_node, _M_buckets + __n); + } + catch(...) + { + _M_deallocate_node(__new_node); + __throw_exception_again; + } + } + + // Insert v if no element with its key is already present. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + std::pair<typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator, bool> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_insert(const value_type& __v, std::tr1::true_type) + { + const key_type& __k = this->_M_extract(__v); + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + + if (_Node* __p = _M_find_node(_M_buckets[__n], __k, __code)) + return std::make_pair(iterator(__p, _M_buckets + __n), false); + return std::make_pair(_M_insert_bucket(__v, __n, __code), true); + } + + // Insert v unconditionally. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_insert(const value_type& __v, std::tr1::false_type) + { + std::pair<bool, std::size_t> __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, + _M_element_count, 1); + if (__do_rehash.first) + _M_rehash(__do_rehash.second); + + const key_type& __k = this->_M_extract(__v); + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + + // First find the node, avoid leaking new_node if compare throws. + _Node* __prev = _M_find_node(_M_buckets[__n], __k, __code); + _Node* __new_node = _M_allocate_node(__v); + + if (__prev) + { + __new_node->_M_next = __prev->_M_next; + __prev->_M_next = __new_node; + } + else + { + __new_node->_M_next = _M_buckets[__n]; + _M_buckets[__n] = __new_node; + } + this->_M_store_code(__new_node, __code); + + ++_M_element_count; + return iterator(__new_node, _M_buckets + __n); + } + + // For erase(iterator) and erase(const_iterator). + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_erase_node(_Node* __p, _Node** __b) + { + _Node* __cur = *__b; + if (__cur == __p) + *__b = __cur->_M_next; + else + { + _Node* __next = __cur->_M_next; + while (__next != __p) + { + __cur = __next; + __next = __cur->_M_next; + } + __cur->_M_next = __next->_M_next; + } + + _M_deallocate_node(__p); + --_M_element_count; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + template<typename _InputIterator> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + insert(_InputIterator __first, _InputIterator __last) + { + size_type __n_elt = __detail::__distance_fw(__first, __last); + std::pair<bool, std::size_t> __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, + _M_element_count, __n_elt); + if (__do_rehash.first) + _M_rehash(__do_rehash.second); + + for (; __first != __last; ++__first) + this->insert(*__first); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(iterator __it) + { + iterator __result = __it; + ++__result; + _M_erase_node(__it._M_cur_node, __it._M_cur_bucket); + return __result; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(const_iterator __it) + { + const_iterator __result = __it; + ++__result; + _M_erase_node(__it._M_cur_node, __it._M_cur_bucket); + return __result; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::size_type + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(const key_type& __k) + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + size_type __result = 0; + + _Node** __slot = _M_buckets + __n; + while (*__slot && !this->_M_compare(__k, __code, *__slot)) + __slot = &((*__slot)->_M_next); + + while (*__slot && this->_M_compare(__k, __code, *__slot)) + { + _Node* __p = *__slot; + *__slot = __p->_M_next; + _M_deallocate_node(__p); + --_M_element_count; + ++__result; + } + + return __result; + } + + // ??? This could be optimized by taking advantage of the bucket + // structure, but it's not clear that it's worth doing. It probably + // wouldn't even be an optimization unless the load factor is large. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(iterator __first, iterator __last) + { + while (__first != __last) + __first = this->erase(__first); + return __last; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(const_iterator __first, const_iterator __last) + { + while (__first != __last) + __first = this->erase(__first); + return __last; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + clear() + { + _M_deallocate_nodes(_M_buckets, _M_bucket_count); + _M_element_count = 0; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + rehash(size_type __n) + { + _M_rehash(std::max(_M_rehash_policy._M_next_bkt(__n), + _M_rehash_policy._M_bkt_for_elements(_M_element_count + + 1))); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_rehash(size_type __n) + { + _Node** __new_array = _M_allocate_buckets(__n); + try + { + for (size_type __i = 0; __i < _M_bucket_count; ++__i) + while (_Node* __p = _M_buckets[__i]) + { + std::size_t __new_index = this->_M_bucket_index(__p, __n); + _M_buckets[__i] = __p->_M_next; + __p->_M_next = __new_array[__new_index]; + __new_array[__new_index] = __p; + } + _M_deallocate_buckets(_M_buckets, _M_bucket_count); + _M_bucket_count = __n; + _M_buckets = __new_array; + } + catch(...) + { + // A failure here means that a hash function threw an exception. + // We can't restore the previous state without calling the hash + // function again, so the only sensible recovery is to delete + // everything. + _M_deallocate_nodes(__new_array, __n); + _M_deallocate_buckets(__new_array, __n); + _M_deallocate_nodes(_M_buckets, _M_bucket_count); + _M_element_count = 0; + __throw_exception_again; + } + } + +_GLIBCXX_END_NAMESPACE +} // namespace std::tr1 + +#endif // _TR1_HASHTABLE + diff --git a/libstdc++/include/tr1/hashtable_policy.h b/libstdc++/include/tr1/hashtable_policy.h new file mode 100644 index 0000000..2d3830d --- /dev/null +++ b/libstdc++/include/tr1/hashtable_policy.h @@ -0,0 +1,903 @@ +// Internal policy header for TR1 unordered_set and unordered_map -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/hashtable_policy.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_HASHTABLE_POLICY_H +#define _TR1_HASHTABLE_POLICY_H 1 + +#include <functional> // _Identity, _Select1st +#include <tr1/utility> +#include <ext/type_traits.h> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) +namespace __detail +{ + // Helper function: return distance(first, last) for forward + // iterators, or 0 for input iterators. + template<class _Iterator> + inline typename std::iterator_traits<_Iterator>::difference_type + __distance_fw(_Iterator __first, _Iterator __last, + std::input_iterator_tag) + { return 0; } + + template<class _Iterator> + inline typename std::iterator_traits<_Iterator>::difference_type + __distance_fw(_Iterator __first, _Iterator __last, + std::forward_iterator_tag) + { return std::distance(__first, __last); } + + template<class _Iterator> + inline typename std::iterator_traits<_Iterator>::difference_type + __distance_fw(_Iterator __first, _Iterator __last) + { + typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag; + return __distance_fw(__first, __last, _Tag()); + } + + // XXX This is a hack. _Prime_rehash_policy's member functions, and + // certainly the list of primes, should be defined in a .cc file. + // We're temporarily putting them in a header because we don't have a + // place to put TR1 .cc files yet. There's no good reason for any of + // _Prime_rehash_policy's member functions to be inline, and there's + // certainly no good reason for _Primes<> to exist at all. + struct _LessThan + { + template<typename _Tp, typename _Up> + bool + operator()(_Tp __x, _Up __y) + { return __x < __y; } + }; + + template<int __ulongsize = sizeof(unsigned long)> + struct _Primes + { + static const int __n_primes = __ulongsize != 8 ? 256 : 256 + 48; + static const unsigned long __primes[256 + 48 + 1]; + }; + + template<int __ulongsize> + const int _Primes<__ulongsize>::__n_primes; + + template<int __ulongsize> + const unsigned long _Primes<__ulongsize>::__primes[256 + 48 + 1] = + { + 2ul, 3ul, 5ul, 7ul, 11ul, 13ul, 17ul, 19ul, 23ul, 29ul, 31ul, + 37ul, 41ul, 43ul, 47ul, 53ul, 59ul, 61ul, 67ul, 71ul, 73ul, 79ul, + 83ul, 89ul, 97ul, 103ul, 109ul, 113ul, 127ul, 137ul, 139ul, 149ul, + 157ul, 167ul, 179ul, 193ul, 199ul, 211ul, 227ul, 241ul, 257ul, + 277ul, 293ul, 313ul, 337ul, 359ul, 383ul, 409ul, 439ul, 467ul, + 503ul, 541ul, 577ul, 619ul, 661ul, 709ul, 761ul, 823ul, 887ul, + 953ul, 1031ul, 1109ul, 1193ul, 1289ul, 1381ul, 1493ul, 1613ul, + 1741ul, 1879ul, 2029ul, 2179ul, 2357ul, 2549ul, 2753ul, 2971ul, + 3209ul, 3469ul, 3739ul, 4027ul, 4349ul, 4703ul, 5087ul, 5503ul, + 5953ul, 6427ul, 6949ul, 7517ul, 8123ul, 8783ul, 9497ul, 10273ul, + 11113ul, 12011ul, 12983ul, 14033ul, 15173ul, 16411ul, 17749ul, + 19183ul, 20753ul, 22447ul, 24281ul, 26267ul, 28411ul, 30727ul, + 33223ul, 35933ul, 38873ul, 42043ul, 45481ul, 49201ul, 53201ul, + 57557ul, 62233ul, 67307ul, 72817ul, 78779ul, 85229ul, 92203ul, + 99733ul, 107897ul, 116731ul, 126271ul, 136607ul, 147793ul, + 159871ul, 172933ul, 187091ul, 202409ul, 218971ul, 236897ul, + 256279ul, 277261ul, 299951ul, 324503ul, 351061ul, 379787ul, + 410857ul, 444487ul, 480881ul, 520241ul, 562841ul, 608903ul, + 658753ul, 712697ul, 771049ul, 834181ul, 902483ul, 976369ul, + 1056323ul, 1142821ul, 1236397ul, 1337629ul, 1447153ul, 1565659ul, + 1693859ul, 1832561ul, 1982627ul, 2144977ul, 2320627ul, 2510653ul, + 2716249ul, 2938679ul, 3179303ul, 3439651ul, 3721303ul, 4026031ul, + 4355707ul, 4712381ul, 5098259ul, 5515729ul, 5967347ul, 6456007ul, + 6984629ul, 7556579ul, 8175383ul, 8844859ul, 9569143ul, 10352717ul, + 11200489ul, 12117689ul, 13109983ul, 14183539ul, 15345007ul, + 16601593ul, 17961079ul, 19431899ul, 21023161ul, 22744717ul, + 24607243ul, 26622317ul, 28802401ul, 31160981ul, 33712729ul, + 36473443ul, 39460231ul, 42691603ul, 46187573ul, 49969847ul, + 54061849ul, 58488943ul, 63278561ul, 68460391ul, 74066549ul, + 80131819ul, 86693767ul, 93793069ul, 101473717ul, 109783337ul, + 118773397ul, 128499677ul, 139022417ul, 150406843ul, 162723577ul, + 176048909ul, 190465427ul, 206062531ul, 222936881ul, 241193053ul, + 260944219ul, 282312799ul, 305431229ul, 330442829ul, 357502601ul, + 386778277ul, 418451333ul, 452718089ul, 489790921ul, 529899637ul, + 573292817ul, 620239453ul, 671030513ul, 725980837ul, 785430967ul, + 849749479ul, 919334987ul, 994618837ul, 1076067617ul, 1164186217ul, + 1259520799ul, 1362662261ul, 1474249943ul, 1594975441ul, + 1725587117ul, 1866894511ul, 2019773507ul, 2185171673ul, + 2364114217ul, 2557710269ul, 2767159799ul, 2993761039ul, + 3238918481ul, 3504151727ul, 3791104843ul, 4101556399ul, + 4294967291ul, + // Sentinel, so we don't have to test the result of lower_bound, + // or, on 64-bit machines, rest of the table. + __ulongsize != 8 ? 4294967291ul : (unsigned long)6442450933ull, + (unsigned long)8589934583ull, + (unsigned long)12884901857ull, (unsigned long)17179869143ull, + (unsigned long)25769803693ull, (unsigned long)34359738337ull, + (unsigned long)51539607367ull, (unsigned long)68719476731ull, + (unsigned long)103079215087ull, (unsigned long)137438953447ull, + (unsigned long)206158430123ull, (unsigned long)274877906899ull, + (unsigned long)412316860387ull, (unsigned long)549755813881ull, + (unsigned long)824633720731ull, (unsigned long)1099511627689ull, + (unsigned long)1649267441579ull, (unsigned long)2199023255531ull, + (unsigned long)3298534883309ull, (unsigned long)4398046511093ull, + (unsigned long)6597069766607ull, (unsigned long)8796093022151ull, + (unsigned long)13194139533241ull, (unsigned long)17592186044399ull, + (unsigned long)26388279066581ull, (unsigned long)35184372088777ull, + (unsigned long)52776558133177ull, (unsigned long)70368744177643ull, + (unsigned long)105553116266399ull, (unsigned long)140737488355213ull, + (unsigned long)211106232532861ull, (unsigned long)281474976710597ull, + (unsigned long)562949953421231ull, (unsigned long)1125899906842597ull, + (unsigned long)2251799813685119ull, (unsigned long)4503599627370449ull, + (unsigned long)9007199254740881ull, (unsigned long)18014398509481951ull, + (unsigned long)36028797018963913ull, (unsigned long)72057594037927931ull, + (unsigned long)144115188075855859ull, + (unsigned long)288230376151711717ull, + (unsigned long)576460752303423433ull, + (unsigned long)1152921504606846883ull, + (unsigned long)2305843009213693951ull, + (unsigned long)4611686018427387847ull, + (unsigned long)9223372036854775783ull, + (unsigned long)18446744073709551557ull, + (unsigned long)18446744073709551557ull + }; + + // Auxiliary types used for all instantiations of _Hashtable: nodes + // and iterators. + + // Nodes, used to wrap elements stored in the hash table. A policy + // template parameter of class template _Hashtable controls whether + // nodes also store a hash code. In some cases (e.g. strings) this + // may be a performance win. + template<typename _Value, bool __cache_hash_code> + struct _Hash_node; + + template<typename _Value> + struct _Hash_node<_Value, true> + { + _Value _M_v; + std::size_t _M_hash_code; + _Hash_node* _M_next; + }; + + template<typename _Value> + struct _Hash_node<_Value, false> + { + _Value _M_v; + _Hash_node* _M_next; + }; + + // Local iterators, used to iterate within a bucket but not between + // buckets. + template<typename _Value, bool __cache> + struct _Node_iterator_base + { + _Node_iterator_base(_Hash_node<_Value, __cache>* __p) + : _M_cur(__p) { } + + void + _M_incr() + { _M_cur = _M_cur->_M_next; } + + _Hash_node<_Value, __cache>* _M_cur; + }; + + template<typename _Value, bool __cache> + inline bool + operator==(const _Node_iterator_base<_Value, __cache>& __x, + const _Node_iterator_base<_Value, __cache>& __y) + { return __x._M_cur == __y._M_cur; } + + template<typename _Value, bool __cache> + inline bool + operator!=(const _Node_iterator_base<_Value, __cache>& __x, + const _Node_iterator_base<_Value, __cache>& __y) + { return __x._M_cur != __y._M_cur; } + + template<typename _Value, bool __constant_iterators, bool __cache> + struct _Node_iterator + : public _Node_iterator_base<_Value, __cache> + { + typedef _Value value_type; + typedef typename + __gnu_cxx::__conditional_type<__constant_iterators, + const _Value*, _Value*>::__type + pointer; + typedef typename + __gnu_cxx::__conditional_type<__constant_iterators, + const _Value&, _Value&>::__type + reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Node_iterator() + : _Node_iterator_base<_Value, __cache>(0) { } + + explicit + _Node_iterator(_Hash_node<_Value, __cache>* __p) + : _Node_iterator_base<_Value, __cache>(__p) { } + + reference + operator*() const + { return this->_M_cur->_M_v; } + + pointer + operator->() const + { return &this->_M_cur->_M_v; } + + _Node_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Node_iterator + operator++(int) + { + _Node_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + template<typename _Value, bool __constant_iterators, bool __cache> + struct _Node_const_iterator + : public _Node_iterator_base<_Value, __cache> + { + typedef _Value value_type; + typedef const _Value* pointer; + typedef const _Value& reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Node_const_iterator() + : _Node_iterator_base<_Value, __cache>(0) { } + + explicit + _Node_const_iterator(_Hash_node<_Value, __cache>* __p) + : _Node_iterator_base<_Value, __cache>(__p) { } + + _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators, + __cache>& __x) + : _Node_iterator_base<_Value, __cache>(__x._M_cur) { } + + reference + operator*() const + { return this->_M_cur->_M_v; } + + pointer + operator->() const + { return &this->_M_cur->_M_v; } + + _Node_const_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Node_const_iterator + operator++(int) + { + _Node_const_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + template<typename _Value, bool __cache> + struct _Hashtable_iterator_base + { + _Hashtable_iterator_base(_Hash_node<_Value, __cache>* __node, + _Hash_node<_Value, __cache>** __bucket) + : _M_cur_node(__node), _M_cur_bucket(__bucket) { } + + void + _M_incr() + { + _M_cur_node = _M_cur_node->_M_next; + if (!_M_cur_node) + _M_incr_bucket(); + } + + void + _M_incr_bucket(); + + _Hash_node<_Value, __cache>* _M_cur_node; + _Hash_node<_Value, __cache>** _M_cur_bucket; + }; + + // Global iterators, used for arbitrary iteration within a hash + // table. Larger and more expensive than local iterators. + template<typename _Value, bool __cache> + void + _Hashtable_iterator_base<_Value, __cache>:: + _M_incr_bucket() + { + ++_M_cur_bucket; + + // This loop requires the bucket array to have a non-null sentinel. + while (!*_M_cur_bucket) + ++_M_cur_bucket; + _M_cur_node = *_M_cur_bucket; + } + + template<typename _Value, bool __cache> + inline bool + operator==(const _Hashtable_iterator_base<_Value, __cache>& __x, + const _Hashtable_iterator_base<_Value, __cache>& __y) + { return __x._M_cur_node == __y._M_cur_node; } + + template<typename _Value, bool __cache> + inline bool + operator!=(const _Hashtable_iterator_base<_Value, __cache>& __x, + const _Hashtable_iterator_base<_Value, __cache>& __y) + { return __x._M_cur_node != __y._M_cur_node; } + + template<typename _Value, bool __constant_iterators, bool __cache> + struct _Hashtable_iterator + : public _Hashtable_iterator_base<_Value, __cache> + { + typedef _Value value_type; + typedef typename + __gnu_cxx::__conditional_type<__constant_iterators, + const _Value*, _Value*>::__type + pointer; + typedef typename + __gnu_cxx::__conditional_type<__constant_iterators, + const _Value&, _Value&>::__type + reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Hashtable_iterator() + : _Hashtable_iterator_base<_Value, __cache>(0, 0) { } + + _Hashtable_iterator(_Hash_node<_Value, __cache>* __p, + _Hash_node<_Value, __cache>** __b) + : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { } + + explicit + _Hashtable_iterator(_Hash_node<_Value, __cache>** __b) + : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { } + + reference + operator*() const + { return this->_M_cur_node->_M_v; } + + pointer + operator->() const + { return &this->_M_cur_node->_M_v; } + + _Hashtable_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Hashtable_iterator + operator++(int) + { + _Hashtable_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + template<typename _Value, bool __constant_iterators, bool __cache> + struct _Hashtable_const_iterator + : public _Hashtable_iterator_base<_Value, __cache> + { + typedef _Value value_type; + typedef const _Value* pointer; + typedef const _Value& reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Hashtable_const_iterator() + : _Hashtable_iterator_base<_Value, __cache>(0, 0) { } + + _Hashtable_const_iterator(_Hash_node<_Value, __cache>* __p, + _Hash_node<_Value, __cache>** __b) + : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { } + + explicit + _Hashtable_const_iterator(_Hash_node<_Value, __cache>** __b) + : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { } + + _Hashtable_const_iterator(const _Hashtable_iterator<_Value, + __constant_iterators, __cache>& __x) + : _Hashtable_iterator_base<_Value, __cache>(__x._M_cur_node, + __x._M_cur_bucket) { } + + reference + operator*() const + { return this->_M_cur_node->_M_v; } + + pointer + operator->() const + { return &this->_M_cur_node->_M_v; } + + _Hashtable_const_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Hashtable_const_iterator + operator++(int) + { + _Hashtable_const_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + + // Many of class template _Hashtable's template parameters are policy + // classes. These are defaults for the policies. + + // Default range hashing function: use division to fold a large number + // into the range [0, N). + struct _Mod_range_hashing + { + typedef std::size_t first_argument_type; + typedef std::size_t second_argument_type; + typedef std::size_t result_type; + + result_type + operator()(first_argument_type __num, second_argument_type __den) const + { return __num % __den; } + }; + + // Default ranged hash function H. In principle it should be a + // function object composed from objects of type H1 and H2 such that + // h(k, N) = h2(h1(k), N), but that would mean making extra copies of + // h1 and h2. So instead we'll just use a tag to tell class template + // hashtable to do that composition. + struct _Default_ranged_hash { }; + + // Default value for rehash policy. Bucket size is (usually) the + // smallest prime that keeps the load factor small enough. + struct _Prime_rehash_policy + { + _Prime_rehash_policy(float __z = 1.0); + + float + max_load_factor() const; + + // Return a bucket size no smaller than n. + std::size_t + _M_next_bkt(std::size_t __n) const; + + // Return a bucket count appropriate for n elements + std::size_t + _M_bkt_for_elements(std::size_t __n) const; + + // __n_bkt is current bucket count, __n_elt is current element count, + // and __n_ins is number of elements to be inserted. Do we need to + // increase bucket count? If so, return make_pair(true, n), where n + // is the new bucket count. If not, return make_pair(false, 0). + std::pair<bool, std::size_t> + _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, + std::size_t __n_ins) const; + + float _M_max_load_factor; + float _M_growth_factor; + mutable std::size_t _M_next_resize; + }; + + inline + _Prime_rehash_policy:: + _Prime_rehash_policy(float __z) + : _M_max_load_factor(__z), _M_growth_factor(2.f), _M_next_resize(0) + { } + + inline float + _Prime_rehash_policy:: + max_load_factor() const + { return _M_max_load_factor; } + + // Return a prime no smaller than n. + inline std::size_t + _Prime_rehash_policy:: + _M_next_bkt(std::size_t __n) const + { + const unsigned long* const __last = (_Primes<>::__primes + + _Primes<>::__n_primes); + const unsigned long* __p = std::lower_bound(_Primes<>::__primes, __last, + __n); + _M_next_resize = static_cast<std::size_t>(std::ceil(*__p + * _M_max_load_factor)); + return *__p; + } + + // Return the smallest prime p such that alpha p >= n, where alpha + // is the load factor. + inline std::size_t + _Prime_rehash_policy:: + _M_bkt_for_elements(std::size_t __n) const + { + const unsigned long* const __last = (_Primes<>::__primes + + _Primes<>::__n_primes); + const float __min_bkts = __n / _M_max_load_factor; + const unsigned long* __p = std::lower_bound(_Primes<>::__primes, __last, + __min_bkts, _LessThan()); + _M_next_resize = static_cast<std::size_t>(std::ceil(*__p + * _M_max_load_factor)); + return *__p; + } + + // Finds the smallest prime p such that alpha p > __n_elt + __n_ins. + // If p > __n_bkt, return make_pair(true, p); otherwise return + // make_pair(false, 0). In principle this isn't very different from + // _M_bkt_for_elements. + + // The only tricky part is that we're caching the element count at + // which we need to rehash, so we don't have to do a floating-point + // multiply for every insertion. + + inline std::pair<bool, std::size_t> + _Prime_rehash_policy:: + _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, + std::size_t __n_ins) const + { + if (__n_elt + __n_ins > _M_next_resize) + { + float __min_bkts = ((float(__n_ins) + float(__n_elt)) + / _M_max_load_factor); + if (__min_bkts > __n_bkt) + { + __min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt); + const unsigned long* const __last = (_Primes<>::__primes + + _Primes<>::__n_primes); + const unsigned long* __p = std::lower_bound(_Primes<>::__primes, + __last, __min_bkts, + _LessThan()); + _M_next_resize = + static_cast<std::size_t>(std::ceil(*__p * _M_max_load_factor)); + return std::make_pair(true, *__p); + } + else + { + _M_next_resize = + static_cast<std::size_t>(std::ceil(__n_bkt + * _M_max_load_factor)); + return std::make_pair(false, 0); + } + } + else + return std::make_pair(false, 0); + } + + // Base classes for std::tr1::_Hashtable. We define these base + // classes because in some cases we want to do different things + // depending on the value of a policy class. In some cases the + // policy class affects which member functions and nested typedefs + // are defined; we handle that by specializing base class templates. + // Several of the base class templates need to access other members + // of class template _Hashtable, so we use the "curiously recurring + // template pattern" for them. + + // class template _Map_base. If the hashtable has a value type of the + // form pair<T1, T2> and a key extraction policy that returns the + // first part of the pair, the hashtable gets a mapped_type typedef. + // If it satisfies those criteria and also has unique keys, then it + // also gets an operator[]. + template<typename _Key, typename _Value, typename _Ex, bool __unique, + typename _Hashtable> + struct _Map_base { }; + + template<typename _Key, typename _Pair, typename _Hashtable> + struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable> + { + typedef typename _Pair::second_type mapped_type; + }; + + template<typename _Key, typename _Pair, typename _Hashtable> + struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable> + { + typedef typename _Pair::second_type mapped_type; + + mapped_type& + operator[](const _Key& __k); + }; + + template<typename _Key, typename _Pair, typename _Hashtable> + typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>, + true, _Hashtable>::mapped_type& + _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: + operator[](const _Key& __k) + { + _Hashtable* __h = static_cast<_Hashtable*>(this); + typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); + std::size_t __n = __h->_M_bucket_index(__k, __code, + __h->_M_bucket_count); + + typename _Hashtable::_Node* __p = + __h->_M_find_node(__h->_M_buckets[__n], __k, __code); + if (!__p) + return __h->_M_insert_bucket(std::make_pair(__k, mapped_type()), + __n, __code)->second; + return (__p->_M_v).second; + } + + // class template _Rehash_base. Give hashtable the max_load_factor + // functions iff the rehash policy is _Prime_rehash_policy. + template<typename _RehashPolicy, typename _Hashtable> + struct _Rehash_base { }; + + template<typename _Hashtable> + struct _Rehash_base<_Prime_rehash_policy, _Hashtable> + { + float + max_load_factor() const + { + const _Hashtable* __this = static_cast<const _Hashtable*>(this); + return __this->__rehash_policy().max_load_factor(); + } + + void + max_load_factor(float __z) + { + _Hashtable* __this = static_cast<_Hashtable*>(this); + __this->__rehash_policy(_Prime_rehash_policy(__z)); + } + }; + + // Class template _Hash_code_base. Encapsulates two policy issues that + // aren't quite orthogonal. + // (1) the difference between using a ranged hash function and using + // the combination of a hash function and a range-hashing function. + // In the former case we don't have such things as hash codes, so + // we have a dummy type as placeholder. + // (2) Whether or not we cache hash codes. Caching hash codes is + // meaningless if we have a ranged hash function. + // We also put the key extraction and equality comparison function + // objects here, for convenience. + + // Primary template: unused except as a hook for specializations. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, + bool __cache_hash_code> + struct _Hash_code_base; + + // Specialization: ranged hash function, no caching hash codes. H1 + // and H2 are provided but ignored. We define a dummy hash code type. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash> + struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, + _Hash, false> + { + protected: + _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq, + const _H1&, const _H2&, const _Hash& __h) + : _M_extract(__ex), _M_eq(__eq), _M_ranged_hash(__h) { } + + typedef void* _Hash_code_type; + + _Hash_code_type + _M_hash_code(const _Key& __key) const + { return 0; } + + std::size_t + _M_bucket_index(const _Key& __k, _Hash_code_type, + std::size_t __n) const + { return _M_ranged_hash(__k, __n); } + + std::size_t + _M_bucket_index(const _Hash_node<_Value, false>* __p, + std::size_t __n) const + { return _M_ranged_hash(_M_extract(__p->_M_v), __n); } + + bool + _M_compare(const _Key& __k, _Hash_code_type, + _Hash_node<_Value, false>* __n) const + { return _M_eq(__k, _M_extract(__n->_M_v)); } + + void + _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const + { } + + void + _M_copy_code(_Hash_node<_Value, false>*, + const _Hash_node<_Value, false>*) const + { } + + void + _M_swap(_Hash_code_base& __x) + { + std::swap(_M_extract, __x._M_extract); + std::swap(_M_eq, __x._M_eq); + std::swap(_M_ranged_hash, __x._M_ranged_hash); + } + + protected: + _ExtractKey _M_extract; + _Equal _M_eq; + _Hash _M_ranged_hash; + }; + + + // No specialization for ranged hash function while caching hash codes. + // That combination is meaningless, and trying to do it is an error. + + + // Specialization: ranged hash function, cache hash codes. This + // combination is meaningless, so we provide only a declaration + // and no definition. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash> + struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, + _Hash, true>; + + // Specialization: hash function and range-hashing function, no + // caching of hash codes. H is provided but ignored. Provides + // typedef and accessor required by TR1. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2> + struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, + _Default_ranged_hash, false> + { + typedef _H1 hasher; + + hasher + hash_function() const + { return _M_h1; } + + protected: + _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq, + const _H1& __h1, const _H2& __h2, + const _Default_ranged_hash&) + : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { } + + typedef std::size_t _Hash_code_type; + + _Hash_code_type + _M_hash_code(const _Key& __k) const + { return _M_h1(__k); } + + std::size_t + _M_bucket_index(const _Key&, _Hash_code_type __c, + std::size_t __n) const + { return _M_h2(__c, __n); } + + std::size_t + _M_bucket_index(const _Hash_node<_Value, false>* __p, + std::size_t __n) const + { return _M_h2(_M_h1(_M_extract(__p->_M_v)), __n); } + + bool + _M_compare(const _Key& __k, _Hash_code_type, + _Hash_node<_Value, false>* __n) const + { return _M_eq(__k, _M_extract(__n->_M_v)); } + + void + _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const + { } + + void + _M_copy_code(_Hash_node<_Value, false>*, + const _Hash_node<_Value, false>*) const + { } + + void + _M_swap(_Hash_code_base& __x) + { + std::swap(_M_extract, __x._M_extract); + std::swap(_M_eq, __x._M_eq); + std::swap(_M_h1, __x._M_h1); + std::swap(_M_h2, __x._M_h2); + } + + protected: + _ExtractKey _M_extract; + _Equal _M_eq; + _H1 _M_h1; + _H2 _M_h2; + }; + + // Specialization: hash function and range-hashing function, + // caching hash codes. H is provided but ignored. Provides + // typedef and accessor required by TR1. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2> + struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, + _Default_ranged_hash, true> + { + typedef _H1 hasher; + + hasher + hash_function() const + { return _M_h1; } + + protected: + _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq, + const _H1& __h1, const _H2& __h2, + const _Default_ranged_hash&) + : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { } + + typedef std::size_t _Hash_code_type; + + _Hash_code_type + _M_hash_code(const _Key& __k) const + { return _M_h1(__k); } + + std::size_t + _M_bucket_index(const _Key&, _Hash_code_type __c, + std::size_t __n) const + { return _M_h2(__c, __n); } + + std::size_t + _M_bucket_index(const _Hash_node<_Value, true>* __p, + std::size_t __n) const + { return _M_h2(__p->_M_hash_code, __n); } + + bool + _M_compare(const _Key& __k, _Hash_code_type __c, + _Hash_node<_Value, true>* __n) const + { return __c == __n->_M_hash_code && _M_eq(__k, _M_extract(__n->_M_v)); } + + void + _M_store_code(_Hash_node<_Value, true>* __n, _Hash_code_type __c) const + { __n->_M_hash_code = __c; } + + void + _M_copy_code(_Hash_node<_Value, true>* __to, + const _Hash_node<_Value, true>* __from) const + { __to->_M_hash_code = __from->_M_hash_code; } + + void + _M_swap(_Hash_code_base& __x) + { + std::swap(_M_extract, __x._M_extract); + std::swap(_M_eq, __x._M_eq); + std::swap(_M_h1, __x._M_h1); + std::swap(_M_h2, __x._M_h2); + } + + protected: + _ExtractKey _M_extract; + _Equal _M_eq; + _H1 _M_h1; + _H2 _M_h2; + }; +} // namespace __detail +_GLIBCXX_END_NAMESPACE +} // namespace std::tr1 + +#endif // _TR1_HASHTABLE_POLICY_H + diff --git a/libstdc++/include/tr1/inttypes.h b/libstdc++/include/tr1/inttypes.h new file mode 100644 index 0000000..720089c --- /dev/null +++ b/libstdc++/include/tr1/inttypes.h @@ -0,0 +1,39 @@ +// TR1 inttypes.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/inttypes.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_INTTYPES_H +#define _TR1_INTTYPES_H 1 + +#include <tr1/cinttypes> + +#endif diff --git a/libstdc++/include/tr1/limits.h b/libstdc++/include/tr1/limits.h new file mode 100644 index 0000000..437d151 --- /dev/null +++ b/libstdc++/include/tr1/limits.h @@ -0,0 +1,39 @@ +// TR1 limits.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/limits.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_LIMITS_H +#define _TR1_LIMITS_H 1 + +#include <tr1/climits> + +#endif diff --git a/libstdc++/include/tr1/math.h b/libstdc++/include/tr1/math.h new file mode 100644 index 0000000..36fb2fd --- /dev/null +++ b/libstdc++/include/tr1/math.h @@ -0,0 +1,99 @@ +// TR1 math.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/math.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_MATH_H +#define _TR1_MATH_H 1 + +#include <tr1/cmath> + +#if _GLIBCXX_USE_C99_MATH_TR1 + +using std::tr1::acos; +using std::tr1::acosh; +using std::tr1::asin; +using std::tr1::asinh; +using std::tr1::atan; +using std::tr1::atan2; +using std::tr1::atanh; +using std::tr1::cbrt; +using std::tr1::ceil; +using std::tr1::copysign; +using std::tr1::cos; +using std::tr1::cosh; +using std::tr1::erf; +using std::tr1::erfc; +using std::tr1::exp; +using std::tr1::exp2; +using std::tr1::expm1; +using std::tr1::fabs; +using std::tr1::fdim; +using std::tr1::floor; +using std::tr1::fma; +using std::tr1::fmax; +using std::tr1::fmin; +using std::tr1::fmod; +using std::tr1::frexp; +using std::tr1::hypot; +using std::tr1::ilogb; +using std::tr1::ldexp; +using std::tr1::lgamma; +using std::tr1::llrint; +using std::tr1::llround; +using std::tr1::log; +using std::tr1::log10; +using std::tr1::log1p; +using std::tr1::log2; +using std::tr1::logb; +using std::tr1::lrint; +using std::tr1::lround; +using std::tr1::nearbyint; +using std::tr1::nextafter; +using std::tr1::nexttoward; +using std::tr1::pow; +using std::tr1::remainder; +using std::tr1::remquo; +using std::tr1::rint; +using std::tr1::round; +using std::tr1::scalbln; +using std::tr1::scalbn; +using std::tr1::sin; +using std::tr1::sinh; +using std::tr1::sqrt; +using std::tr1::tan; +using std::tr1::tanh; +using std::tr1::tgamma; +using std::tr1::trunc; + +#endif + +#endif diff --git a/libstdc++/include/tr1/memory b/libstdc++/include/tr1/memory new file mode 100644 index 0000000..9de80da --- /dev/null +++ b/libstdc++/include/tr1/memory @@ -0,0 +1,56 @@ +// <tr1/memory> -*- C++ -*- + +// Copyright (C) 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. + +/** + * @file tr1/memory + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_MEMORY +#define _TR1_MEMORY 1 + +#include "../memory" +#include <functional> // std::less +#include <exception> // std::exception +#include <new> // std::bad_alloc +#include <typeinfo> // std::type_info in get_deleter +#include <cstddef> // std::size_t +#include <algorithm> // std::swap +#include <iosfwd> // std::basic_ostream +#include <cstdlib> // std::abort + +#include <ext/atomicity.h> +#include <ext/concurrence.h> +#include <bits/functexcept.h> +#include <debug/debug.h> +#include <tr1/type_traits> // tr1::add_reference + +#include <tr1/boost_shared_ptr.h> + +#endif diff --git a/libstdc++/include/tr1/mu_iterate.h b/libstdc++/include/tr1/mu_iterate.h new file mode 100644 index 0000000..abdc724 --- /dev/null +++ b/libstdc++/include/tr1/mu_iterate.h @@ -0,0 +1,52 @@ +// TR1 functional -*- C++ -*- + +// Copyright (C) 2005 Free Software Foundation, Inc. +// Written by Douglas Gregor <doug.gregor -at- gmail.com> +// +// 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. + +/** @file tr1/mu_iterate.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Determine the result type when we pass the arguments along. This +// involves passing along the cv-qualifiers placed on _Mu and +// unwrapping the argument bundle. +// @namespace std::tr1 +// @class std::tr1::_Mu::result +template<typename _CVMu, typename _CVArg + _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +class result<_CVMu(_CVArg, tuple<_GLIBCXX_TEMPLATE_ARGS>)> + : public result_of<_CVArg(_GLIBCXX_TEMPLATE_ARGS)> { }; + +template<typename _CVArg _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS> +typename result_of<_CVArg(_GLIBCXX_TEMPLATE_ARGS)>::type +operator()(_CVArg& __arg, const tuple<_GLIBCXX_TEMPLATE_ARGS>& __tuple) + const volatile +{ + return __arg(_GLIBCXX_MU_GET_TUPLE_ARGS); +} diff --git a/libstdc++/include/tr1/random b/libstdc++/include/tr1/random new file mode 100644 index 0000000..56ea508 --- /dev/null +++ b/libstdc++/include/tr1/random @@ -0,0 +1,2365 @@ +// random number generation -*- C++ -*- + +// Copyright (C) 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. + +/** + * @file tr1/random + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_RANDOM +#define _TR1_RANDOM 1 + +#include <cmath> +#include <cstdio> +#include <string> +#include <iosfwd> +#include <limits> +#include <tr1/type_traits> +#include <tr1/cmath> +#include <ext/type_traits.h> +#include <ext/numeric_traits.h> +#include <bits/concept_check.h> +#include <debug/debug.h> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // [5.1] Random number generation + + /** + * @addtogroup tr1_random Random Number Generation + * A facility for generating random numbers on selected distributions. + * @{ + */ + + /* + * Implementation-space details. + */ + namespace __detail + { + template<typename _UIntType, int __w, + bool = __w < std::numeric_limits<_UIntType>::digits> + struct _Shift + { static const _UIntType __value = 0; }; + + template<typename _UIntType, int __w> + struct _Shift<_UIntType, __w, true> + { static const _UIntType __value = _UIntType(1) << __w; }; + + template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool> + struct _Mod; + + // Dispatch based on modulus value to prevent divide-by-zero compile-time + // errors when m == 0. + template<typename _Tp, _Tp __a, _Tp __c, _Tp __m> + inline _Tp + __mod(_Tp __x) + { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); } + + typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4), + unsigned, unsigned long>::__type _UInt32Type; + + /* + * An adaptor class for converting the output of any Generator into + * the input for a specific Distribution. + */ + template<typename _Engine, typename _Distribution> + struct _Adaptor + { + typedef typename _Engine::result_type _Engine_result_type; + typedef typename _Distribution::input_type result_type; + + public: + _Adaptor(const _Engine& __g) + : _M_g(__g) { } + + result_type + min() const + { + result_type __return_value = 0; + if (is_integral<_Engine_result_type>::value + && is_integral<result_type>::value) + __return_value = _M_g.min(); + else if (!is_integral<result_type>::value) + __return_value = result_type(0); + return __return_value; + } + + result_type + max() const + { + result_type __return_value = 0; + if (is_integral<_Engine_result_type>::value + && is_integral<result_type>::value) + __return_value = _M_g.max(); + else if (!is_integral<result_type>::value) + __return_value = result_type(1); + return __return_value; + } + + result_type + operator()(); + + private: + _Engine _M_g; + }; + + /* + * Converts a value generated by the adapted random number generator into a + * value in the input domain for the dependent random number distribution. + * + * Because the type traits are compile time constants only the appropriate + * clause of the if statements will actually be emitted by the compiler. + */ + template<typename _Engine, typename _Distribution> + typename _Adaptor<_Engine, _Distribution>::result_type + _Adaptor<_Engine, _Distribution>:: + operator()() + { + result_type __return_value = 0; + if (is_integral<_Engine_result_type>::value + && is_integral<result_type>::value) + __return_value = _M_g(); + else if (is_integral<_Engine_result_type>::value + && !is_integral<result_type>::value) + __return_value = result_type(_M_g() - _M_g.min()) + / result_type(_M_g.max() - _M_g.min() + result_type(1)); + else if (!is_integral<_Engine_result_type>::value + && !is_integral<result_type>::value) + __return_value = result_type(_M_g() - _M_g.min()) + / result_type(_M_g.max() - _M_g.min()); + return __return_value; + } + } // namespace __detail + + /** + * Produces random numbers on a given disribution function using a un uniform + * random number generation engine. + * + * @todo the engine_value_type needs to be studied more carefully. + */ + template<typename _Engine, typename _Dist> + class variate_generator + { + // Concept requirements. + __glibcxx_class_requires(_Engine, _CopyConstructibleConcept) + // __glibcxx_class_requires(_Engine, _EngineConcept) + // __glibcxx_class_requires(_Dist, _EngineConcept) + + public: + typedef _Engine engine_type; + typedef __detail::_Adaptor<_Engine, _Dist> engine_value_type; + typedef _Dist distribution_type; + typedef typename _Dist::result_type result_type; + + // tr1:5.1.1 table 5.1 requirement + typedef typename __gnu_cxx::__enable_if< + is_arithmetic<result_type>::value, result_type>::__type _IsValidType; + + /** + * Constructs a variate generator with the uniform random number + * generator @p __eng for the random distribution @p __dist. + * + * @throws Any exceptions which may thrown by the copy constructors of + * the @p _Engine or @p _Dist objects. + */ + variate_generator(engine_type __eng, distribution_type __dist) + : _M_engine(__eng), _M_dist(__dist) { } + + /** + * Gets the next generated value on the distribution. + */ + result_type + operator()() + { return _M_dist(_M_engine); } + + /** + * WTF? + */ + template<typename _Tp> + result_type + operator()(_Tp __value) + { return _M_dist(_M_engine, __value); } + + /** + * Gets a reference to the underlying uniform random number generator + * object. + */ + engine_value_type& + engine() + { return _M_engine; } + + /** + * Gets a const reference to the underlying uniform random number + * generator object. + */ + const engine_value_type& + engine() const + { return _M_engine; } + + /** + * Gets a reference to the underlying random distribution. + */ + distribution_type& + distribution() + { return _M_dist; } + + /** + * Gets a const reference to the underlying random distribution. + */ + const distribution_type& + distribution() const + { return _M_dist; } + + /** + * Gets the closed lower bound of the distribution interval. + */ + result_type + min() const + { return this->distribution().min(); } + + /** + * Gets the closed upper bound of the distribution interval. + */ + result_type + max() const + { return this->distribution().max(); } + + private: + engine_value_type _M_engine; + distribution_type _M_dist; + }; + + + /** + * @addtogroup tr1_random_generators Random Number Generators + * @ingroup tr1_random + * + * These classes define objects which provide random or pseudorandom + * numbers, either from a discrete or a continuous interval. The + * random number generator supplied as a part of this library are + * all uniform random number generators which provide a sequence of + * random number uniformly distributed over their range. + * + * A number generator is a function object with an operator() that + * takes zero arguments and returns a number. + * + * A compliant random number generator must satisy the following + * requirements. <table border=1 cellpadding=10 cellspacing=0> + * <caption align=top>Random Number Generator Requirements</caption> + * <tr><td>To be documented.</td></tr> </table> + * + * @{ + */ + + /** + * @brief A model of a linear congruential random number generator. + * + * A random number generator that produces pseudorandom numbers using the + * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$. + * + * The template parameter @p _UIntType must be an unsigned integral type + * large enough to store values up to (__m-1). If the template parameter + * @p __m is 0, the modulus @p __m used is + * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template + * parameters @p __a and @p __c must be less than @p __m. + * + * The size of the state is @f$ 1 @f$. + */ + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + class linear_congruential + { + __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept) + // __glibcpp_class_requires(__a < __m && __c < __m) + + public: + /** The type of the generated random value. */ + typedef _UIntType result_type; + + /** The multiplier. */ + static const _UIntType multiplier = __a; + /** An increment. */ + static const _UIntType increment = __c; + /** The modulus. */ + static const _UIntType modulus = __m; + + /** + * Constructs a %linear_congruential random number generator engine with + * seed @p __s. The default seed value is 1. + * + * @param __s The initial seed value. + */ + explicit + linear_congruential(unsigned long __x0 = 1) + { this->seed(__x0); } + + /** + * Constructs a %linear_congruential random number generator engine + * seeded from the generator function @p __g. + * + * @param __g The seed generator function. + */ + template<class _Gen> + linear_congruential(_Gen& __g) + { this->seed(__g); } + + /** + * Reseeds the %linear_congruential random number generator engine + * sequence to the seed @g __s. + * + * @param __s The new seed. + */ + void + seed(unsigned long __s = 1); + + /** + * Reseeds the %linear_congruential random number generator engine + * sequence using values from the generator function @p __g. + * + * @param __g the seed generator function. + */ + template<class _Gen> + void + seed(_Gen& __g) + { seed(__g, typename is_fundamental<_Gen>::type()); } + + /** + * Gets the smallest possible value in the output range. + * + * The minumum depends on the @p __c parameter: if it is zero, the + * minimum generated must be > 0, otherwise 0 is allowed. + */ + result_type + min() const + { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; } + + /** + * Gets the largest possible value in the output range. + */ + result_type + max() const + { return __m - 1; } + + /** + * Gets the next random number in the sequence. + */ + result_type + operator()(); + + /** + * Compares two linear congruential random number generator + * objects of the same type for equality. + * + * @param __lhs A linear congruential random number generator object. + * @param __rhs Another linear congruential random number generator obj. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const linear_congruential& __lhs, + const linear_congruential& __rhs) + { return __lhs._M_x == __rhs._M_x; } + + /** + * Compares two linear congruential random number generator + * objects of the same type for inequality. + * + * @param __lhs A linear congruential random number generator object. + * @param __rhs Another linear congruential random number generator obj. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const linear_congruential& __lhs, + const linear_congruential& __rhs) + { return !(__lhs == __rhs); } + + /** + * Writes the textual representation of the state x(i) of x to @p __os. + * + * @param __os The output stream. + * @param __lcr A % linear_congruential random number generator. + * @returns __os. + */ + template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1, + _UIntType1 __m1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const linear_congruential<_UIntType1, __a1, __c1, + __m1>& __lcr); + + /** + * Sets the state of the engine by reading its textual + * representation from @p __is. + * + * The textual representation must have been previously written using an + * output stream whose imbued locale and whose type's template + * specialization arguments _CharT and _Traits were the same as those of + * @p __is. + * + * @param __is The input stream. + * @param __lcr A % linear_congruential random number generator. + * @returns __is. + */ + template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1, + _UIntType1 __m1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr); + + private: + template<class _Gen> + void + seed(_Gen& __g, true_type) + { return seed(static_cast<unsigned long>(__g)); } + + template<class _Gen> + void + seed(_Gen& __g, false_type); + + _UIntType _M_x; + }; + + /** + * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller. + */ + typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0; + + /** + * An alternative LCR (Lehmer Generator function) . + */ + typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand; + + + /** + * A generalized feedback shift register discrete random number generator. + * + * This algorithm avoind multiplication and division and is designed to be + * friendly to a pipelined architecture. If the parameters are chosen + * correctly, this generator will produce numbers with a very long period and + * fairly good apparent entropy, although still not cryptographically strong. + * + * The best way to use this generator is with the predefined mt19937 class. + * + * This algorithm was originally invented by Makoto Matsumoto and + * Takuji Nishimura. + * + * @var word_size The number of bits in each element of the state vector. + * @var state_size The degree of recursion. + * @var shift_size The period parameter. + * @var mask_bits The separation point bit index. + * @var parameter_a The last row of the twist matrix. + * @var output_u The first right-shift tempering matrix parameter. + * @var output_s The first left-shift tempering matrix parameter. + * @var output_b The first left-shift tempering matrix mask. + * @var output_t The second left-shift tempering matrix parameter. + * @var output_c The second left-shift tempering matrix mask. + * @var output_l The second right-shift tempering matrix parameter. + */ + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, _UIntType __b, int __t, + _UIntType __c, int __l> + class mersenne_twister + { + __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept) + + public: + // types + typedef _UIntType result_type; + + // parameter values + static const int word_size = __w; + static const int state_size = __n; + static const int shift_size = __m; + static const int mask_bits = __r; + static const _UIntType parameter_a = __a; + static const int output_u = __u; + static const int output_s = __s; + static const _UIntType output_b = __b; + static const int output_t = __t; + static const _UIntType output_c = __c; + static const int output_l = __l; + + // constructors and member function + mersenne_twister() + { seed(); } + + explicit + mersenne_twister(unsigned long __value) + { seed(__value); } + + template<class _Gen> + mersenne_twister(_Gen& __g) + { seed(__g); } + + void + seed() + { seed(5489UL); } + + void + seed(unsigned long __value); + + template<class _Gen> + void + seed(_Gen& __g) + { seed(__g, typename is_fundamental<_Gen>::type()); } + + result_type + min() const + { return 0; }; + + result_type + max() const + { return __detail::_Shift<_UIntType, __w>::__value - 1; } + + result_type + operator()(); + + /** + * Compares two % mersenne_twister random number generator objects of + * the same type for equality. + * + * @param __lhs A % mersenne_twister random number generator object. + * @param __rhs Another % mersenne_twister random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const mersenne_twister& __lhs, + const mersenne_twister& __rhs) + { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); } + + /** + * Compares two % mersenne_twister random number generator objects of + * the same type for inequality. + * + * @param __lhs A % mersenne_twister random number generator object. + * @param __rhs Another % mersenne_twister random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const mersenne_twister& __lhs, + const mersenne_twister& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a % mersenne_twister random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A % mersenne_twister random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<class _UIntType1, int __w1, int __n1, int __m1, int __r1, + _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1, + _UIntType1 __c1, int __l1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1, + __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x); + + /** + * Extracts the current state of a % mersenne_twister random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A % mersenne_twister random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<class _UIntType1, int __w1, int __n1, int __m1, int __r1, + _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1, + _UIntType1 __c1, int __l1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1, + __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x); + + private: + template<class _Gen> + void + seed(_Gen& __g, true_type) + { return seed(static_cast<unsigned long>(__g)); } + + template<class _Gen> + void + seed(_Gen& __g, false_type); + + _UIntType _M_x[state_size]; + int _M_p; + }; + + /** + * The classic Mersenne Twister. + * + * Reference: + * M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally + * Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions + * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. + */ + typedef mersenne_twister< + unsigned long, 32, 624, 397, 31, + 0x9908b0dful, 11, 7, + 0x9d2c5680ul, 15, + 0xefc60000ul, 18 + > mt19937; + + + /** + * @brief The Marsaglia-Zaman generator. + * + * This is a model of a Generalized Fibonacci discrete random number + * generator, sometimes referred to as the SWC generator. + * + * A discrete random number generator that produces pseudorandom + * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} - + * carry_{i-1}) \bmod m @f$. + * + * The size of the state is @f$ r @f$ + * and the maximum period of the generator is @f$ m^r - m^s -1 @f$. + * + * N1688[4.13] says "the template parameter _IntType shall denote an integral + * type large enough to store values up to m." + * + * @if maint + * @var _M_x The state of the generator. This is a ring buffer. + * @var _M_carry The carry. + * @var _M_p Current index of x(i - r). + * @endif + */ + template<typename _IntType, _IntType __m, int __s, int __r> + class subtract_with_carry + { + __glibcxx_class_requires(_IntType, _IntegerConcept) + + public: + /** The type of the generated random value. */ + typedef _IntType result_type; + + // parameter values + static const _IntType modulus = __m; + static const int long_lag = __r; + static const int short_lag = __s; + + /** + * Constructs a default-initialized % subtract_with_carry random number + * generator. + */ + subtract_with_carry() + { this->seed(); } + + /** + * Constructs an explicitly seeded % subtract_with_carry random number + * generator. + */ + explicit + subtract_with_carry(unsigned long __value) + { this->seed(__value); } + + /** + * Constructs a %subtract_with_carry random number generator engine + * seeded from the generator function @p __g. + * + * @param __g The seed generator function. + */ + template<class _Gen> + subtract_with_carry(_Gen& __g) + { this->seed(__g); } + + /** + * Seeds the initial state @f$ x_0 @f$ of the random number generator. + * + * N1688[4.19] modifies this as follows. If @p __value == 0, + * sets value to 19780503. In any case, with a linear + * congruential generator lcg(i) having parameters @f$ m_{lcg} = + * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value + * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m + * \dots lcg(r) \bmod m @f$ respectively. If @f$ x_{-1} = 0 @f$ + * set carry to 1, otherwise sets carry to 0. + */ + void + seed(unsigned long __value = 19780503); + + /** + * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry + * random number generator. + */ + template<class _Gen> + void + seed(_Gen& __g) + { seed(__g, typename is_fundamental<_Gen>::type()); } + + /** + * Gets the inclusive minimum value of the range of random integers + * returned by this generator. + */ + result_type + min() const + { return 0; } + + /** + * Gets the inclusive maximum value of the range of random integers + * returned by this generator. + */ + result_type + max() const + { return this->modulus - 1; } + + /** + * Gets the next random number in the sequence. + */ + result_type + operator()(); + + /** + * Compares two % subtract_with_carry random number generator objects of + * the same type for equality. + * + * @param __lhs A % subtract_with_carry random number generator object. + * @param __rhs Another % subtract_with_carry random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const subtract_with_carry& __lhs, + const subtract_with_carry& __rhs) + { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); } + + /** + * Compares two % subtract_with_carry random number generator objects of + * the same type for inequality. + * + * @param __lhs A % subtract_with_carry random number generator object. + * @param __rhs Another % subtract_with_carry random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const subtract_with_carry& __lhs, + const subtract_with_carry& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a % subtract_with_carry random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A % subtract_with_carry random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, _IntType1 __m1, int __s1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry<_IntType1, __m1, __s1, + __r1>& __x); + + /** + * Extracts the current state of a % subtract_with_carry random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A % subtract_with_carry random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<typename _IntType1, _IntType1 __m1, int __s1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x); + + private: + template<class _Gen> + void + seed(_Gen& __g, true_type) + { return seed(static_cast<unsigned long>(__g)); } + + template<class _Gen> + void + seed(_Gen& __g, false_type); + + typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType; + + _UIntType _M_x[long_lag]; + _UIntType _M_carry; + int _M_p; + }; + + + /** + * @brief The Marsaglia-Zaman generator (floats version). + * + * @if maint + * @var _M_x The state of the generator. This is a ring buffer. + * @var _M_carry The carry. + * @var _M_p Current index of x(i - r). + * @var _M_npows Precomputed negative powers of 2. + * @endif + */ + template<typename _RealType, int __w, int __s, int __r> + class subtract_with_carry_01 + { + public: + /** The type of the generated random value. */ + typedef _RealType result_type; + + // parameter values + static const int word_size = __w; + static const int long_lag = __r; + static const int short_lag = __s; + + /** + * Constructs a default-initialized % subtract_with_carry_01 random + * number generator. + */ + subtract_with_carry_01() + { + this->seed(); + _M_initialize_npows(); + } + + /** + * Constructs an explicitly seeded % subtract_with_carry_01 random number + * generator. + */ + explicit + subtract_with_carry_01(unsigned long __value) + { + this->seed(__value); + _M_initialize_npows(); + } + + /** + * Constructs a % subtract_with_carry_01 random number generator engine + * seeded from the generator function @p __g. + * + * @param __g The seed generator function. + */ + template<class _Gen> + subtract_with_carry_01(_Gen& __g) + { + this->seed(__g); + _M_initialize_npows(); + } + + /** + * Seeds the initial state @f$ x_0 @f$ of the random number generator. + */ + void + seed(unsigned long __value = 19780503); + + /** + * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01 + * random number generator. + */ + template<class _Gen> + void + seed(_Gen& __g) + { seed(__g, typename is_fundamental<_Gen>::type()); } + + /** + * Gets the minimum value of the range of random floats + * returned by this generator. + */ + result_type + min() const + { return 0.0; } + + /** + * Gets the maximum value of the range of random floats + * returned by this generator. + */ + result_type + max() const + { return 1.0; } + + /** + * Gets the next random number in the sequence. + */ + result_type + operator()(); + + /** + * Compares two % subtract_with_carry_01 random number generator objects + * of the same type for equality. + * + * @param __lhs A % subtract_with_carry_01 random number + * generator object. + * @param __rhs Another % subtract_with_carry_01 random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const subtract_with_carry_01& __lhs, + const subtract_with_carry_01& __rhs) + { + for (int __i = 0; __i < long_lag; ++__i) + if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n, + __rhs._M_x[__i])) + return false; + return true; + } + + /** + * Compares two % subtract_with_carry_01 random number generator objects + * of the same type for inequality. + * + * @param __lhs A % subtract_with_carry_01 random number + * generator object. + * + * @param __rhs Another % subtract_with_carry_01 random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const subtract_with_carry_01& __lhs, + const subtract_with_carry_01& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a % subtract_with_carry_01 random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A % subtract_with_carry_01 random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, int __w1, int __s1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry_01<_RealType1, __w1, __s1, + __r1>& __x); + + /** + * Extracts the current state of a % subtract_with_carry_01 random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A % subtract_with_carry_01 random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<typename _RealType1, int __w1, int __s1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x); + + private: + template<class _Gen> + void + seed(_Gen& __g, true_type) + { return seed(static_cast<unsigned long>(__g)); } + + template<class _Gen> + void + seed(_Gen& __g, false_type); + + void + _M_initialize_npows(); + + static const int __n = (__w + 31) / 32; + + typedef __detail::_UInt32Type _UInt32Type; + _UInt32Type _M_x[long_lag][__n]; + _RealType _M_npows[__n]; + _UInt32Type _M_carry; + int _M_p; + }; + + typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 508. Bad parameters for ranlux64_base_01. + typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01; + + + /** + * Produces random numbers from some base engine by discarding blocks of + * data. + * + * 0 <= @p __r <= @p __p + */ + template<class _UniformRandomNumberGenerator, int __p, int __r> + class discard_block + { + // __glibcxx_class_requires(typename base_type::result_type, + // ArithmeticTypeConcept) + + public: + /** The type of the underlying generator engine. */ + typedef _UniformRandomNumberGenerator base_type; + /** The type of the generated random value. */ + typedef typename base_type::result_type result_type; + + // parameter values + static const int block_size = __p; + static const int used_block = __r; + + /** + * Constructs a default %discard_block engine. + * + * The underlying engine is default constructed as well. + */ + discard_block() + : _M_n(0) { } + + /** + * Copy constructs a %discard_block engine. + * + * Copies an existing base class random number geenerator. + * @param rng An existing (base class) engine object. + */ + explicit + discard_block(const base_type& __rng) + : _M_b(__rng), _M_n(0) { } + + /** + * Seed constructs a %discard_block engine. + * + * Constructs the underlying generator engine seeded with @p __s. + * @param __s A seed value for the base class engine. + */ + explicit + discard_block(unsigned long __s) + : _M_b(__s), _M_n(0) { } + + /** + * Generator construct a %discard_block engine. + * + * @param __g A seed generator function. + */ + template<class _Gen> + discard_block(_Gen& __g) + : _M_b(__g), _M_n(0) { } + + /** + * Reseeds the %discard_block object with the default seed for the + * underlying base class generator engine. + */ + void seed() + { + _M_b.seed(); + _M_n = 0; + } + + /** + * Reseeds the %discard_block object with the given seed generator + * function. + * @param __g A seed generator function. + */ + template<class _Gen> + void seed(_Gen& __g) + { + _M_b.seed(__g); + _M_n = 0; + } + + /** + * Gets a const reference to the underlying generator engine object. + */ + const base_type& + base() const + { return _M_b; } + + /** + * Gets the minimum value in the generated random number range. + */ + result_type + min() const + { return _M_b.min(); } + + /** + * Gets the maximum value in the generated random number range. + */ + result_type + max() const + { return _M_b.max(); } + + /** + * Gets the next value in the generated random number sequence. + */ + result_type + operator()(); + + /** + * Compares two %discard_block random number generator objects of + * the same type for equality. + * + * @param __lhs A %discard_block random number generator object. + * @param __rhs Another %discard_block random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const discard_block& __lhs, const discard_block& __rhs) + { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); } + + /** + * Compares two %discard_block random number generator objects of + * the same type for inequality. + * + * @param __lhs A %discard_block random number generator object. + * @param __rhs Another %discard_block random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const discard_block& __lhs, const discard_block& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a %discard_block random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %discard_block random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<class _UniformRandomNumberGenerator1, int __p1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const discard_block<_UniformRandomNumberGenerator1, + __p1, __r1>& __x); + + /** + * Extracts the current state of a % subtract_with_carry random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %discard_block random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<class _UniformRandomNumberGenerator1, int __p1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + discard_block<_UniformRandomNumberGenerator1, + __p1, __r1>& __x); + + private: + base_type _M_b; + int _M_n; + }; + + + /** + * James's luxury-level-3 integer adaptation of Luescher's generator. + */ + typedef discard_block< + subtract_with_carry<unsigned long, (1UL << 24), 10, 24>, + 223, + 24 + > ranlux3; + + /** + * James's luxury-level-4 integer adaptation of Luescher's generator. + */ + typedef discard_block< + subtract_with_carry<unsigned long, (1UL << 24), 10, 24>, + 389, + 24 + > ranlux4; + + typedef discard_block< + subtract_with_carry_01<float, 24, 10, 24>, + 223, + 24 + > ranlux3_01; + + typedef discard_block< + subtract_with_carry_01<float, 24, 10, 24>, + 389, + 24 + > ranlux4_01; + + + /** + * A random number generator adaptor class that combines two random number + * generator engines into a single output sequence. + */ + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2> + class xor_combine + { + // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1:: + // result_type, ArithmeticTypeConcept) + // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2:: + // result_type, ArithmeticTypeConcept) + + public: + /** The type of the the first underlying generator engine. */ + typedef _UniformRandomNumberGenerator1 base1_type; + /** The type of the the second underlying generator engine. */ + typedef _UniformRandomNumberGenerator2 base2_type; + + private: + typedef typename base1_type::result_type _Result_type1; + typedef typename base2_type::result_type _Result_type2; + + public: + /** The type of the generated random value. */ + typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1) + > sizeof(_Result_type2)), + _Result_type1, _Result_type2>::__type result_type; + + // parameter values + static const int shift1 = __s1; + static const int shift2 = __s2; + + // constructors and member function + xor_combine() + : _M_b1(), _M_b2() + { _M_initialize_max(); } + + xor_combine(const base1_type& __rng1, const base2_type& __rng2) + : _M_b1(__rng1), _M_b2(__rng2) + { _M_initialize_max(); } + + xor_combine(unsigned long __s) + : _M_b1(__s), _M_b2(__s + 1) + { _M_initialize_max(); } + + template<class _Gen> + xor_combine(_Gen& __g) + : _M_b1(__g), _M_b2(__g) + { _M_initialize_max(); } + + void + seed() + { + _M_b1.seed(); + _M_b2.seed(); + } + + template<class _Gen> + void + seed(_Gen& __g) + { + _M_b1.seed(__g); + _M_b2.seed(__g); + } + + const base1_type& + base1() const + { return _M_b1; } + + const base2_type& + base2() const + { return _M_b2; } + + result_type + min() const + { return 0; } + + result_type + max() const + { return _M_max; } + + /** + * Gets the next random number in the sequence. + */ + // NB: Not exactly the TR1 formula, per N2079 instead. + result_type + operator()() + { + return ((result_type(_M_b1() - _M_b1.min()) << shift1) + ^ (result_type(_M_b2() - _M_b2.min()) << shift2)); + } + + /** + * Compares two %xor_combine random number generator objects of + * the same type for equality. + * + * @param __lhs A %xor_combine random number generator object. + * @param __rhs Another %xor_combine random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const xor_combine& __lhs, const xor_combine& __rhs) + { + return (__lhs.base1() == __rhs.base1()) + && (__lhs.base2() == __rhs.base2()); + } + + /** + * Compares two %xor_combine random number generator objects of + * the same type for inequality. + * + * @param __lhs A %xor_combine random number generator object. + * @param __rhs Another %xor_combine random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const xor_combine& __lhs, const xor_combine& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a %xor_combine random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %xor_combine random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<class _UniformRandomNumberGenerator11, int __s11, + class _UniformRandomNumberGenerator21, int __s21, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const xor_combine<_UniformRandomNumberGenerator11, __s11, + _UniformRandomNumberGenerator21, __s21>& __x); + + /** + * Extracts the current state of a %xor_combine random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %xor_combine random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<class _UniformRandomNumberGenerator11, int __s11, + class _UniformRandomNumberGenerator21, int __s21, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + xor_combine<_UniformRandomNumberGenerator11, __s11, + _UniformRandomNumberGenerator21, __s21>& __x); + + private: + void + _M_initialize_max(); + + result_type + _M_initialize_max_aux(result_type, result_type, int); + + base1_type _M_b1; + base2_type _M_b2; + result_type _M_max; + }; + + + /** + * A standard interface to a platform-specific non-deterministic + * random number generator (if any are available). + */ + class random_device + { + public: + // types + typedef unsigned int result_type; + + // constructors, destructors and member functions + +#ifdef _GLIBCXX_USE_RANDOM_TR1 + + explicit + random_device(const std::string& __token = "/dev/urandom") + { + if ((__token != "/dev/urandom" && __token != "/dev/random") + || !(_M_file = std::fopen(__token.c_str(), "rb"))) + std::__throw_runtime_error(__N("random_device::" + "random_device(const std::string&)")); + } + + ~random_device() + { std::fclose(_M_file); } + +#else + + explicit + random_device(const std::string& __token = "mt19937") + : _M_mt(_M_strtoul(__token)) { } + + private: + static unsigned long + _M_strtoul(const std::string& __str) + { + unsigned long __ret = 5489UL; + if (__str != "mt19937") + { + const char* __nptr = __str.c_str(); + char* __endptr; + __ret = std::strtoul(__nptr, &__endptr, 0); + if (*__nptr == '\0' || *__endptr != '\0') + std::__throw_runtime_error(__N("random_device::_M_strtoul" + "(const std::string&)")); + } + return __ret; + } + + public: + +#endif + + result_type + min() const + { return std::numeric_limits<result_type>::min(); } + + result_type + max() const + { return std::numeric_limits<result_type>::max(); } + + double + entropy() const + { return 0.0; } + + result_type + operator()() + { +#ifdef _GLIBCXX_USE_RANDOM_TR1 + result_type __ret; + std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type), + 1, _M_file); + return __ret; +#else + return _M_mt(); +#endif + } + + private: + random_device(const random_device&); + void operator=(const random_device&); + +#ifdef _GLIBCXX_USE_RANDOM_TR1 + FILE* _M_file; +#else + mt19937 _M_mt; +#endif + }; + + /* @} */ // group tr1_random_generators + + /** + * @addtogroup tr1_random_distributions Random Number Distributions + * @ingroup tr1_random + * @{ + */ + + /** + * @addtogroup tr1_random_distributions_discrete Discrete Distributions + * @ingroup tr1_random_distributions + * @{ + */ + + /** + * @brief Uniform discrete distribution for random numbers. + * A discrete random distribution on the range @f$[min, max]@f$ with equal + * probability throughout the range. + */ + template<typename _IntType = int> + class uniform_int + { + __glibcxx_class_requires(_IntType, _IntegerConcept) + + public: + /** The type of the parameters of the distribution. */ + typedef _IntType input_type; + /** The type of the range of the distribution. */ + typedef _IntType result_type; + + public: + /** + * Constructs a uniform distribution object. + */ + explicit + uniform_int(_IntType __min = 0, _IntType __max = 9) + : _M_min(__min), _M_max(__max) + { + _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max); + } + + /** + * Gets the inclusive lower bound of the distribution range. + */ + result_type + min() const + { return _M_min; } + + /** + * Gets the inclusive upper bound of the distribution range. + */ + result_type + max() const + { return _M_max; } + + /** + * Resets the distribution state. + * + * Does nothing for the uniform integer distribution. + */ + void + reset() { } + + /** + * Gets a uniformly distributed random number in the range + * @f$(min, max)@f$. + */ + template<typename _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { + typedef typename _UniformRandomNumberGenerator::result_type + _UResult_type; + return _M_call(__urng, _M_min, _M_max, + typename is_integral<_UResult_type>::type()); + } + + /** + * Gets a uniform random number in the range @f$[0, n)@f$. + * + * This function is aimed at use with std::random_shuffle. + */ + template<typename _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng, result_type __n) + { + typedef typename _UniformRandomNumberGenerator::result_type + _UResult_type; + return _M_call(__urng, 0, __n - 1, + typename is_integral<_UResult_type>::type()); + } + + /** + * Inserts a %uniform_int random number distribution @p __x into the + * output stream @p os. + * + * @param __os An output stream. + * @param __x A %uniform_int random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const uniform_int<_IntType1>& __x); + + /** + * Extracts a %unform_int random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %uniform_int random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _IntType1, typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + uniform_int<_IntType1>& __x); + + private: + template<typename _UniformRandomNumberGenerator> + result_type + _M_call(_UniformRandomNumberGenerator& __urng, + result_type __min, result_type __max, true_type) + { return result_type(__urng() % (__max - __min + 1)) + __min; } + + template<typename _UniformRandomNumberGenerator> + result_type + _M_call(_UniformRandomNumberGenerator& __urng, + result_type __min, result_type __max, false_type) + { + return result_type((__urng() - __urng.min()) + / (__urng.max() - __urng.min()) + * (__max - __min + 1)) + __min; + } + + _IntType _M_min; + _IntType _M_max; + }; + + + /** + * @brief A Bernoulli random number distribution. + * + * Generates a sequence of true and false values with likelihood @f$ p @f$ + * that true will come up and @f$ (1 - p) @f$ that false will appear. + */ + class bernoulli_distribution + { + public: + typedef int input_type; + typedef bool result_type; + + public: + /** + * Constructs a Bernoulli distribution with likelihood @p p. + * + * @param __p [IN] The likelihood of a true result being returned. Must + * be in the interval @f$ [0, 1] @f$. + */ + explicit + bernoulli_distribution(double __p = 0.5) + : _M_p(__p) + { + _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0)); + } + + /** + * Gets the @p p parameter of the distribution. + */ + double + p() const + { return _M_p; } + + /** + * Resets the distribution state. + * + * Does nothing for a bernoulli distribution. + */ + void + reset() { } + + /** + * Gets the next value in the Bernoullian sequence. + */ + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { + if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min())) + return true; + return false; + } + + /** + * Inserts a %bernoulli_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %bernoulli_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bernoulli_distribution& __x); + + /** + * Extracts a %bernoulli_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %bernoulli_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + bernoulli_distribution& __x) + { return __is >> __x._M_p; } + + private: + double _M_p; + }; + + + /** + * @brief A discrete geometric random number distribution. + * + * The formula for the geometric probability mass function is + * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the + * distribution. + */ + template<typename _IntType = int, typename _RealType = double> + class geometric_distribution + { + public: + // types + typedef _RealType input_type; + typedef _IntType result_type; + + // constructors and member function + explicit + geometric_distribution(const _RealType& __p = _RealType(0.5)) + : _M_p(__p) + { + _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0)); + _M_initialize(); + } + + /** + * Gets the distribution parameter @p p. + */ + _RealType + p() const + { return _M_p; } + + void + reset() { } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %geometric_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %geometric_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const geometric_distribution<_IntType1, _RealType1>& __x); + + /** + * Extracts a %geometric_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %geometric_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + geometric_distribution& __x) + { + __is >> __x._M_p; + __x._M_initialize(); + return __is; + } + + private: + void + _M_initialize() + { _M_log_p = std::log(_M_p); } + + _RealType _M_p; + _RealType _M_log_p; + }; + + + template<typename _RealType> + class normal_distribution; + + /** + * @brief A discrete Poisson random number distribution. + * + * The formula for the poisson probability mass function is + * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the + * parameter of the distribution. + */ + template<typename _IntType = int, typename _RealType = double> + class poisson_distribution + { + public: + // types + typedef _RealType input_type; + typedef _IntType result_type; + + // constructors and member function + explicit + poisson_distribution(const _RealType& __mean = _RealType(1)) + : _M_mean(__mean), _M_nd() + { + _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0); + _M_initialize(); + } + + /** + * Gets the distribution parameter @p mean. + */ + _RealType + mean() const + { return _M_mean; } + + void + reset() + { _M_nd.reset(); } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %poisson_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %poisson_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const poisson_distribution<_IntType1, _RealType1>& __x); + + /** + * Extracts a %poisson_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %poisson_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + poisson_distribution<_IntType1, _RealType1>& __x); + + private: + void + _M_initialize(); + + // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. + normal_distribution<_RealType> _M_nd; + + _RealType _M_mean; + + // Hosts either log(mean) or the threshold of the simple method. + _RealType _M_lm_thr; +#if _GLIBCXX_USE_C99_MATH_TR1 + _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb; +#endif + }; + + + /** + * @brief A discrete binomial random number distribution. + * + * The formula for the binomial probability mass function is + * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$ + * and @f$ p @f$ are the parameters of the distribution. + */ + template<typename _IntType = int, typename _RealType = double> + class binomial_distribution + { + public: + // types + typedef _RealType input_type; + typedef _IntType result_type; + + // constructors and member function + explicit + binomial_distribution(_IntType __t = 1, + const _RealType& __p = _RealType(0.5)) + : _M_t(__t), _M_p(__p), _M_nd() + { + _GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0)); + _M_initialize(); + } + + /** + * Gets the distribution @p t parameter. + */ + _IntType + t() const + { return _M_t; } + + /** + * Gets the distribution @p p parameter. + */ + _RealType + p() const + { return _M_p; } + + void + reset() + { _M_nd.reset(); } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %binomial_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %binomial_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const binomial_distribution<_IntType1, _RealType1>& __x); + + /** + * Extracts a %binomial_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %binomial_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + binomial_distribution<_IntType1, _RealType1>& __x); + + private: + void + _M_initialize(); + + template<class _UniformRandomNumberGenerator> + result_type + _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t); + + // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. + normal_distribution<_RealType> _M_nd; + + _RealType _M_q; +#if _GLIBCXX_USE_C99_MATH_TR1 + _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c, + _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p; +#endif + _RealType _M_p; + _IntType _M_t; + + bool _M_easy; + }; + + /* @} */ // group tr1_random_distributions_discrete + + /** + * @addtogroup tr1_random_distributions_continuous Continuous Distributions + * @ingroup tr1_random_distributions + * @{ + */ + + /** + * @brief Uniform continuous distribution for random numbers. + * + * A continuous random distribution on the range [min, max) with equal + * probability throughout the range. The URNG should be real-valued and + * deliver number in the range [0, 1). + */ + template<typename _RealType = double> + class uniform_real + { + public: + // types + typedef _RealType input_type; + typedef _RealType result_type; + + public: + /** + * Constructs a uniform_real object. + * + * @param __min [IN] The lower bound of the distribution. + * @param __max [IN] The upper bound of the distribution. + */ + explicit + uniform_real(_RealType __min = _RealType(0), + _RealType __max = _RealType(1)) + : _M_min(__min), _M_max(__max) + { + _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max); + } + + result_type + min() const + { return _M_min; } + + result_type + max() const + { return _M_max; } + + void + reset() { } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { return (__urng() * (_M_max - _M_min)) + _M_min; } + + /** + * Inserts a %uniform_real random number distribution @p __x into the + * output stream @p __os. + * + * @param __os An output stream. + * @param __x A %uniform_real random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const uniform_real<_RealType1>& __x); + + /** + * Extracts a %unform_real random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %uniform_real random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + uniform_real<_RealType1>& __x); + + private: + _RealType _M_min; + _RealType _M_max; + }; + + + /** + * @brief An exponential continuous distribution for random numbers. + * + * The formula for the exponential probability mass function is + * @f$ p(x) = \lambda e^{-\lambda x} @f$. + * + * <table border=1 cellpadding=10 cellspacing=0> + * <caption align=top>Distribution Statistics</caption> + * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr> + * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr> + * <tr><td>Mode</td><td>@f$ zero @f$</td></tr> + * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr> + * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr> + * </table> + */ + template<typename _RealType = double> + class exponential_distribution + { + public: + // types + typedef _RealType input_type; + typedef _RealType result_type; + + public: + /** + * Constructs an exponential distribution with inverse scale parameter + * @f$ \lambda @f$. + */ + explicit + exponential_distribution(const result_type& __lambda = result_type(1)) + : _M_lambda(__lambda) + { + _GLIBCXX_DEBUG_ASSERT(_M_lambda > 0); + } + + /** + * Gets the inverse scale parameter of the distribution. + */ + _RealType + lambda() const + { return _M_lambda; } + + /** + * Resets the distribution. + * + * Has no effect on exponential distributions. + */ + void + reset() { } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { return -std::log(__urng()) / _M_lambda; } + + /** + * Inserts a %exponential_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %exponential_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const exponential_distribution<_RealType1>& __x); + + /** + * Extracts a %exponential_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %exponential_distribution random number + * generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + exponential_distribution& __x) + { return __is >> __x._M_lambda; } + + private: + result_type _M_lambda; + }; + + + /** + * @brief A normal continuous distribution for random numbers. + * + * The formula for the normal probability mass function is + * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}} + * e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$. + */ + template<typename _RealType = double> + class normal_distribution + { + public: + // types + typedef _RealType input_type; + typedef _RealType result_type; + + public: + /** + * Constructs a normal distribution with parameters @f$ mean @f$ and + * @f$ \sigma @f$. + */ + explicit + normal_distribution(const result_type& __mean = result_type(0), + const result_type& __sigma = result_type(1)) + : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false) + { + _GLIBCXX_DEBUG_ASSERT(_M_sigma > 0); + } + + /** + * Gets the mean of the distribution. + */ + _RealType + mean() const + { return _M_mean; } + + /** + * Gets the @f$ \sigma @f$ of the distribution. + */ + _RealType + sigma() const + { return _M_sigma; } + + /** + * Resets the distribution. + */ + void + reset() + { _M_saved_available = false; } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %normal_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %normal_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const normal_distribution<_RealType1>& __x); + + /** + * Extracts a %normal_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %normal_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + normal_distribution<_RealType1>& __x); + + private: + result_type _M_mean; + result_type _M_sigma; + result_type _M_saved; + bool _M_saved_available; + }; + + + /** + * @brief A gamma continuous distribution for random numbers. + * + * The formula for the gamma probability mass function is + * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$. + */ + template<typename _RealType = double> + class gamma_distribution + { + public: + // types + typedef _RealType input_type; + typedef _RealType result_type; + + public: + /** + * Constructs a gamma distribution with parameters @f$ \alpha @f$. + */ + explicit + gamma_distribution(const result_type& __alpha_val = result_type(1)) + : _M_alpha(__alpha_val) + { + _GLIBCXX_DEBUG_ASSERT(_M_alpha > 0); + _M_initialize(); + } + + /** + * Gets the @f$ \alpha @f$ of the distribution. + */ + _RealType + alpha() const + { return _M_alpha; } + + /** + * Resets the distribution. + */ + void + reset() { } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %gamma_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %gamma_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const gamma_distribution<_RealType1>& __x); + + /** + * Extracts a %gamma_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %gamma_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + gamma_distribution& __x) + { + __is >> __x._M_alpha; + __x._M_initialize(); + return __is; + } + + private: + void + _M_initialize(); + + result_type _M_alpha; + + // Hosts either lambda of GB or d of modified Vaduva's. + result_type _M_l_d; + }; + + /* @} */ // group tr1_random_distributions_continuous + /* @} */ // group tr1_random_distributions + /* @} */ // group tr1_random + +_GLIBCXX_END_NAMESPACE +} + +#include <tr1/random.tcc> + +#endif // _TR1_RANDOM diff --git a/libstdc++/include/tr1/random.tcc b/libstdc++/include/tr1/random.tcc new file mode 100644 index 0000000..3962816 --- /dev/null +++ b/libstdc++/include/tr1/random.tcc @@ -0,0 +1,1547 @@ +// random number generation (out of line) -*- C++ -*- + +// Copyright (C) 2006, 2007 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. + +/** @file tr1/random.tcc + * This is a TR1 C++ Library header. + */ + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + /* + * (Further) implementation-space details. + */ + namespace __detail + { + // General case for x = (ax + c) mod m -- use Schrage's algorithm to avoid + // integer overflow. + // + // Because a and c are compile-time integral constants the compiler kindly + // elides any unreachable paths. + // + // Preconditions: a > 0, m > 0. + // + template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool> + struct _Mod + { + static _Tp + __calc(_Tp __x) + { + if (__a == 1) + __x %= __m; + else + { + static const _Tp __q = __m / __a; + static const _Tp __r = __m % __a; + + _Tp __t1 = __a * (__x % __q); + _Tp __t2 = __r * (__x / __q); + if (__t1 >= __t2) + __x = __t1 - __t2; + else + __x = __m - __t2 + __t1; + } + + if (__c != 0) + { + const _Tp __d = __m - __x; + if (__d > __c) + __x += __c; + else + __x = __c - __d; + } + return __x; + } + }; + + // Special case for m == 0 -- use unsigned integer overflow as modulo + // operator. + template<typename _Tp, _Tp __a, _Tp __c, _Tp __m> + struct _Mod<_Tp, __a, __c, __m, true> + { + static _Tp + __calc(_Tp __x) + { return __a * __x + __c; } + }; + } // namespace __detail + + /** + * Seeds the LCR with integral value @p __x0, adjusted so that the + * ring identity is never a member of the convergence set. + */ + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + void + linear_congruential<_UIntType, __a, __c, __m>:: + seed(unsigned long __x0) + { + if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) + && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0)) + _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1); + else + _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0); + } + + /** + * Seeds the LCR engine with a value generated by @p __g. + */ + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + template<class _Gen> + void + linear_congruential<_UIntType, __a, __c, __m>:: + seed(_Gen& __g, false_type) + { + _UIntType __x0 = __g(); + if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) + && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0)) + _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1); + else + _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0); + } + + /** + * Gets the next generated value in sequence. + */ + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + typename linear_congruential<_UIntType, __a, __c, __m>::result_type + linear_congruential<_UIntType, __a, __c, __m>:: + operator()() + { + _M_x = __detail::__mod<_UIntType, __a, __c, __m>(_M_x); + return _M_x; + } + + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const linear_congruential<_UIntType, __a, __c, __m>& __lcr) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__os.widen(' ')); + + __os << __lcr._M_x; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + linear_congruential<_UIntType, __a, __c, __m>& __lcr) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec); + + __is >> __lcr._M_x; + + __is.flags(__flags); + return __is; + } + + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + void + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>:: + seed(unsigned long __value) + { + _M_x[0] = __detail::__mod<_UIntType, 1, 0, + __detail::_Shift<_UIntType, __w>::__value>(__value); + + for (int __i = 1; __i < state_size; ++__i) + { + _UIntType __x = _M_x[__i - 1]; + __x ^= __x >> (__w - 2); + __x *= 1812433253ul; + __x += __i; + _M_x[__i] = __detail::__mod<_UIntType, 1, 0, + __detail::_Shift<_UIntType, __w>::__value>(__x); + } + _M_p = state_size; + } + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + template<class _Gen> + void + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>:: + seed(_Gen& __gen, false_type) + { + for (int __i = 0; __i < state_size; ++__i) + _M_x[__i] = __detail::__mod<_UIntType, 1, 0, + __detail::_Shift<_UIntType, __w>::__value>(__gen()); + _M_p = state_size; + } + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + typename + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::result_type + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>:: + operator()() + { + // Reload the vector - cost is O(n) amortized over n calls. + if (_M_p >= state_size) + { + const _UIntType __upper_mask = (~_UIntType()) << __r; + const _UIntType __lower_mask = ~__upper_mask; + + for (int __k = 0; __k < (__n - __m); ++__k) + { + _UIntType __y = ((_M_x[__k] & __upper_mask) + | (_M_x[__k + 1] & __lower_mask)); + _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1) + ^ ((__y & 0x01) ? __a : 0)); + } + + for (int __k = (__n - __m); __k < (__n - 1); ++__k) + { + _UIntType __y = ((_M_x[__k] & __upper_mask) + | (_M_x[__k + 1] & __lower_mask)); + _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1) + ^ ((__y & 0x01) ? __a : 0)); + } + + _UIntType __y = ((_M_x[__n - 1] & __upper_mask) + | (_M_x[0] & __lower_mask)); + _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1) + ^ ((__y & 0x01) ? __a : 0)); + _M_p = 0; + } + + // Calculate o(x(i)). + result_type __z = _M_x[_M_p++]; + __z ^= (__z >> __u); + __z ^= (__z << __s) & __b; + __z ^= (__z << __t) & __c; + __z ^= (__z >> __l); + + return __z; + } + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, _UIntType __b, int __t, + _UIntType __c, int __l, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const mersenne_twister<_UIntType, __w, __n, __m, + __r, __a, __u, __s, __b, __t, __c, __l>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__space); + + for (int __i = 0; __i < __n - 1; ++__i) + __os << __x._M_x[__i] << __space; + __os << __x._M_x[__n - 1]; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, _UIntType __b, int __t, + _UIntType __c, int __l, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + mersenne_twister<_UIntType, __w, __n, __m, + __r, __a, __u, __s, __b, __t, __c, __l>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + for (int __i = 0; __i < __n; ++__i) + __is >> __x._M_x[__i]; + + __is.flags(__flags); + return __is; + } + + + template<typename _IntType, _IntType __m, int __s, int __r> + void + subtract_with_carry<_IntType, __m, __s, __r>:: + seed(unsigned long __value) + { + if (__value == 0) + __value = 19780503; + + std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563> + __lcg(__value); + + for (int __i = 0; __i < long_lag; ++__i) + _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__lcg()); + + _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; + _M_p = 0; + } + + template<typename _IntType, _IntType __m, int __s, int __r> + template<class _Gen> + void + subtract_with_carry<_IntType, __m, __s, __r>:: + seed(_Gen& __gen, false_type) + { + const int __n = (std::numeric_limits<_UIntType>::digits + 31) / 32; + + for (int __i = 0; __i < long_lag; ++__i) + { + _UIntType __tmp = 0; + _UIntType __factor = 1; + for (int __j = 0; __j < __n; ++__j) + { + __tmp += __detail::__mod<__detail::_UInt32Type, 1, 0, 0> + (__gen()) * __factor; + __factor *= __detail::_Shift<_UIntType, 32>::__value; + } + _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__tmp); + } + _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; + _M_p = 0; + } + + template<typename _IntType, _IntType __m, int __s, int __r> + typename subtract_with_carry<_IntType, __m, __s, __r>::result_type + subtract_with_carry<_IntType, __m, __s, __r>:: + operator()() + { + // Derive short lag index from current index. + int __ps = _M_p - short_lag; + if (__ps < 0) + __ps += long_lag; + + // Calculate new x(i) without overflow or division. + // NB: Thanks to the requirements for _IntType, _M_x[_M_p] + _M_carry + // cannot overflow. + _UIntType __xi; + if (_M_x[__ps] >= _M_x[_M_p] + _M_carry) + { + __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry; + _M_carry = 0; + } + else + { + __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps]; + _M_carry = 1; + } + _M_x[_M_p] = __xi; + + // Adjust current index to loop around in ring buffer. + if (++_M_p >= long_lag) + _M_p = 0; + + return __xi; + } + + template<typename _IntType, _IntType __m, int __s, int __r, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry<_IntType, __m, __s, __r>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__space); + + for (int __i = 0; __i < __r; ++__i) + __os << __x._M_x[__i] << __space; + __os << __x._M_carry; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<typename _IntType, _IntType __m, int __s, int __r, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + subtract_with_carry<_IntType, __m, __s, __r>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + for (int __i = 0; __i < __r; ++__i) + __is >> __x._M_x[__i]; + __is >> __x._M_carry; + + __is.flags(__flags); + return __is; + } + + + template<typename _RealType, int __w, int __s, int __r> + void + subtract_with_carry_01<_RealType, __w, __s, __r>:: + _M_initialize_npows() + { + for (int __j = 0; __j < __n; ++__j) +#if _GLIBCXX_USE_C99_MATH_TR1 + _M_npows[__j] = std::tr1::ldexp(_RealType(1), -__w + __j * 32); +#else + _M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32); +#endif + } + + template<typename _RealType, int __w, int __s, int __r> + void + subtract_with_carry_01<_RealType, __w, __s, __r>:: + seed(unsigned long __value) + { + if (__value == 0) + __value = 19780503; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 512. Seeding subtract_with_carry_01 from a single unsigned long. + std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563> + __lcg(__value); + + this->seed(__lcg); + } + + template<typename _RealType, int __w, int __s, int __r> + template<class _Gen> + void + subtract_with_carry_01<_RealType, __w, __s, __r>:: + seed(_Gen& __gen, false_type) + { + for (int __i = 0; __i < long_lag; ++__i) + { + for (int __j = 0; __j < __n - 1; ++__j) + _M_x[__i][__j] = __detail::__mod<_UInt32Type, 1, 0, 0>(__gen()); + _M_x[__i][__n - 1] = __detail::__mod<_UInt32Type, 1, 0, + __detail::_Shift<_UInt32Type, __w % 32>::__value>(__gen()); + } + + _M_carry = 1; + for (int __j = 0; __j < __n; ++__j) + if (_M_x[long_lag - 1][__j] != 0) + { + _M_carry = 0; + break; + } + + _M_p = 0; + } + + template<typename _RealType, int __w, int __s, int __r> + typename subtract_with_carry_01<_RealType, __w, __s, __r>::result_type + subtract_with_carry_01<_RealType, __w, __s, __r>:: + operator()() + { + // Derive short lag index from current index. + int __ps = _M_p - short_lag; + if (__ps < 0) + __ps += long_lag; + + _UInt32Type __new_carry; + for (int __j = 0; __j < __n - 1; ++__j) + { + if (_M_x[__ps][__j] > _M_x[_M_p][__j] + || (_M_x[__ps][__j] == _M_x[_M_p][__j] && _M_carry == 0)) + __new_carry = 0; + else + __new_carry = 1; + + _M_x[_M_p][__j] = _M_x[__ps][__j] - _M_x[_M_p][__j] - _M_carry; + _M_carry = __new_carry; + } + + if (_M_x[__ps][__n - 1] > _M_x[_M_p][__n - 1] + || (_M_x[__ps][__n - 1] == _M_x[_M_p][__n - 1] && _M_carry == 0)) + __new_carry = 0; + else + __new_carry = 1; + + _M_x[_M_p][__n - 1] = __detail::__mod<_UInt32Type, 1, 0, + __detail::_Shift<_UInt32Type, __w % 32>::__value> + (_M_x[__ps][__n - 1] - _M_x[_M_p][__n - 1] - _M_carry); + _M_carry = __new_carry; + + result_type __ret = 0.0; + for (int __j = 0; __j < __n; ++__j) + __ret += _M_x[_M_p][__j] * _M_npows[__j]; + + // Adjust current index to loop around in ring buffer. + if (++_M_p >= long_lag) + _M_p = 0; + + return __ret; + } + + template<typename _RealType, int __w, int __s, int __r, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry_01<_RealType, __w, __s, __r>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__space); + + for (int __i = 0; __i < __r; ++__i) + for (int __j = 0; __j < __x.__n; ++__j) + __os << __x._M_x[__i][__j] << __space; + __os << __x._M_carry; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<typename _RealType, int __w, int __s, int __r, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + subtract_with_carry_01<_RealType, __w, __s, __r>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + for (int __i = 0; __i < __r; ++__i) + for (int __j = 0; __j < __x.__n; ++__j) + __is >> __x._M_x[__i][__j]; + __is >> __x._M_carry; + + __is.flags(__flags); + return __is; + } + + + template<class _UniformRandomNumberGenerator, int __p, int __r> + typename discard_block<_UniformRandomNumberGenerator, + __p, __r>::result_type + discard_block<_UniformRandomNumberGenerator, __p, __r>:: + operator()() + { + if (_M_n >= used_block) + { + while (_M_n < block_size) + { + _M_b(); + ++_M_n; + } + _M_n = 0; + } + ++_M_n; + return _M_b(); + } + + template<class _UniformRandomNumberGenerator, int __p, int __r, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const discard_block<_UniformRandomNumberGenerator, + __p, __r>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed + | __ios_base::left); + __os.fill(__space); + + __os << __x._M_b << __space << __x._M_n; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<class _UniformRandomNumberGenerator, int __p, int __r, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + discard_block<_UniformRandomNumberGenerator, __p, __r>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + __is >> __x._M_b >> __x._M_n; + + __is.flags(__flags); + return __is; + } + + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2> + void + xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>:: + _M_initialize_max() + { + const int __w = std::numeric_limits<result_type>::digits; + + const result_type __m1 = + std::min(result_type(_M_b1.max() - _M_b1.min()), + __detail::_Shift<result_type, __w - __s1>::__value - 1); + + const result_type __m2 = + std::min(result_type(_M_b2.max() - _M_b2.min()), + __detail::_Shift<result_type, __w - __s2>::__value - 1); + + // NB: In TR1 s1 is not required to be >= s2. + if (__s1 < __s2) + _M_max = _M_initialize_max_aux(__m2, __m1, __s2 - __s1) << __s1; + else + _M_max = _M_initialize_max_aux(__m1, __m2, __s1 - __s2) << __s2; + } + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2> + typename xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>::result_type + xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>:: + _M_initialize_max_aux(result_type __a, result_type __b, int __d) + { + const result_type __two2d = result_type(1) << __d; + const result_type __c = __a * __two2d; + + if (__a == 0 || __b < __two2d) + return __c + __b; + + const result_type __t = std::max(__c, __b); + const result_type __u = std::min(__c, __b); + + result_type __ub = __u; + result_type __p; + for (__p = 0; __ub != 1; __ub >>= 1) + ++__p; + + const result_type __two2p = result_type(1) << __p; + const result_type __k = __t / __two2p; + + if (__k & 1) + return (__k + 1) * __two2p - 1; + + if (__c >= __b) + return (__k + 1) * __two2p + _M_initialize_max_aux((__t % __two2p) + / __two2d, + __u % __two2p, __d); + else + return (__k + 1) * __two2p + _M_initialize_max_aux((__u % __two2p) + / __two2d, + __t % __two2p, __d); + } + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__space); + + __os << __x.base1() << __space << __x.base2(); + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::skipws); + + __is >> __x._M_b1 >> __x._M_b2; + + __is.flags(__flags); + return __is; + } + + + template<typename _IntType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const uniform_int<_IntType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + + __os << __x.min() << __space << __x.max(); + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<typename _IntType, typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + uniform_int<_IntType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + __is >> __x._M_min >> __x._M_max; + + __is.flags(__flags); + return __is; + } + + + template<typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bernoulli_distribution& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__os.widen(' ')); + __os.precision(__gnu_cxx::__numeric_traits<double>::__max_digits10); + + __os << __x.p(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + + template<typename _IntType, typename _RealType> + template<class _UniformRandomNumberGenerator> + typename geometric_distribution<_IntType, _RealType>::result_type + geometric_distribution<_IntType, _RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { + // About the epsilon thing see this thread: + // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html + const _RealType __naf = + (1 - std::numeric_limits<_RealType>::epsilon()) / 2; + // The largest _RealType convertible to _IntType. + const _RealType __thr = + std::numeric_limits<_IntType>::max() + __naf; + + _RealType __cand; + do + __cand = std::ceil(std::log(__urng()) / _M_log_p); + while (__cand >= __thr); + + return result_type(__cand + __naf); + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const geometric_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__os.widen(' ')); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.p(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + + template<typename _IntType, typename _RealType> + void + poisson_distribution<_IntType, _RealType>:: + _M_initialize() + { +#if _GLIBCXX_USE_C99_MATH_TR1 + if (_M_mean >= 12) + { + const _RealType __m = std::floor(_M_mean); + _M_lm_thr = std::log(_M_mean); + _M_lfm = std::tr1::lgamma(__m + 1); + _M_sm = std::sqrt(__m); + + const _RealType __pi_4 = 0.7853981633974483096156608458198757L; + const _RealType __dx = std::sqrt(2 * __m * std::log(32 * __m + / __pi_4)); + _M_d = std::tr1::round(std::max(_RealType(6), + std::min(__m, __dx))); + const _RealType __cx = 2 * __m + _M_d; + _M_scx = std::sqrt(__cx / 2); + _M_1cx = 1 / __cx; + + _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx); + _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) / _M_d; + } + else +#endif + _M_lm_thr = std::exp(-_M_mean); + } + + /** + * A rejection algorithm when mean >= 12 and a simple method based + * upon the multiplication of uniform random variates otherwise. + * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 + * is defined. + * + * Reference: + * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag, + * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!). + */ + template<typename _IntType, typename _RealType> + template<class _UniformRandomNumberGenerator> + typename poisson_distribution<_IntType, _RealType>::result_type + poisson_distribution<_IntType, _RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { +#if _GLIBCXX_USE_C99_MATH_TR1 + if (_M_mean >= 12) + { + _RealType __x; + + // See comments above... + const _RealType __naf = + (1 - std::numeric_limits<_RealType>::epsilon()) / 2; + const _RealType __thr = + std::numeric_limits<_IntType>::max() + __naf; + + const _RealType __m = std::floor(_M_mean); + // sqrt(pi / 2) + const _RealType __spi_2 = 1.2533141373155002512078826424055226L; + const _RealType __c1 = _M_sm * __spi_2; + const _RealType __c2 = _M_c2b + __c1; + const _RealType __c3 = __c2 + 1; + const _RealType __c4 = __c3 + 1; + // e^(1 / 78) + const _RealType __e178 = 1.0129030479320018583185514777512983L; + const _RealType __c5 = __c4 + __e178; + const _RealType __c = _M_cb + __c5; + const _RealType __2cx = 2 * (2 * __m + _M_d); + + bool __reject = true; + do + { + const _RealType __u = __c * __urng(); + const _RealType __e = -std::log(__urng()); + + _RealType __w = 0.0; + + if (__u <= __c1) + { + const _RealType __n = _M_nd(__urng); + const _RealType __y = -std::abs(__n) * _M_sm - 1; + __x = std::floor(__y); + __w = -__n * __n / 2; + if (__x < -__m) + continue; + } + else if (__u <= __c2) + { + const _RealType __n = _M_nd(__urng); + const _RealType __y = 1 + std::abs(__n) * _M_scx; + __x = std::ceil(__y); + __w = __y * (2 - __y) * _M_1cx; + if (__x > _M_d) + continue; + } + else if (__u <= __c3) + // NB: This case not in the book, nor in the Errata, + // but should be ok... + __x = -1; + else if (__u <= __c4) + __x = 0; + else if (__u <= __c5) + __x = 1; + else + { + const _RealType __v = -std::log(__urng()); + const _RealType __y = _M_d + __v * __2cx / _M_d; + __x = std::ceil(__y); + __w = -_M_d * _M_1cx * (1 + __y / 2); + } + + __reject = (__w - __e - __x * _M_lm_thr + > _M_lfm - std::tr1::lgamma(__x + __m + 1)); + + __reject |= __x + __m >= __thr; + + } while (__reject); + + return result_type(__x + __m + __naf); + } + else +#endif + { + _IntType __x = 0; + _RealType __prod = 1.0; + + do + { + __prod *= __urng(); + __x += 1; + } + while (__prod > _M_lm_thr); + + return __x - 1; + } + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const poisson_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.mean() << __space << __x._M_nd; + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + poisson_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::skipws); + + __is >> __x._M_mean >> __x._M_nd; + __x._M_initialize(); + + __is.flags(__flags); + return __is; + } + + + template<typename _IntType, typename _RealType> + void + binomial_distribution<_IntType, _RealType>:: + _M_initialize() + { + const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; + + _M_easy = true; + +#if _GLIBCXX_USE_C99_MATH_TR1 + if (_M_t * __p12 >= 8) + { + _M_easy = false; + const _RealType __np = std::floor(_M_t * __p12); + const _RealType __pa = __np / _M_t; + const _RealType __1p = 1 - __pa; + + const _RealType __pi_4 = 0.7853981633974483096156608458198757L; + const _RealType __d1x = + std::sqrt(__np * __1p * std::log(32 * __np + / (81 * __pi_4 * __1p))); + _M_d1 = std::tr1::round(std::max(_RealType(1), __d1x)); + const _RealType __d2x = + std::sqrt(__np * __1p * std::log(32 * _M_t * __1p + / (__pi_4 * __pa))); + _M_d2 = std::tr1::round(std::max(_RealType(1), __d2x)); + + // sqrt(pi / 2) + const _RealType __spi_2 = 1.2533141373155002512078826424055226L; + _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np)); + _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p)); + _M_c = 2 * _M_d1 / __np; + _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2; + const _RealType __a12 = _M_a1 + _M_s2 * __spi_2; + const _RealType __s1s = _M_s1 * _M_s1; + _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p)) + * 2 * __s1s / _M_d1 + * std::exp(-_M_d1 * _M_d1 / (2 * __s1s))); + const _RealType __s2s = _M_s2 * _M_s2; + _M_s = (_M_a123 + 2 * __s2s / _M_d2 + * std::exp(-_M_d2 * _M_d2 / (2 * __s2s))); + _M_lf = (std::tr1::lgamma(__np + 1) + + std::tr1::lgamma(_M_t - __np + 1)); + _M_lp1p = std::log(__pa / __1p); + + _M_q = -std::log(1 - (__p12 - __pa) / __1p); + } + else +#endif + _M_q = -std::log(1 - __p12); + } + + template<typename _IntType, typename _RealType> + template<class _UniformRandomNumberGenerator> + typename binomial_distribution<_IntType, _RealType>::result_type + binomial_distribution<_IntType, _RealType>:: + _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t) + { + _IntType __x = 0; + _RealType __sum = 0; + + do + { + const _RealType __e = -std::log(__urng()); + __sum += __e / (__t - __x); + __x += 1; + } + while (__sum <= _M_q); + + return __x - 1; + } + + /** + * A rejection algorithm when t * p >= 8 and a simple waiting time + * method - the second in the referenced book - otherwise. + * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 + * is defined. + * + * Reference: + * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag, + * New York, 1986, Ch. X, Sect. 4 (+ Errata!). + */ + template<typename _IntType, typename _RealType> + template<class _UniformRandomNumberGenerator> + typename binomial_distribution<_IntType, _RealType>::result_type + binomial_distribution<_IntType, _RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { + result_type __ret; + const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; + +#if _GLIBCXX_USE_C99_MATH_TR1 + if (!_M_easy) + { + _RealType __x; + + // See comments above... + const _RealType __naf = + (1 - std::numeric_limits<_RealType>::epsilon()) / 2; + const _RealType __thr = + std::numeric_limits<_IntType>::max() + __naf; + + const _RealType __np = std::floor(_M_t * __p12); + const _RealType __pa = __np / _M_t; + + // sqrt(pi / 2) + const _RealType __spi_2 = 1.2533141373155002512078826424055226L; + const _RealType __a1 = _M_a1; + const _RealType __a12 = __a1 + _M_s2 * __spi_2; + const _RealType __a123 = _M_a123; + const _RealType __s1s = _M_s1 * _M_s1; + const _RealType __s2s = _M_s2 * _M_s2; + + bool __reject; + do + { + const _RealType __u = _M_s * __urng(); + + _RealType __v; + + if (__u <= __a1) + { + const _RealType __n = _M_nd(__urng); + const _RealType __y = _M_s1 * std::abs(__n); + __reject = __y >= _M_d1; + if (!__reject) + { + const _RealType __e = -std::log(__urng()); + __x = std::floor(__y); + __v = -__e - __n * __n / 2 + _M_c; + } + } + else if (__u <= __a12) + { + const _RealType __n = _M_nd(__urng); + const _RealType __y = _M_s2 * std::abs(__n); + __reject = __y >= _M_d2; + if (!__reject) + { + const _RealType __e = -std::log(__urng()); + __x = std::floor(-__y); + __v = -__e - __n * __n / 2; + } + } + else if (__u <= __a123) + { + const _RealType __e1 = -std::log(__urng()); + const _RealType __e2 = -std::log(__urng()); + + const _RealType __y = _M_d1 + 2 * __s1s * __e1 / _M_d1; + __x = std::floor(__y); + __v = (-__e2 + _M_d1 * (1 / (_M_t - __np) + -__y / (2 * __s1s))); + __reject = false; + } + else + { + const _RealType __e1 = -std::log(__urng()); + const _RealType __e2 = -std::log(__urng()); + + const _RealType __y = _M_d2 + 2 * __s2s * __e1 / _M_d2; + __x = std::floor(-__y); + __v = -__e2 - _M_d2 * __y / (2 * __s2s); + __reject = false; + } + + __reject = __reject || __x < -__np || __x > _M_t - __np; + if (!__reject) + { + const _RealType __lfx = + std::tr1::lgamma(__np + __x + 1) + + std::tr1::lgamma(_M_t - (__np + __x) + 1); + __reject = __v > _M_lf - __lfx + __x * _M_lp1p; + } + + __reject |= __x + __np >= __thr; + } + while (__reject); + + __x += __np + __naf; + + const _IntType __z = _M_waiting(__urng, _M_t - _IntType(__x)); + __ret = _IntType(__x) + __z; + } + else +#endif + __ret = _M_waiting(__urng, _M_t); + + if (__p12 != _M_p) + __ret = _M_t - __ret; + return __ret; + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const binomial_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.t() << __space << __x.p() + << __space << __x._M_nd; + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + binomial_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + __is >> __x._M_t >> __x._M_p >> __x._M_nd; + __x._M_initialize(); + + __is.flags(__flags); + return __is; + } + + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const uniform_real<_RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.min() << __space << __x.max(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + uniform_real<_RealType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::skipws); + + __is >> __x._M_min >> __x._M_max; + + __is.flags(__flags); + return __is; + } + + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const exponential_distribution<_RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__os.widen(' ')); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.lambda(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + + /** + * Polar method due to Marsaglia. + * + * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag, + * New York, 1986, Ch. V, Sect. 4.4. + */ + template<typename _RealType> + template<class _UniformRandomNumberGenerator> + typename normal_distribution<_RealType>::result_type + normal_distribution<_RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { + result_type __ret; + + if (_M_saved_available) + { + _M_saved_available = false; + __ret = _M_saved; + } + else + { + result_type __x, __y, __r2; + do + { + __x = result_type(2.0) * __urng() - 1.0; + __y = result_type(2.0) * __urng() - 1.0; + __r2 = __x * __x + __y * __y; + } + while (__r2 > 1.0 || __r2 == 0.0); + + const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); + _M_saved = __x * __mult; + _M_saved_available = true; + __ret = __y * __mult; + } + + __ret = __ret * _M_sigma + _M_mean; + return __ret; + } + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const normal_distribution<_RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x._M_saved_available << __space + << __x.mean() << __space + << __x.sigma(); + if (__x._M_saved_available) + __os << __space << __x._M_saved; + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + normal_distribution<_RealType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + __is >> __x._M_saved_available >> __x._M_mean + >> __x._M_sigma; + if (__x._M_saved_available) + __is >> __x._M_saved; + + __is.flags(__flags); + return __is; + } + + + template<typename _RealType> + void + gamma_distribution<_RealType>:: + _M_initialize() + { + if (_M_alpha >= 1) + _M_l_d = std::sqrt(2 * _M_alpha - 1); + else + _M_l_d = (std::pow(_M_alpha, _M_alpha / (1 - _M_alpha)) + * (1 - _M_alpha)); + } + + /** + * Cheng's rejection algorithm GB for alpha >= 1 and a modification + * of Vaduva's rejection from Weibull algorithm due to Devroye for + * alpha < 1. + * + * References: + * Cheng, R. C. "The Generation of Gamma Random Variables with Non-integral + * Shape Parameter." Applied Statistics, 26, 71-75, 1977. + * + * Vaduva, I. "Computer Generation of Gamma Gandom Variables by Rejection + * and Composition Procedures." Math. Operationsforschung and Statistik, + * Series in Statistics, 8, 545-576, 1977. + * + * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag, + * New York, 1986, Ch. IX, Sect. 3.4 (+ Errata!). + */ + template<typename _RealType> + template<class _UniformRandomNumberGenerator> + typename gamma_distribution<_RealType>::result_type + gamma_distribution<_RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { + result_type __x; + + bool __reject; + if (_M_alpha >= 1) + { + // alpha - log(4) + const result_type __b = _M_alpha + - result_type(1.3862943611198906188344642429163531L); + const result_type __c = _M_alpha + _M_l_d; + const result_type __1l = 1 / _M_l_d; + + // 1 + log(9 / 2) + const result_type __k = 2.5040773967762740733732583523868748L; + + do + { + const result_type __u = __urng(); + const result_type __v = __urng(); + + const result_type __y = __1l * std::log(__v / (1 - __v)); + __x = _M_alpha * std::exp(__y); + + const result_type __z = __u * __v * __v; + const result_type __r = __b + __c * __y - __x; + + __reject = __r < result_type(4.5) * __z - __k; + if (__reject) + __reject = __r < std::log(__z); + } + while (__reject); + } + else + { + const result_type __c = 1 / _M_alpha; + + do + { + const result_type __z = -std::log(__urng()); + const result_type __e = -std::log(__urng()); + + __x = std::pow(__z, __c); + + __reject = __z + __e < _M_l_d + __x; + } + while (__reject); + } + + return __x; + } + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const gamma_distribution<_RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__os.widen(' ')); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.alpha(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + +_GLIBCXX_END_NAMESPACE +} diff --git a/libstdc++/include/tr1/ref_fwd.h b/libstdc++/include/tr1/ref_fwd.h new file mode 100644 index 0000000..6c0efbc --- /dev/null +++ b/libstdc++/include/tr1/ref_fwd.h @@ -0,0 +1,59 @@ + + +// class template reference_wrapper forwarding header -*- C++ -*- + +// 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. + +/** @file tr1/ref_fwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Douglas Gregor <doug.gregor -at- gmail.com> +#ifndef _TR1_REF_FWD +#define _TR1_REF_FWD + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + +template<typename _Tp> + class reference_wrapper; + +template<typename _Tp> + reference_wrapper<_Tp> + ref(_Tp& __t); + + // Denotes a const reference should be taken to a variable. +template<typename _Tp> + reference_wrapper<const _Tp> + cref(const _Tp& __t); + +_GLIBCXX_END_NAMESPACE +} +#endif diff --git a/libstdc++/include/tr1/ref_wrap_iterate.h b/libstdc++/include/tr1/ref_wrap_iterate.h new file mode 100644 index 0000000..7c63d2c --- /dev/null +++ b/libstdc++/include/tr1/ref_wrap_iterate.h @@ -0,0 +1,44 @@ +// TR1 reference_wrapper -*- C++ -*- + +// Copyright (C) 2005 Free Software Foundation, Inc. +// Written by Douglas Gregor <doug.gregor -at- gmail.com> +// +// 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. + +/** @file tr1/ref_wrap_iterate.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#if _GLIBCXX_NUM_ARGS > 0 +template<_GLIBCXX_TEMPLATE_PARAMS> + typename result_of<_M_func_type(_GLIBCXX_TEMPLATE_ARGS)>::type + operator()(_GLIBCXX_REF_PARAMS) const; +#else +typename result_of<_M_func_type()>::type +operator()() const +{ return get()(); } +#endif diff --git a/libstdc++/include/tr1/repeat.h b/libstdc++/include/tr1/repeat.h new file mode 100644 index 0000000..3f09dd5 --- /dev/null +++ b/libstdc++/include/tr1/repeat.h @@ -0,0 +1,677 @@ +// TR1 code repetition -*- C++ -*- + +// Copyright (C) 2005 Free Software Foundation, Inc. +// Written by Douglas Gregor <doug.gregor -at- gmail.com> +// +// 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. + +/** @file tr1/repeat.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_REPEAT_HEADER +# error Internal error: _GLIBCXX_REPEAT_HEADER must be set +#endif /* _GLIBCXX_REPEAT_HEADER */ + +#ifndef _GLIBCXX_TUPLE_ALL_TEMPLATE_PARAMS +# define _GLIBCXX_TUPLE_ALL_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10 +# define _GLIBCXX_TUPLE_ALL_TEMPLATE_PARAMS_UNNAMED typename, typename, typename, typename, typename, typename, typename, typename, typename, typename +# define _GLIBCXX_TUPLE_ALL_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10 +#endif + +#define _GLIBCXX_NUM_ARGS 0 +#define _GLIBCXX_COMMA +#define _GLIBCXX_TEMPLATE_PARAMS +#define _GLIBCXX_TEMPLATE_ARGS +#define _GLIBCXX_PARAMS +#define _GLIBCXX_REF_PARAMS +#define _GLIBCXX_ARGS +#define _GLIBCXX_COMMA_SHIFTED +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#define _GLIBCXX_PARAMS_SHIFTED +#define _GLIBCXX_ARGS_SHIFTED +#define _GLIBCXX_BIND_MEMBERS_INIT +#define _GLIBCXX_BIND_MEMBERS +#define _GLIBCXX_MU_GET_TUPLE_ARGS +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) +#define _GLIBCXX_BIND_V_ARGS +#define _GLIBCXX_TUPLE_ADD_CREF +#define _GLIBCXX_TUPLE_COPY_INIT +#define _GLIBCXX_TUPLE_ASSIGN +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#define _GLIBCXX_TEMPLATE_PARAMS_U +#define _GLIBCXX_TEMPLATE_ARGS_U +#define _GLIBCXX_REF_WRAP_PARAMS +#define _GLIBCXX_REF_TEMPLATE_ARGS +#define _GLIBCXX_NUM_ARGS_PLUS_1 1 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T1 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS + +#define _GLIBCXX_NUM_ARGS 1 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1 +#define _GLIBCXX_TEMPLATE_ARGS _T1 +#define _GLIBCXX_PARAMS _T1 __a1 +#define _GLIBCXX_REF_PARAMS _T1& __a1 +#define _GLIBCXX_ARGS __a1 +#define _GLIBCXX_COMMA_SHIFTED +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#define _GLIBCXX_PARAMS_SHIFTED +#define _GLIBCXX_ARGS_SHIFTED +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1& +#define _GLIBCXX_NUM_ARGS_PLUS_1 2 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T2 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS + +#define _GLIBCXX_NUM_ARGS 2 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2 +#define _GLIBCXX_TEMPLATE_ARGS _T1, _T2 +#define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2 +#define _GLIBCXX_REF_PARAMS _T1& __a1, _T2& __a2 +#define _GLIBCXX_ARGS __a1, __a2 +#define _GLIBCXX_COMMA_SHIFTED , +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1 +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1 +#define _GLIBCXX_PARAMS_SHIFTED _T1 __a1 +#define _GLIBCXX_ARGS_SHIFTED __a1 +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; _T2 _M_arg2; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1), _M_arg2(__a2) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple), ::std::tr1::get<1>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T2> _CV(_T2, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T2>()(_M_arg2, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1, typename __add_c_ref<_T2>::type __a2 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1), _M_arg2(__in._M_arg2) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; _M_arg2 = __in._M_arg2; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass, typename _T2 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1, typename _U2 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1, _U2 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1), ref(__a2) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1&, _T2& +#define _GLIBCXX_NUM_ARGS_PLUS_1 3 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T3 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS +#define _GLIBCXX_NUM_ARGS 3 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3 +#define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3 +#define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3 +#define _GLIBCXX_REF_PARAMS _T1& __a1, _T2& __a2, _T3& __a3 +#define _GLIBCXX_ARGS __a1, __a2, __a3 +#define _GLIBCXX_COMMA_SHIFTED , +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2 +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2 +#define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2 +#define _GLIBCXX_ARGS_SHIFTED __a1, __a2 +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; _T2 _M_arg2; _T3 _M_arg3; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1), _M_arg2(__a2), _M_arg3(__a3) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple), ::std::tr1::get<1>(__tuple), ::std::tr1::get<2>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T2> _CV(_T2, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T3> _CV(_T3, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T2>()(_M_arg2, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T3>()(_M_arg3, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1, typename __add_c_ref<_T2>::type __a2, typename __add_c_ref<_T3>::type __a3 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1), _M_arg2(__in._M_arg2), _M_arg3(__in._M_arg3) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; _M_arg2 = __in._M_arg2; _M_arg3 = __in._M_arg3; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass, typename _T2 = _NullClass, typename _T3 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type, typename __strip_reference_wrapper<_T3>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1, typename _U2, typename _U3 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1, _U2, _U3 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1), ref(__a2), ref(__a3) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1&, _T2&, _T3& +#define _GLIBCXX_NUM_ARGS_PLUS_1 4 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T4 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS +#define _GLIBCXX_NUM_ARGS 4 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4 +#define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4 +#define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4 +#define _GLIBCXX_REF_PARAMS _T1& __a1, _T2& __a2, _T3& __a3, _T4& __a4 +#define _GLIBCXX_ARGS __a1, __a2, __a3, __a4 +#define _GLIBCXX_COMMA_SHIFTED , +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3 +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3 +#define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3 +#define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3 +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; _T2 _M_arg2; _T3 _M_arg3; _T4 _M_arg4; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1), _M_arg2(__a2), _M_arg3(__a3), _M_arg4(__a4) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple), ::std::tr1::get<1>(__tuple), ::std::tr1::get<2>(__tuple), ::std::tr1::get<3>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T2> _CV(_T2, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T3> _CV(_T3, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T4> _CV(_T4, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T2>()(_M_arg2, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T3>()(_M_arg3, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T4>()(_M_arg4, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1, typename __add_c_ref<_T2>::type __a2, typename __add_c_ref<_T3>::type __a3, typename __add_c_ref<_T4>::type __a4 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1), _M_arg2(__in._M_arg2), _M_arg3(__in._M_arg3), _M_arg4(__in._M_arg4) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; _M_arg2 = __in._M_arg2; _M_arg3 = __in._M_arg3; _M_arg4 = __in._M_arg4; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass, typename _T2 = _NullClass, typename _T3 = _NullClass, typename _T4 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type, typename __strip_reference_wrapper<_T3>::__type, typename __strip_reference_wrapper<_T4>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1, typename _U2, typename _U3, typename _U4 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1, _U2, _U3, _U4 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1), ref(__a2), ref(__a3), ref(__a4) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1&, _T2&, _T3&, _T4& +#define _GLIBCXX_NUM_ARGS_PLUS_1 5 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T5 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS +#define _GLIBCXX_NUM_ARGS 5 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5 +#define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5 +#define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5 +#define _GLIBCXX_REF_PARAMS _T1& __a1, _T2& __a2, _T3& __a3, _T4& __a4, _T5& __a5 +#define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5 +#define _GLIBCXX_COMMA_SHIFTED , +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4 +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4 +#define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4 +#define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4 +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; _T2 _M_arg2; _T3 _M_arg3; _T4 _M_arg4; _T5 _M_arg5; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1), _M_arg2(__a2), _M_arg3(__a3), _M_arg4(__a4), _M_arg5(__a5) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple), ::std::tr1::get<1>(__tuple), ::std::tr1::get<2>(__tuple), ::std::tr1::get<3>(__tuple), ::std::tr1::get<4>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T2> _CV(_T2, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T3> _CV(_T3, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T4> _CV(_T4, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T5> _CV(_T5, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T2>()(_M_arg2, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T3>()(_M_arg3, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T4>()(_M_arg4, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T5>()(_M_arg5, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1, typename __add_c_ref<_T2>::type __a2, typename __add_c_ref<_T3>::type __a3, typename __add_c_ref<_T4>::type __a4, typename __add_c_ref<_T5>::type __a5 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1), _M_arg2(__in._M_arg2), _M_arg3(__in._M_arg3), _M_arg4(__in._M_arg4), _M_arg5(__in._M_arg5) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; _M_arg2 = __in._M_arg2; _M_arg3 = __in._M_arg3; _M_arg4 = __in._M_arg4; _M_arg5 = __in._M_arg5; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass, typename _T2 = _NullClass, typename _T3 = _NullClass, typename _T4 = _NullClass, typename _T5 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type, typename __strip_reference_wrapper<_T3>::__type, typename __strip_reference_wrapper<_T4>::__type, typename __strip_reference_wrapper<_T5>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1, typename _U2, typename _U3, typename _U4, typename _U5 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1, _U2, _U3, _U4, _U5 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1), ref(__a2), ref(__a3), ref(__a4), ref(__a5) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1&, _T2&, _T3&, _T4&, _T5& +#define _GLIBCXX_NUM_ARGS_PLUS_1 6 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T6 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS +#define _GLIBCXX_NUM_ARGS 6 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6 +#define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6 +#define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6 +#define _GLIBCXX_REF_PARAMS _T1& __a1, _T2& __a2, _T3& __a3, _T4& __a4, _T5& __a5, _T6& __a6 +#define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6 +#define _GLIBCXX_COMMA_SHIFTED , +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5 +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5 +#define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5 +#define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5 +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; _T2 _M_arg2; _T3 _M_arg3; _T4 _M_arg4; _T5 _M_arg5; _T6 _M_arg6; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1), _M_arg2(__a2), _M_arg3(__a3), _M_arg4(__a4), _M_arg5(__a5), _M_arg6(__a6) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple), ::std::tr1::get<1>(__tuple), ::std::tr1::get<2>(__tuple), ::std::tr1::get<3>(__tuple), ::std::tr1::get<4>(__tuple), ::std::tr1::get<5>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T2> _CV(_T2, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T3> _CV(_T3, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T4> _CV(_T4, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T5> _CV(_T5, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T6> _CV(_T6, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T2>()(_M_arg2, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T3>()(_M_arg3, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T4>()(_M_arg4, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T5>()(_M_arg5, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T6>()(_M_arg6, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1, typename __add_c_ref<_T2>::type __a2, typename __add_c_ref<_T3>::type __a3, typename __add_c_ref<_T4>::type __a4, typename __add_c_ref<_T5>::type __a5, typename __add_c_ref<_T6>::type __a6 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1), _M_arg2(__in._M_arg2), _M_arg3(__in._M_arg3), _M_arg4(__in._M_arg4), _M_arg5(__in._M_arg5), _M_arg6(__in._M_arg6) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; _M_arg2 = __in._M_arg2; _M_arg3 = __in._M_arg3; _M_arg4 = __in._M_arg4; _M_arg5 = __in._M_arg5; _M_arg6 = __in._M_arg6; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass, typename _T2 = _NullClass, typename _T3 = _NullClass, typename _T4 = _NullClass, typename _T5 = _NullClass, typename _T6 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type, typename __strip_reference_wrapper<_T3>::__type, typename __strip_reference_wrapper<_T4>::__type, typename __strip_reference_wrapper<_T5>::__type, typename __strip_reference_wrapper<_T6>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1, _U2, _U3, _U4, _U5, _U6 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1), ref(__a2), ref(__a3), ref(__a4), ref(__a5), ref(__a6) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1&, _T2&, _T3&, _T4&, _T5&, _T6& +#define _GLIBCXX_NUM_ARGS_PLUS_1 7 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T7 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS +#define _GLIBCXX_NUM_ARGS 7 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7 +#define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7 +#define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7 +#define _GLIBCXX_REF_PARAMS _T1& __a1, _T2& __a2, _T3& __a3, _T4& __a4, _T5& __a5, _T6& __a6, _T7& __a7 +#define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7 +#define _GLIBCXX_COMMA_SHIFTED , +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6 +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6 +#define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6 +#define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6 +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; _T2 _M_arg2; _T3 _M_arg3; _T4 _M_arg4; _T5 _M_arg5; _T6 _M_arg6; _T7 _M_arg7; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1), _M_arg2(__a2), _M_arg3(__a3), _M_arg4(__a4), _M_arg5(__a5), _M_arg6(__a6), _M_arg7(__a7) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple), ::std::tr1::get<1>(__tuple), ::std::tr1::get<2>(__tuple), ::std::tr1::get<3>(__tuple), ::std::tr1::get<4>(__tuple), ::std::tr1::get<5>(__tuple), ::std::tr1::get<6>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T2> _CV(_T2, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T3> _CV(_T3, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T4> _CV(_T4, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T5> _CV(_T5, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T6> _CV(_T6, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T7> _CV(_T7, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T2>()(_M_arg2, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T3>()(_M_arg3, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T4>()(_M_arg4, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T5>()(_M_arg5, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T6>()(_M_arg6, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T7>()(_M_arg7, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1, typename __add_c_ref<_T2>::type __a2, typename __add_c_ref<_T3>::type __a3, typename __add_c_ref<_T4>::type __a4, typename __add_c_ref<_T5>::type __a5, typename __add_c_ref<_T6>::type __a6, typename __add_c_ref<_T7>::type __a7 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1), _M_arg2(__in._M_arg2), _M_arg3(__in._M_arg3), _M_arg4(__in._M_arg4), _M_arg5(__in._M_arg5), _M_arg6(__in._M_arg6), _M_arg7(__in._M_arg7) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; _M_arg2 = __in._M_arg2; _M_arg3 = __in._M_arg3; _M_arg4 = __in._M_arg4; _M_arg5 = __in._M_arg5; _M_arg6 = __in._M_arg6; _M_arg7 = __in._M_arg7; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass, typename _T2 = _NullClass, typename _T3 = _NullClass, typename _T4 = _NullClass, typename _T5 = _NullClass, typename _T6 = _NullClass, typename _T7 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type, typename __strip_reference_wrapper<_T3>::__type, typename __strip_reference_wrapper<_T4>::__type, typename __strip_reference_wrapper<_T5>::__type, typename __strip_reference_wrapper<_T6>::__type, typename __strip_reference_wrapper<_T7>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1, _U2, _U3, _U4, _U5, _U6, _U7 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1), ref(__a2), ref(__a3), ref(__a4), ref(__a5), ref(__a6), ref(__a7) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1&, _T2&, _T3&, _T4&, _T5&, _T6&, _T7& +#define _GLIBCXX_NUM_ARGS_PLUS_1 8 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T8 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS +#define _GLIBCXX_NUM_ARGS 8 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8 +#define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8 +#define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8 +#define _GLIBCXX_REF_PARAMS _T1& __a1, _T2& __a2, _T3& __a3, _T4& __a4, _T5& __a5, _T6& __a6, _T7& __a7, _T8& __a8 +#define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8 +#define _GLIBCXX_COMMA_SHIFTED , +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7 +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7 +#define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7 +#define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7 +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; _T2 _M_arg2; _T3 _M_arg3; _T4 _M_arg4; _T5 _M_arg5; _T6 _M_arg6; _T7 _M_arg7; _T8 _M_arg8; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1), _M_arg2(__a2), _M_arg3(__a3), _M_arg4(__a4), _M_arg5(__a5), _M_arg6(__a6), _M_arg7(__a7), _M_arg8(__a8) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple), ::std::tr1::get<1>(__tuple), ::std::tr1::get<2>(__tuple), ::std::tr1::get<3>(__tuple), ::std::tr1::get<4>(__tuple), ::std::tr1::get<5>(__tuple), ::std::tr1::get<6>(__tuple), ::std::tr1::get<7>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T2> _CV(_T2, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T3> _CV(_T3, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T4> _CV(_T4, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T5> _CV(_T5, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T6> _CV(_T6, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T7> _CV(_T7, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T8> _CV(_T8, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T2>()(_M_arg2, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T3>()(_M_arg3, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T4>()(_M_arg4, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T5>()(_M_arg5, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T6>()(_M_arg6, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T7>()(_M_arg7, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T8>()(_M_arg8, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1, typename __add_c_ref<_T2>::type __a2, typename __add_c_ref<_T3>::type __a3, typename __add_c_ref<_T4>::type __a4, typename __add_c_ref<_T5>::type __a5, typename __add_c_ref<_T6>::type __a6, typename __add_c_ref<_T7>::type __a7, typename __add_c_ref<_T8>::type __a8 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1), _M_arg2(__in._M_arg2), _M_arg3(__in._M_arg3), _M_arg4(__in._M_arg4), _M_arg5(__in._M_arg5), _M_arg6(__in._M_arg6), _M_arg7(__in._M_arg7), _M_arg8(__in._M_arg8) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; _M_arg2 = __in._M_arg2; _M_arg3 = __in._M_arg3; _M_arg4 = __in._M_arg4; _M_arg5 = __in._M_arg5; _M_arg6 = __in._M_arg6; _M_arg7 = __in._M_arg7; _M_arg8 = __in._M_arg8; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass, typename _T2 = _NullClass, typename _T3 = _NullClass, typename _T4 = _NullClass, typename _T5 = _NullClass, typename _T6 = _NullClass, typename _T7 = _NullClass, typename _T8 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type, typename __strip_reference_wrapper<_T3>::__type, typename __strip_reference_wrapper<_T4>::__type, typename __strip_reference_wrapper<_T5>::__type, typename __strip_reference_wrapper<_T6>::__type, typename __strip_reference_wrapper<_T7>::__type, typename __strip_reference_wrapper<_T8>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1), ref(__a2), ref(__a3), ref(__a4), ref(__a5), ref(__a6), ref(__a7), ref(__a8) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1&, _T2&, _T3&, _T4&, _T5&, _T6&, _T7&, _T8& +#define _GLIBCXX_NUM_ARGS_PLUS_1 9 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T9 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS +#define _GLIBCXX_NUM_ARGS 9 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9 +#define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9 +#define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9 +#define _GLIBCXX_REF_PARAMS _T1& __a1, _T2& __a2, _T3& __a3, _T4& __a4, _T5& __a5, _T6& __a6, _T7& __a7, _T8& __a8, _T9& __a9 +#define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9 +#define _GLIBCXX_COMMA_SHIFTED , +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8 +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8 +#define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8 +#define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8 +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; _T2 _M_arg2; _T3 _M_arg3; _T4 _M_arg4; _T5 _M_arg5; _T6 _M_arg6; _T7 _M_arg7; _T8 _M_arg8; _T9 _M_arg9; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1), _M_arg2(__a2), _M_arg3(__a3), _M_arg4(__a4), _M_arg5(__a5), _M_arg6(__a6), _M_arg7(__a7), _M_arg8(__a8), _M_arg9(__a9) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple), ::std::tr1::get<1>(__tuple), ::std::tr1::get<2>(__tuple), ::std::tr1::get<3>(__tuple), ::std::tr1::get<4>(__tuple), ::std::tr1::get<5>(__tuple), ::std::tr1::get<6>(__tuple), ::std::tr1::get<7>(__tuple), ::std::tr1::get<8>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T2> _CV(_T2, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T3> _CV(_T3, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T4> _CV(_T4, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T5> _CV(_T5, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T6> _CV(_T6, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T7> _CV(_T7, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T8> _CV(_T8, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T9> _CV(_T9, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T2>()(_M_arg2, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T3>()(_M_arg3, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T4>()(_M_arg4, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T5>()(_M_arg5, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T6>()(_M_arg6, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T7>()(_M_arg7, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T8>()(_M_arg8, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T9>()(_M_arg9, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1, typename __add_c_ref<_T2>::type __a2, typename __add_c_ref<_T3>::type __a3, typename __add_c_ref<_T4>::type __a4, typename __add_c_ref<_T5>::type __a5, typename __add_c_ref<_T6>::type __a6, typename __add_c_ref<_T7>::type __a7, typename __add_c_ref<_T8>::type __a8, typename __add_c_ref<_T9>::type __a9 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1), _M_arg2(__in._M_arg2), _M_arg3(__in._M_arg3), _M_arg4(__in._M_arg4), _M_arg5(__in._M_arg5), _M_arg6(__in._M_arg6), _M_arg7(__in._M_arg7), _M_arg8(__in._M_arg8), _M_arg9(__in._M_arg9) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; _M_arg2 = __in._M_arg2; _M_arg3 = __in._M_arg3; _M_arg4 = __in._M_arg4; _M_arg5 = __in._M_arg5; _M_arg6 = __in._M_arg6; _M_arg7 = __in._M_arg7; _M_arg8 = __in._M_arg8; _M_arg9 = __in._M_arg9; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass, typename _T2 = _NullClass, typename _T3 = _NullClass, typename _T4 = _NullClass, typename _T5 = _NullClass, typename _T6 = _NullClass, typename _T7 = _NullClass, typename _T8 = _NullClass, typename _T9 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type, typename __strip_reference_wrapper<_T3>::__type, typename __strip_reference_wrapper<_T4>::__type, typename __strip_reference_wrapper<_T5>::__type, typename __strip_reference_wrapper<_T6>::__type, typename __strip_reference_wrapper<_T7>::__type, typename __strip_reference_wrapper<_T8>::__type, typename __strip_reference_wrapper<_T9>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1), ref(__a2), ref(__a3), ref(__a4), ref(__a5), ref(__a6), ref(__a7), ref(__a8), ref(__a9) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1&, _T2&, _T3&, _T4&, _T5&, _T6&, _T7&, _T8&, _T9& +#define _GLIBCXX_NUM_ARGS_PLUS_1 10 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T10 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS +#define _GLIBCXX_LAST_INCLUDE +#define _GLIBCXX_NUM_ARGS 10 +#define _GLIBCXX_COMMA , +#define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10 +#define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10 +#define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10 +#define _GLIBCXX_REF_PARAMS _T1& __a1, _T2& __a2, _T3& __a3, _T4& __a4, _T5& __a5, _T6& __a6, _T7& __a7, _T8& __a8, _T9& __a9, _T10& __a10 +#define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10 +#define _GLIBCXX_COMMA_SHIFTED , +#define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9 +#define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9 +#define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9 +#define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9 +#define _GLIBCXX_BIND_MEMBERS _T1 _M_arg1; _T2 _M_arg2; _T3 _M_arg3; _T4 _M_arg4; _T5 _M_arg5; _T6 _M_arg6; _T7 _M_arg7; _T8 _M_arg8; _T9 _M_arg9; _T10 _M_arg10; +#define _GLIBCXX_BIND_MEMBERS_INIT _M_arg1(__a1), _M_arg2(__a2), _M_arg3(__a3), _M_arg4(__a4), _M_arg5(__a5), _M_arg6(__a6), _M_arg7(__a7), _M_arg8(__a8), _M_arg9(__a9), _M_arg10(__a10) +#define _GLIBCXX_MU_GET_TUPLE_ARGS ::std::tr1::get<0>(__tuple), ::std::tr1::get<1>(__tuple), ::std::tr1::get<2>(__tuple), ::std::tr1::get<3>(__tuple), ::std::tr1::get<4>(__tuple), ::std::tr1::get<5>(__tuple), ::std::tr1::get<6>(__tuple), ::std::tr1::get<7>(__tuple), ::std::tr1::get<8>(__tuple), ::std::tr1::get<9>(__tuple) +#define _GLIBCXX_BIND_V_TEMPLATE_ARGS(_CV) typename result_of<_Mu<_T1> _CV(_T1, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T2> _CV(_T2, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T3> _CV(_T3, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T4> _CV(_T4, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T5> _CV(_T5, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T6> _CV(_T6, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T7> _CV(_T7, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T8> _CV(_T8, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T9> _CV(_T9, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type, typename result_of<_Mu<_T10> _CV(_T10, tuple<_GLIBCXX_BIND_TEMPLATE_ARGS>)>::type +#define _GLIBCXX_BIND_V_ARGS _Mu<_T1>()(_M_arg1, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T2>()(_M_arg2, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T3>()(_M_arg3, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T4>()(_M_arg4, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T5>()(_M_arg5, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T6>()(_M_arg6, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T7>()(_M_arg7, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T8>()(_M_arg8, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T9>()(_M_arg9, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)), _Mu<_T10>()(_M_arg10, ::std::tr1::tie(_GLIBCXX_BIND_ARGS)) +#define _GLIBCXX_TUPLE_ADD_CREF typename __add_c_ref<_T1>::type __a1, typename __add_c_ref<_T2>::type __a2, typename __add_c_ref<_T3>::type __a3, typename __add_c_ref<_T4>::type __a4, typename __add_c_ref<_T5>::type __a5, typename __add_c_ref<_T6>::type __a6, typename __add_c_ref<_T7>::type __a7, typename __add_c_ref<_T8>::type __a8, typename __add_c_ref<_T9>::type __a9, typename __add_c_ref<_T10>::type __a10 +#define _GLIBCXX_TUPLE_COPY_INIT _M_arg1(__in._M_arg1), _M_arg2(__in._M_arg2), _M_arg3(__in._M_arg3), _M_arg4(__in._M_arg4), _M_arg5(__in._M_arg5), _M_arg6(__in._M_arg6), _M_arg7(__in._M_arg7), _M_arg8(__in._M_arg8), _M_arg9(__in._M_arg9), _M_arg10(__in._M_arg10) +#define _GLIBCXX_TUPLE_ASSIGN _M_arg1 = __in._M_arg1; _M_arg2 = __in._M_arg2; _M_arg3 = __in._M_arg3; _M_arg4 = __in._M_arg4; _M_arg5 = __in._M_arg5; _M_arg6 = __in._M_arg6; _M_arg7 = __in._M_arg7; _M_arg8 = __in._M_arg8; _M_arg9 = __in._M_arg9; _M_arg10 = __in._M_arg10; +#define _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS typename _T1 = _NullClass, typename _T2 = _NullClass, typename _T3 = _NullClass, typename _T4 = _NullClass, typename _T5 = _NullClass, typename _T6 = _NullClass, typename _T7 = _NullClass, typename _T8 = _NullClass, typename _T9 = _NullClass, typename _T10 = _NullClass +#define _GLIBCXX_TEMPLATE_ARGS_STRIPPED typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type, typename __strip_reference_wrapper<_T3>::__type, typename __strip_reference_wrapper<_T4>::__type, typename __strip_reference_wrapper<_T5>::__type, typename __strip_reference_wrapper<_T6>::__type, typename __strip_reference_wrapper<_T7>::__type, typename __strip_reference_wrapper<_T8>::__type, typename __strip_reference_wrapper<_T9>::__type, typename __strip_reference_wrapper<_T10>::__type +#define _GLIBCXX_TEMPLATE_PARAMS_U typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9, typename _U10 +#define _GLIBCXX_TEMPLATE_ARGS_U _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9, _U10 +#define _GLIBCXX_REF_WRAP_PARAMS ref(__a1), ref(__a2), ref(__a3), ref(__a4), ref(__a5), ref(__a6), ref(__a7), ref(__a8), ref(__a9), ref(__a10) +#define _GLIBCXX_REF_TEMPLATE_ARGS _T1&, _T2&, _T3&, _T4&, _T5&, _T6&, _T7&, _T8&, _T9&, _T10& +#define _GLIBCXX_NUM_ARGS_PLUS_1 11 +#define _GLIBCXX_T_NUM_ARGS_PLUS_1 _T11 +#include _GLIBCXX_REPEAT_HEADER +#undef _GLIBCXX_T_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_NUM_ARGS_PLUS_1 +#undef _GLIBCXX_REF_TEMPLATE_ARGS +#undef _GLIBCXX_REF_WRAP_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS_U +#undef _GLIBCXX_TEMPLATE_PARAMS_U +#undef _GLIBCXX_TEMPLATE_ARGS_STRIPPED +#undef _GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS +#undef _GLIBCXX_TUPLE_ASSIGN +#undef _GLIBCXX_TUPLE_COPY_INIT +#undef _GLIBCXX_TUPLE_ADD_CREF +#undef _GLIBCXX_BIND_V_ARGS +#undef _GLIBCXX_BIND_V_TEMPLATE_ARGS +#undef _GLIBCXX_MU_GET_TUPLE_ARGS +#undef _GLIBCXX_BIND_MEMBERS_INIT +#undef _GLIBCXX_BIND_MEMBERS +#undef _GLIBCXX_ARGS_SHIFTED +#undef _GLIBCXX_PARAMS_SHIFTED +#undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED +#undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED +#undef _GLIBCXX_COMMA_SHIFTED +#undef _GLIBCXX_ARGS +#undef _GLIBCXX_REF_PARAMS +#undef _GLIBCXX_PARAMS +#undef _GLIBCXX_TEMPLATE_ARGS +#undef _GLIBCXX_TEMPLATE_PARAMS +#undef _GLIBCXX_COMMA +#undef _GLIBCXX_NUM_ARGS +#undef _GLIBCXX_LAST_INCLUDE + diff --git a/libstdc++/include/tr1/stdarg.h b/libstdc++/include/tr1/stdarg.h new file mode 100644 index 0000000..87c4cf3 --- /dev/null +++ b/libstdc++/include/tr1/stdarg.h @@ -0,0 +1,39 @@ +// TR1 stdarg.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/stdarg.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_STDARG_H +#define _TR1_STDARG_H 1 + +#include <tr1/cstdarg> + +#endif diff --git a/libstdc++/include/tr1/stdbool.h b/libstdc++/include/tr1/stdbool.h new file mode 100644 index 0000000..5865e02 --- /dev/null +++ b/libstdc++/include/tr1/stdbool.h @@ -0,0 +1,39 @@ +// TR1 stdbool.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/stdbool.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_STDBOOL_H +#define _TR1_STDBOOL_H 1 + +#include <tr1/cstdbool> + +#endif diff --git a/libstdc++/include/tr1/stdint.h b/libstdc++/include/tr1/stdint.h new file mode 100644 index 0000000..f9e4870 --- /dev/null +++ b/libstdc++/include/tr1/stdint.h @@ -0,0 +1,39 @@ +// TR1 stdint.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/stdint.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_STDINT_H +#define _TR1_STDINT_H 1 + +#include <tr1/cstdint> + +#endif diff --git a/libstdc++/include/tr1/stdio.h b/libstdc++/include/tr1/stdio.h new file mode 100644 index 0000000..763f03e --- /dev/null +++ b/libstdc++/include/tr1/stdio.h @@ -0,0 +1,39 @@ +// TR1 stdio.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/stdio.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_STDIO_H +#define _TR1_STDIO_H 1 + +#include <tr1/cstdio> + +#endif diff --git a/libstdc++/include/tr1/stdlib.h b/libstdc++/include/tr1/stdlib.h new file mode 100644 index 0000000..92bc468 --- /dev/null +++ b/libstdc++/include/tr1/stdlib.h @@ -0,0 +1,56 @@ +// TR1 stdlib.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/stdlib.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_STDLIB_H +#define _TR1_STDLIB_H 1 + +#include <tr1/cstdlib> + +#if _GLIBCXX_HOSTED + +#if _GLIBCXX_USE_C99 + +using std::tr1::atoll; +using std::tr1::strtoll; +using std::tr1::strtoull; + +using std::tr1::abs; +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC +using std::tr1::div; +#endif + +#endif + +#endif + +#endif diff --git a/libstdc++/include/tr1/tgmath.h b/libstdc++/include/tr1/tgmath.h new file mode 100644 index 0000000..90c8a63 --- /dev/null +++ b/libstdc++/include/tr1/tgmath.h @@ -0,0 +1,39 @@ +// TR1 tgmath.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/tgmath.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_TGMATH_H +#define _TR1_TGMATH_H 1 + +#include <tr1/ctgmath> + +#endif diff --git a/libstdc++/include/tr1/tuple b/libstdc++/include/tr1/tuple new file mode 100644 index 0000000..379631d --- /dev/null +++ b/libstdc++/include/tr1/tuple @@ -0,0 +1,161 @@ +// class template tuple -*- C++ -*- + +// 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. + +/** @file tr1/tuple +* This is a TR1 C++ Library header. +*/ + +// Chris Jefferson <chris@bubblescope.net> + +#ifndef _TR1_TUPLE +#define _TR1_TUPLE 1 + +#include <tr1/utility> +#include <tr1/ref_fwd.h> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // An implementation specific class which is used in the tuple class + // when the tuple is not maximum possible size. + struct _NullClass { }; + + /// Gives the type of the ith element of a given tuple type. + template<int __i, typename _Tp> + struct tuple_element; + + /// Finds the size of a given tuple type. + template<typename _Tp> + struct tuple_size; + + // Adds a const reference to a non-reference type. + template<typename _Tp> + struct __add_c_ref + { typedef const _Tp& type; }; + + template<typename _Tp> + struct __add_c_ref<_Tp&> + { typedef _Tp& type; }; + + // Adds a reference to a non-reference type. + template<typename _Tp> + struct __add_ref + { typedef _Tp& type; }; + + template<typename _Tp> + struct __add_ref<_Tp&> + { typedef _Tp& type; }; + + // Class used in the implementation of get + template<int __i, typename _Tp> + struct __get_helper; + + // Returns a const reference to the ith element of a tuple. + // Any const or non-const ref elements are returned with their original type. + + // This class helps construct the various comparison operations on tuples + template<int __check_equal_size, int __i, int __j, typename _Tp, typename _Up> + struct __tuple_compare; + + // Helper which adds a reference to a type when given a reference_wrapper + template<typename _Tp> + struct __strip_reference_wrapper + { + typedef _Tp __type; + }; + + template<typename _Tp> + struct __strip_reference_wrapper<reference_wrapper<_Tp> > + { + typedef _Tp& __type; + }; + + template<typename _Tp> + struct __strip_reference_wrapper<const reference_wrapper<_Tp> > + { + typedef _Tp& __type; + }; + + #include "tuple_defs.h" + + template<int __i, int __j, typename _Tp, typename _Up> + struct __tuple_compare<0, __i, __j, _Tp, _Up> + { + static bool __eq(const _Tp& __t, const _Up& __u) + { + return get<__i>(__t) == get<__i>(__u) && + __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u); + } + static bool __less(const _Tp& __t, const _Up& __u) + { + return (get<__i>(__t) < get<__i>(__u)) || !(get<__i>(__u) < get<__i>(__t)) && + __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u); + } + }; + + template<int __i, typename _Tp, typename _Up> + struct __tuple_compare<0, __i, __i, _Tp, _Up> + { + static bool __eq(const _Tp&, const _Up&) + { return true; } + static bool __less(const _Tp&, const _Up&) + { return false; } + }; + + // A class (and instance) which can be used in 'tie' when an element + // of a tuple is not required + struct swallow_assign + { + template<class T> + swallow_assign& + operator=(const T&) + { return *this; } + }; + + // TODO: Put this in some kind of shared file. + namespace + { + swallow_assign ignore; + }; // anonymous namespace + +_GLIBCXX_END_NAMESPACE +} + +#define _GLIBCXX_CAT(x,y) _GLIBCXX_CAT2(x,y) +#define _GLIBCXX_CAT2(x,y) x##y +#define _SHORT_REPEAT +#define _GLIBCXX_REPEAT_HEADER <tr1/tuple_iterate.h> +#include <tr1/repeat.h> +#undef _GLIBCXX_REPEAT_HEADER +#undef _SHORT_REPEAT + +#include <tr1/functional> + +#endif diff --git a/libstdc++/include/tr1/tuple_defs.h b/libstdc++/include/tr1/tuple_defs.h new file mode 100644 index 0000000..dba6ccc --- /dev/null +++ b/libstdc++/include/tr1/tuple_defs.h @@ -0,0 +1,114 @@ +// class template tuple -*- C++ -*- + +// 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. + +/** @file tr1/tuple_defs.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_REPEAT_HEADER +# define _GLIBCXX_REPEAT_HEADER "tuple_defs.h" +# include "repeat.h" +# undef _GLIBCXX_REPEAT_HEADER +#endif + +#ifdef _GLIBCXX_LAST_INCLUDE +// Chris Jefferson <chris@bubblescope.net> + template<_GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS> class tuple; + + // Returns a const reference to the ith element of a tuple. + // Any const or non-const ref elements are returned with their original type. + template<int __i, _GLIBCXX_TEMPLATE_PARAMS> + typename __add_ref<typename tuple_element<__i, tuple<_GLIBCXX_TEMPLATE_ARGS> >::type>::type + get(tuple<_GLIBCXX_TEMPLATE_ARGS>& __t) + { + return __get_helper<__i, tuple<_GLIBCXX_TEMPLATE_ARGS> >::get_value(__t); + } + + template<int __i, _GLIBCXX_TEMPLATE_PARAMS> + typename __add_c_ref<typename tuple_element<__i, tuple<_GLIBCXX_TEMPLATE_ARGS> >::type>::type + get(const tuple<_GLIBCXX_TEMPLATE_ARGS>& __t) + { + return __get_helper<__i, tuple<_GLIBCXX_TEMPLATE_ARGS> >::get_value(__t); + } + + template<_GLIBCXX_TEMPLATE_PARAMS, _GLIBCXX_TEMPLATE_PARAMS_U> + bool + operator==(const tuple<_GLIBCXX_TEMPLATE_ARGS>& __t, + const tuple<_GLIBCXX_TEMPLATE_ARGS_U>& __u) + { + typedef tuple<_GLIBCXX_TEMPLATE_ARGS> _Tp; + typedef tuple<_GLIBCXX_TEMPLATE_ARGS_U> _Up; + return __tuple_compare<tuple_size<_Tp>::value - tuple_size<_Tp>::value, 0, + tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u); + } + + template<_GLIBCXX_TEMPLATE_PARAMS, _GLIBCXX_TEMPLATE_PARAMS_U> + bool + operator<(const tuple<_GLIBCXX_TEMPLATE_ARGS>& __t, + const tuple<_GLIBCXX_TEMPLATE_ARGS_U>& __u) + { + typedef tuple<_GLIBCXX_TEMPLATE_ARGS> _Tp; + typedef tuple<_GLIBCXX_TEMPLATE_ARGS_U> _Up; + return __tuple_compare<tuple_size<_Tp>::value - tuple_size<_Tp>::value, 0, + tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u); + } + + template<_GLIBCXX_TEMPLATE_PARAMS, _GLIBCXX_TEMPLATE_PARAMS_U> + bool + operator!=(const tuple<_GLIBCXX_TEMPLATE_ARGS>& __t, + const tuple<_GLIBCXX_TEMPLATE_ARGS_U>& __u) + { return !(__t == __u); } + + template<_GLIBCXX_TEMPLATE_PARAMS, _GLIBCXX_TEMPLATE_PARAMS_U> + bool + operator>(const tuple<_GLIBCXX_TEMPLATE_ARGS>& __t, + const tuple<_GLIBCXX_TEMPLATE_ARGS_U>& __u) + { return __u < __t; } + + template<_GLIBCXX_TEMPLATE_PARAMS, _GLIBCXX_TEMPLATE_PARAMS_U> + bool + operator<=(const tuple<_GLIBCXX_TEMPLATE_ARGS>& __t, + const tuple<_GLIBCXX_TEMPLATE_ARGS_U>& __u) + { return !(__u < __t); } + + template<_GLIBCXX_TEMPLATE_PARAMS, _GLIBCXX_TEMPLATE_PARAMS_U> + bool + operator>=(const tuple<_GLIBCXX_TEMPLATE_ARGS>& __t, + const tuple<_GLIBCXX_TEMPLATE_ARGS_U>& __u) + { return !(__t < __u); } + + template<_GLIBCXX_TEMPLATE_PARAMS_NULL_CLASS> + struct __stripped_tuple_type + { + typedef tuple<_GLIBCXX_TEMPLATE_ARGS_STRIPPED> __type; + }; + +#endif + diff --git a/libstdc++/include/tr1/tuple_iterate.h b/libstdc++/include/tr1/tuple_iterate.h new file mode 100644 index 0000000..42ddf54 --- /dev/null +++ b/libstdc++/include/tr1/tuple_iterate.h @@ -0,0 +1,172 @@ +// class template tuple -*- C++ -*- + +// 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. + +/** @file tr1/tuple_iterate.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// Chris Jefferson <chris@bubblescope.net> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + +/// @brief class tuple_size +template<_GLIBCXX_TEMPLATE_PARAMS> + struct tuple_size<tuple<_GLIBCXX_TEMPLATE_ARGS> > + { static const int value = _GLIBCXX_NUM_ARGS; }; + +#if _GLIBCXX_NUM_ARGS > 0 +template<_GLIBCXX_TEMPLATE_PARAMS> + const int tuple_size<tuple<_GLIBCXX_TEMPLATE_ARGS> >::value; +#endif + +template<_GLIBCXX_TEMPLATE_PARAMS> +#ifdef _GLIBCXX_LAST_INCLUDE + class tuple +#else + class tuple<_GLIBCXX_TEMPLATE_ARGS> +#endif + { + _GLIBCXX_BIND_MEMBERS + + public: + tuple() + { } + +#if _GLIBCXX_NUM_ARGS == 2 + template<typename _U1, typename _U2> + tuple(const std::pair<_U1, _U2>& __u) : + _M_arg1(__u.first), _M_arg2(__u.second) + { } + + template<typename _U1, typename _U2> + tuple& + operator=(const std::pair<_U1, _U2>& __u) + { + _M_arg1 = __u.first; + _M_arg2 = __u.second; + return *this; + } +#endif + +#if _GLIBCXX_NUM_ARGS > 0 + explicit tuple(_GLIBCXX_TUPLE_ADD_CREF) : + _GLIBCXX_BIND_MEMBERS_INIT + { } + + template<_GLIBCXX_TEMPLATE_PARAMS_U> + tuple(const tuple<_GLIBCXX_TEMPLATE_ARGS_U>& __in) : + _GLIBCXX_TUPLE_COPY_INIT + { } + + + template<_GLIBCXX_TEMPLATE_PARAMS_U> + tuple& + operator=(const tuple<_GLIBCXX_TEMPLATE_ARGS_U>& __in) + { + _GLIBCXX_TUPLE_ASSIGN + return *this; + } + + tuple(const tuple& __in) : + _GLIBCXX_TUPLE_COPY_INIT + { } + +#else + + tuple(const tuple&) + { } + +#endif + + tuple& + operator=(const tuple& __in __attribute__((__unused__)) ) + { + _GLIBCXX_TUPLE_ASSIGN + return *this; + } + + template<int __i, typename __Type> + friend class __get_helper; + + template<_GLIBCXX_TUPLE_ALL_TEMPLATE_PARAMS_UNNAMED> + friend class tuple; + }; + +#ifndef _GLIBCXX_LAST_INCLUDE + +template<typename _Tp> + struct __get_helper<_GLIBCXX_NUM_ARGS, _Tp> + { + static typename __add_ref<typename tuple_element<_GLIBCXX_NUM_ARGS, + _Tp>::type>::type + get_value(_Tp& __in) + { return __in._GLIBCXX_CAT(_M_arg,_GLIBCXX_NUM_ARGS_PLUS_1); } + + static typename __add_c_ref<typename tuple_element<_GLIBCXX_NUM_ARGS, + _Tp>::type>::type + get_value(const _Tp& __in) + { return __in._GLIBCXX_CAT(_M_arg,_GLIBCXX_NUM_ARGS_PLUS_1); } + }; + +/// @brief class tuple_element +template<_GLIBCXX_TUPLE_ALL_TEMPLATE_PARAMS> + struct tuple_element<_GLIBCXX_NUM_ARGS, tuple<_GLIBCXX_TUPLE_ALL_TEMPLATE_ARGS> > + { typedef _GLIBCXX_T_NUM_ARGS_PLUS_1 type; }; + +#endif +#if _GLIBCXX_NUM_ARGS == 0 + +tuple<> +inline make_tuple() +{ return tuple<>(); } + +tuple<> +inline tie() +{ return tuple<>(); } +#else + +template<_GLIBCXX_TEMPLATE_PARAMS> + typename __stripped_tuple_type<_GLIBCXX_TEMPLATE_ARGS>::__type + inline make_tuple(_GLIBCXX_PARAMS) + { + return typename __stripped_tuple_type<_GLIBCXX_TEMPLATE_ARGS>:: + __type(_GLIBCXX_ARGS); + } + +template<_GLIBCXX_TEMPLATE_PARAMS> + tuple<_GLIBCXX_REF_TEMPLATE_ARGS> + inline tie(_GLIBCXX_REF_PARAMS) + { return make_tuple(_GLIBCXX_REF_WRAP_PARAMS); } +#endif + +_GLIBCXX_END_NAMESPACE +} diff --git a/libstdc++/include/tr1/type_traits b/libstdc++/include/tr1/type_traits new file mode 100644 index 0000000..0481801 --- /dev/null +++ b/libstdc++/include/tr1/type_traits @@ -0,0 +1,703 @@ +// TR1 type_traits -*- C++ -*- + +// 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. + +/** @file tr1/type_traits + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_TYPE_TRAITS +#define _TR1_TYPE_TRAITS 1 + +#include <bits/c++config.h> +#include <tr1/type_traits_fwd.h> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // For use in __in_array and elsewhere. + struct __sfinae_types + { + typedef char __one; + typedef struct { char __arr[2]; } __two; + }; + + template<typename _Tp> + struct __in_array + : public __sfinae_types + { + private: + template<typename _Up> + static __one __test(_Up(*)[1]); + template<typename> + static __two __test(...); + + public: + static const bool __value = sizeof(__test<_Tp>(0)) == 1; + }; + +#define _DEFINE_SPEC_BODY(_Value) \ + : public integral_constant<bool, _Value> { }; + +#define _DEFINE_SPEC_0_HELPER(_Spec, _Value) \ + template<> \ + struct _Spec \ + _DEFINE_SPEC_BODY(_Value) + +#define _DEFINE_SPEC_1_HELPER(_Spec, _Value) \ + template<typename _Tp> \ + struct _Spec \ + _DEFINE_SPEC_BODY(_Value) + +#define _DEFINE_SPEC_2_HELPER(_Spec, _Value) \ + template<typename _Tp, typename _Cp> \ + struct _Spec \ + _DEFINE_SPEC_BODY(_Value) + +#define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ + _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value) \ + _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value) \ + _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value) \ + _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value) + + /// @brief helper classes [4.3]. + template<typename _Tp, _Tp __v> + struct integral_constant + { + static const _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant<_Tp, __v> type; + }; + typedef integral_constant<bool, true> true_type; + typedef integral_constant<bool, false> false_type; + + template<typename _Tp, _Tp __v> + const _Tp integral_constant<_Tp, __v>::value; + + /// @brief primary type categories [4.5.1]. + template<typename> + struct is_void + : public false_type { }; + _DEFINE_SPEC(0, is_void, void, true) + + template<typename> + struct is_integral + : public false_type { }; + _DEFINE_SPEC(0, is_integral, bool, true) + _DEFINE_SPEC(0, is_integral, char, true) + _DEFINE_SPEC(0, is_integral, signed char, true) + _DEFINE_SPEC(0, is_integral, unsigned char, true) +#ifdef _GLIBCXX_USE_WCHAR_T + _DEFINE_SPEC(0, is_integral, wchar_t, true) +#endif + _DEFINE_SPEC(0, is_integral, short, true) + _DEFINE_SPEC(0, is_integral, unsigned short, true) + _DEFINE_SPEC(0, is_integral, int, true) + _DEFINE_SPEC(0, is_integral, unsigned int, true) + _DEFINE_SPEC(0, is_integral, long, true) + _DEFINE_SPEC(0, is_integral, unsigned long, true) + _DEFINE_SPEC(0, is_integral, long long, true) + _DEFINE_SPEC(0, is_integral, unsigned long long, true) + + template<typename> + struct is_floating_point + : public false_type { }; + _DEFINE_SPEC(0, is_floating_point, float, true) + _DEFINE_SPEC(0, is_floating_point, double, true) + _DEFINE_SPEC(0, is_floating_point, long double, true) + + template<typename> + struct is_array + : public false_type { }; + + template<typename _Tp, std::size_t _Size> + struct is_array<_Tp[_Size]> + : public true_type { }; + + template<typename _Tp> + struct is_array<_Tp[]> + : public true_type { }; + + template<typename> + struct is_pointer + : public false_type { }; + _DEFINE_SPEC(1, is_pointer, _Tp*, true) + + template<typename> + struct is_reference + : public false_type { }; + + template<typename _Tp> + struct is_reference<_Tp&> + : public true_type { }; + + template<typename> + struct is_member_object_pointer + : public false_type { }; + _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*, + !is_function<_Tp>::value) + + template<typename> + struct is_member_function_pointer + : public false_type { }; + _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*, + is_function<_Tp>::value) + + template<typename _Tp> + struct is_enum + : public integral_constant<bool, !(is_fundamental<_Tp>::value + || is_array<_Tp>::value + || is_pointer<_Tp>::value + || is_reference<_Tp>::value + || is_member_pointer<_Tp>::value + || is_function<_Tp>::value + || __is_union_or_class<_Tp>::value)> + { }; + + template<typename> + struct is_union { }; + + template<typename> + struct is_class { }; + + template<typename _Tp> + struct is_function + : public integral_constant<bool, !(__in_array<_Tp>::__value + || __is_union_or_class<_Tp>::value + || is_reference<_Tp>::value + || is_void<_Tp>::value)> + { }; + + /// @brief composite type traits [4.5.2]. + template<typename _Tp> + struct is_arithmetic + : public integral_constant<bool, (is_integral<_Tp>::value + || is_floating_point<_Tp>::value)> + { }; + + template<typename _Tp> + struct is_fundamental + : public integral_constant<bool, (is_arithmetic<_Tp>::value + || is_void<_Tp>::value)> + { }; + + template<typename _Tp> + struct is_object + : public integral_constant<bool, !(is_function<_Tp>::value + || is_reference<_Tp>::value + || is_void<_Tp>::value)> + { }; + + template<typename _Tp> + struct is_scalar + : public integral_constant<bool, (is_arithmetic<_Tp>::value + || is_enum<_Tp>::value + || is_pointer<_Tp>::value + || is_member_pointer<_Tp>::value)> + { }; + + template<typename _Tp> + struct is_compound + : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; + + template<typename _Tp> + struct is_member_pointer + : public integral_constant<bool, + (is_member_object_pointer<_Tp>::value + || is_member_function_pointer<_Tp>::value)> + { }; + + template<typename _Tp> + struct __is_union_or_class_helper + : public __sfinae_types + { + private: + template<typename _Up> + static __one __test(int _Up::*); + template<typename> + static __two __test(...); + + public: + static const bool __value = sizeof(__test<_Tp>(0)) == 1; + }; + + // Extension. + template<typename _Tp> + struct __is_union_or_class + : public integral_constant<bool, __is_union_or_class_helper<_Tp>::__value> + { }; + + /// @brief type properties [4.5.3]. + template<typename> + struct is_const + : public false_type { }; + + template<typename _Tp> + struct is_const<_Tp const> + : public true_type { }; + + template<typename> + struct is_volatile + : public false_type { }; + + template<typename _Tp> + struct is_volatile<_Tp volatile> + : public true_type { }; + + template<typename _Tp> + struct is_pod + : public integral_constant<bool, (is_void<_Tp>::value + || is_scalar<typename + remove_all_extents<_Tp>::type>::value)> + { }; + + // NB: Without compiler support we cannot tell union from class types, + // and is_empty and is_polymorphic don't work at all with the former. + template<typename _Tp, bool = !__is_union_or_class<_Tp>::value> + struct __is_empty_helper + { + private: + template<typename> + struct __first { }; + template<typename _Up> + struct __second + : public _Up { }; + + public: + static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>); + }; + + template<typename _Tp> + struct __is_empty_helper<_Tp, true> + { static const bool __value = false; }; + + template<typename _Tp> + struct is_empty + : public integral_constant<bool, __is_empty_helper<_Tp>::__value> + { }; + + template<typename _Tp, bool = !__is_union_or_class<_Tp>::value> + struct __is_polymorphic_helper + { + private: + template<typename _Up> + struct __first + : public _Up { }; + template<typename _Up> + struct __second + : public _Up + { + virtual void __dummy(); + virtual ~__second() throw(); + }; + + public: + static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>); + }; + + template<typename _Tp> + struct __is_polymorphic_helper<_Tp, true> + { static const bool __value = false; }; + + template<typename _Tp> + struct is_polymorphic + : public integral_constant<bool, __is_polymorphic_helper<_Tp>::__value> + { }; + + // Exploit the resolution DR core/337. + template<typename _Tp> + struct is_abstract + : public integral_constant<bool, (!__in_array<_Tp>::__value + && __is_union_or_class<_Tp>::value)> { }; + + template<typename _Tp> + struct has_trivial_constructor + : public integral_constant<bool, is_pod<_Tp>::value> { }; + + template<typename _Tp> + struct has_trivial_copy + : public integral_constant<bool, is_pod<_Tp>::value> { }; + + template<typename _Tp> + struct has_trivial_assign + : public integral_constant<bool, is_pod<_Tp>::value> { }; + + template<typename _Tp> + struct has_trivial_destructor + : public integral_constant<bool, is_pod<_Tp>::value> { }; + + template<typename _Tp> + struct has_nothrow_constructor + : public integral_constant<bool, is_pod<_Tp>::value> { }; + + template<typename _Tp> + struct has_nothrow_copy + : public integral_constant<bool, is_pod<_Tp>::value> { }; + + template<typename _Tp> + struct has_nothrow_assign + : public integral_constant<bool, is_pod<_Tp>::value> { }; + + template<typename> + struct has_virtual_destructor + : public false_type { }; + + template<typename> + struct is_signed + : public false_type { }; + _DEFINE_SPEC(0, is_signed, signed char, true) + _DEFINE_SPEC(0, is_signed, short, true) + _DEFINE_SPEC(0, is_signed, int, true) + _DEFINE_SPEC(0, is_signed, long, true) + _DEFINE_SPEC(0, is_signed, long long, true) + + template<typename> + struct is_unsigned + : public false_type { }; + _DEFINE_SPEC(0, is_unsigned, unsigned char, true) + _DEFINE_SPEC(0, is_unsigned, unsigned short, true) + _DEFINE_SPEC(0, is_unsigned, unsigned int, true) + _DEFINE_SPEC(0, is_unsigned, unsigned long, true) + _DEFINE_SPEC(0, is_unsigned, unsigned long long, true) + + template<typename _Tp> + struct alignment_of + : public integral_constant<std::size_t, __alignof__(_Tp)> { }; + + template<typename> + struct rank + : public integral_constant<std::size_t, 0> { }; + + template<typename _Tp, std::size_t _Size> + struct rank<_Tp[_Size]> + : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; + + template<typename _Tp> + struct rank<_Tp[]> + : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; + + template<typename, unsigned> + struct extent + : public integral_constant<std::size_t, 0> { }; + + template<typename _Tp, unsigned _Uint, std::size_t _Size> + struct extent<_Tp[_Size], _Uint> + : public integral_constant<std::size_t, + _Uint == 0 ? _Size : extent<_Tp, + _Uint - 1>::value> + { }; + + template<typename _Tp, unsigned _Uint> + struct extent<_Tp[], _Uint> + : public integral_constant<std::size_t, + _Uint == 0 ? 0 : extent<_Tp, + _Uint - 1>::value> + { }; + + /// @brief relationships between types [4.6]. + template<typename, typename> + struct is_same + : public false_type { }; + + template<typename _Tp> + struct is_same<_Tp, _Tp> + : public true_type { }; + + // See Daveed Vandevoorde explanation in http://tinyurl.com/502f. + // Also see Rani Sharoni in http://tinyurl.com/6jvyq. + template<typename _Base, typename _Derived, + bool = (!__is_union_or_class<_Base>::value + || !__is_union_or_class<_Derived>::value + || is_same<_Base, _Derived>::value)> + struct __is_base_of_helper + : public __sfinae_types + { + private: + typedef typename remove_cv<_Base>::type _NoCv_Base; + typedef typename remove_cv<_Derived>::type _NoCv_Derived; + + template<typename _Up> + static __one __test(_NoCv_Derived&, _Up); + static __two __test(_NoCv_Base&, int); + + struct _Conv + { + operator _NoCv_Derived&(); + operator _NoCv_Base&() const; + }; + + public: + static const bool __value = sizeof(__test(_Conv(), 0)) == 1; + }; + + template<typename _Base, typename _Derived> + struct __is_base_of_helper<_Base, _Derived, true> + { static const bool __value = is_same<_Base, _Derived>::value; }; + + template<typename _Base, typename _Derived> + struct is_base_of + : public integral_constant<bool, + __is_base_of_helper<_Base, _Derived>::__value> + { }; + + template<typename _From, typename _To> + struct __is_convertible_simple + : public __sfinae_types + { + private: + static __one __test(_To); + static __two __test(...); + static _From __makeFrom(); + + public: + static const bool __value = sizeof(__test(__makeFrom())) == 1; + }; + + template<typename _Tp> + struct __is_int_or_cref + { + typedef typename remove_reference<_Tp>::type __rr_Tp; + static const bool __value = (is_integral<_Tp>::value + || (is_integral<__rr_Tp>::value + && is_const<__rr_Tp>::value + && !is_volatile<__rr_Tp>::value)); + }; + + template<typename _From, typename _To, + bool = (is_void<_From>::value || is_void<_To>::value + || is_function<_To>::value || is_array<_To>::value + // This special case is here only to avoid warnings. + || (is_floating_point<typename + remove_reference<_From>::type>::value + && __is_int_or_cref<_To>::__value))> + struct __is_convertible_helper + { + // "An imaginary lvalue of type From...". + static const bool __value = (__is_convertible_simple<typename + add_reference<_From>::type, _To>::__value); + }; + + template<typename _From, typename _To> + struct __is_convertible_helper<_From, _To, true> + { static const bool __value = (is_void<_To>::value + || (__is_int_or_cref<_To>::__value + && !is_void<_From>::value)); }; + + template<typename _From, typename _To> + struct is_convertible + : public integral_constant<bool, + __is_convertible_helper<_From, _To>::__value> + { }; + + /// @brief const-volatile modifications [4.7.1]. + template<typename _Tp> + struct remove_const + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_const<_Tp const> + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_volatile + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_volatile<_Tp volatile> + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_cv + { + typedef typename + remove_const<typename remove_volatile<_Tp>::type>::type type; + }; + + template<typename _Tp> + struct add_const + { typedef _Tp const type; }; + + template<typename _Tp> + struct add_volatile + { typedef _Tp volatile type; }; + + template<typename _Tp> + struct add_cv + { + typedef typename + add_const<typename add_volatile<_Tp>::type>::type type; + }; + + /// @brief reference modifications [4.7.2]. + template<typename _Tp> + struct remove_reference + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_reference<_Tp&> + { typedef _Tp type; }; + + // NB: Careful with reference to void. + template<typename _Tp, bool = (is_void<_Tp>::value + || is_reference<_Tp>::value)> + struct __add_reference_helper + { typedef _Tp& type; }; + + template<typename _Tp> + struct __add_reference_helper<_Tp, true> + { typedef _Tp type; }; + + template<typename _Tp> + struct add_reference + : public __add_reference_helper<_Tp> + { }; + + /// @brief array modifications [4.7.3]. + template<typename _Tp> + struct remove_extent + { typedef _Tp type; }; + + template<typename _Tp, std::size_t _Size> + struct remove_extent<_Tp[_Size]> + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_extent<_Tp[]> + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_all_extents + { typedef _Tp type; }; + + template<typename _Tp, std::size_t _Size> + struct remove_all_extents<_Tp[_Size]> + { typedef typename remove_all_extents<_Tp>::type type; }; + + template<typename _Tp> + struct remove_all_extents<_Tp[]> + { typedef typename remove_all_extents<_Tp>::type type; }; + + /// @brief pointer modifications [4.7.4]. +#undef _DEFINE_SPEC_BODY +#define _DEFINE_SPEC_BODY(_Value) \ + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_pointer + { typedef _Tp type; }; + _DEFINE_SPEC(1, remove_pointer, _Tp*, false) + + template<typename _Tp> + struct add_pointer + { typedef typename remove_reference<_Tp>::type* type; }; + + /// @brief other transformations [4.8]. + + // Due to c++/19163 and c++/17743, for the time being we cannot use + // the correct, neat implementation :-( + // + // template<std::size_t _Len, std::size_t _Align> + // struct aligned_storage + // { typedef char type[_Len] __attribute__((__aligned__(_Align))); } + // + // Temporary workaround, useful for Align up to 32: + template<std::size_t, std::size_t> + struct aligned_storage { }; + + template<std::size_t _Len> + struct aligned_storage<_Len, 1> + { + union type + { + unsigned char __data[_Len]; + char __align __attribute__((__aligned__(1))); + }; + }; + + template<std::size_t _Len> + struct aligned_storage<_Len, 2> + { + union type + { + unsigned char __data[_Len]; + char __align __attribute__((__aligned__(2))); + }; + }; + + template<std::size_t _Len> + struct aligned_storage<_Len, 4> + { + union type + { + unsigned char __data[_Len]; + char __align __attribute__((__aligned__(4))); + }; + }; + + template<std::size_t _Len> + struct aligned_storage<_Len, 8> + { + union type + { + unsigned char __data[_Len]; + char __align __attribute__((__aligned__(8))); + }; + }; + + template<std::size_t _Len> + struct aligned_storage<_Len, 16> + { + union type + { + unsigned char __data[_Len]; + char __align __attribute__((__aligned__(16))); + }; + }; + + template<std::size_t _Len> + struct aligned_storage<_Len, 32> + { + union type + { + unsigned char __data[_Len]; + char __align __attribute__((__aligned__(32))); + }; + }; + +#undef _DEFINE_SPEC_0_HELPER +#undef _DEFINE_SPEC_1_HELPER +#undef _DEFINE_SPEC_2_HELPER +#undef _DEFINE_SPEC +#undef _DEFINE_SPEC_BODY + +_GLIBCXX_END_NAMESPACE +} + +#endif diff --git a/libstdc++/include/tr1/type_traits_fwd.h b/libstdc++/include/tr1/type_traits_fwd.h new file mode 100644 index 0000000..819bb91 --- /dev/null +++ b/libstdc++/include/tr1/type_traits_fwd.h @@ -0,0 +1,226 @@ +// TR1 type_traits -*- C++ -*- + +// 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. + +/** @file tr1/type_traits_fwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TYPE_TRAITS_FWD_H +#define _TYPE_TRAITS_FWD_H 1 + +#include <cstddef> + +// namespace std::tr1 +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + /// @brief helper classes [4.3]. + template<typename _Tp, _Tp __v> + struct integral_constant; + typedef integral_constant<bool, true> true_type; + typedef integral_constant<bool, false> false_type; + + /// @brief primary type categories [4.5.1]. + template<typename _Tp> + struct is_void; + + template<typename _Tp> + struct is_integral; + + template<typename _Tp> + struct is_floating_point; + + template<typename _Tp> + struct is_array; + + template<typename _Tp> + struct is_pointer; + + template<typename _Tp> + struct is_reference; + + template<typename _Tp> + struct is_member_object_pointer; + + template<typename _Tp> + struct is_member_function_pointer; + + template<typename _Tp> + struct is_enum; + + template<typename _Tp> + struct is_union; + + template<typename _Tp> + struct is_class; + + template<typename _Tp> + struct is_function; + + /// @brief composite type traits [4.5.2]. + template<typename _Tp> + struct is_arithmetic; + + template<typename _Tp> + struct is_fundamental; + + template<typename _Tp> + struct is_object; + + template<typename _Tp> + struct is_scalar; + + template<typename _Tp> + struct is_compound; + + template<typename _Tp> + struct is_member_pointer; + + // Extension. + template<typename _Tp> + struct __is_union_or_class; + + /// @brief type properties [4.5.3]. + template<typename _Tp> + struct is_const; + + template<typename _Tp> + struct is_volatile; + + template<typename _Tp> + struct is_pod; + + template<typename _Tp> + struct is_empty; + + template<typename _Tp> + struct is_polymorphic; + + template<typename _Tp> + struct is_abstract; + + template<typename _Tp> + struct has_trivial_constructor; + + template<typename _Tp> + struct has_trivial_copy; + + template<typename _Tp> + struct has_trivial_assign; + + template<typename _Tp> + struct has_trivial_destructor; + + template<typename _Tp> + struct has_nothrow_constructor; + + template<typename _Tp> + struct has_nothrow_copy; + + template<typename _Tp> + struct has_nothrow_assign; + + template<typename _Tp> + struct has_virtual_destructor; + + template<typename _Tp> + struct is_signed; + + template<typename _Tp> + struct is_unsigned; + + template<typename _Tp> + struct alignment_of; + + template<typename _Tp> + struct rank; + + template<typename _Tp, unsigned _Uint = 0> + struct extent; + + /// @brief relationships between types [4.6]. + template<typename _Tp, typename _Up> + struct is_same; + + template<typename _From, typename _To> + struct is_convertible; + + template<typename _Base, typename _Derived> + struct is_base_of; + + /// @brief const-volatile modifications [4.7.1]. + template<typename _Tp> + struct remove_const; + + template<typename _Tp> + struct remove_volatile; + + template<typename _Tp> + struct remove_cv; + + template<typename _Tp> + struct add_const; + + template<typename _Tp> + struct add_volatile; + + template<typename _Tp> + struct add_cv; + + /// @brief reference modifications [4.7.2]. + template<typename _Tp> + struct remove_reference; + + template<typename _Tp> + struct add_reference; + + /// @brief array modifications [4.7.3]. + template<typename _Tp> + struct remove_extent; + + template<typename _Tp> + struct remove_all_extents; + + /// @brief pointer modifications [4.7.4]. + template<typename _Tp> + struct remove_pointer; + + template<typename _Tp> + struct add_pointer; + + /// @brief other transformations [4.8]. + template<std::size_t _Len, std::size_t _Align> + struct aligned_storage; + +_GLIBCXX_END_NAMESPACE +} + +#endif diff --git a/libstdc++/include/tr1/unordered_map b/libstdc++/include/tr1/unordered_map new file mode 100644 index 0000000..d613d15 --- /dev/null +++ b/libstdc++/include/tr1/unordered_map @@ -0,0 +1,168 @@ +// TR1 unordered_map -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 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. + +/** @file tr1/unordered_map + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_UNORDERED_MAP +#define _TR1_UNORDERED_MAP 1 + +#include <tr1/hashtable> +#include <tr1/functional_hash.h> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // XXX When we get typedef templates these class definitions + // will be unnecessary. + template<class _Key, class _Tp, + class _Hash = hash<_Key>, + class _Pred = std::equal_to<_Key>, + class _Alloc = std::allocator<std::pair<const _Key, _Tp> >, + bool __cache_hash_code = false> + class unordered_map + : public _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, + std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, false, true> + { + typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, + std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, false, true> + _Base; + + public: + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + unordered_map(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), + __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + { } + + template<typename _InputIterator> + unordered_map(_InputIterator __f, _InputIterator __l, + size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), + __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + { } + }; + + template<class _Key, class _Tp, + class _Hash = hash<_Key>, + class _Pred = std::equal_to<_Key>, + class _Alloc = std::allocator<std::pair<const _Key, _Tp> >, + bool __cache_hash_code = false> + class unordered_multimap + : public _Hashtable<_Key, std::pair<const _Key, _Tp>, + _Alloc, + std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, false, false> + { + typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, + _Alloc, + std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, false, false> + _Base; + + public: + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + unordered_multimap(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), + __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + { } + + + template<typename _InputIterator> + unordered_multimap(_InputIterator __f, _InputIterator __l, + typename _Base::size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), + __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + { } + }; + + template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, + bool __cache_hash_code> + inline void + swap(unordered_map<_Key, _Tp, _Hash, _Pred, + _Alloc, __cache_hash_code>& __x, + unordered_map<_Key, _Tp, _Hash, _Pred, + _Alloc, __cache_hash_code>& __y) + { __x.swap(__y); } + + template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, + bool __cache_hash_code> + inline void + swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, + _Alloc, __cache_hash_code>& __x, + unordered_multimap<_Key, _Tp, _Hash, _Pred, + _Alloc, __cache_hash_code>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NAMESPACE +} + +#endif // _TR1_UNORDERED_MAP diff --git a/libstdc++/include/tr1/unordered_set b/libstdc++/include/tr1/unordered_set new file mode 100644 index 0000000..a01b89b --- /dev/null +++ b/libstdc++/include/tr1/unordered_set @@ -0,0 +1,166 @@ +// TR1 unordered_set -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 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. + +/** @file tr1/unordered_set + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_UNORDERED_SET +#define _TR1_UNORDERED_SET 1 + +#include <tr1/hashtable> +#include <tr1/functional_hash.h> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + // XXX When we get typedef templates these class definitions + // will be unnecessary. + template<class _Value, + class _Hash = hash<_Value>, + class _Pred = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value>, + bool __cache_hash_code = false> + class unordered_set + : public _Hashtable<_Value, _Value, _Alloc, + std::_Identity<_Value>, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, true, true> + { + typedef _Hashtable<_Value, _Value, _Alloc, + std::_Identity<_Value>, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, true, true> + _Base; + + public: + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + unordered_set(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), __eql, + std::_Identity<_Value>(), __a) + { } + + template<typename _InputIterator> + unordered_set(_InputIterator __f, _InputIterator __l, + size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), __eql, + std::_Identity<_Value>(), __a) + { } + }; + + template<class _Value, + class _Hash = hash<_Value>, + class _Pred = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value>, + bool __cache_hash_code = false> + class unordered_multiset + : public _Hashtable<_Value, _Value, _Alloc, + std::_Identity<_Value>, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, true, false> + { + typedef _Hashtable<_Value, _Value, _Alloc, + std::_Identity<_Value>, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, true, false> + _Base; + + public: + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + unordered_multiset(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), __eql, + std::_Identity<_Value>(), __a) + { } + + + template<typename _InputIterator> + unordered_multiset(_InputIterator __f, _InputIterator __l, + typename _Base::size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), __eql, + std::_Identity<_Value>(), __a) + { } + }; + + template<class _Value, class _Hash, class _Pred, class _Alloc, + bool __cache_hash_code> + inline void + swap (unordered_set<_Value, _Hash, _Pred, + _Alloc, __cache_hash_code>& __x, + unordered_set<_Value, _Hash, _Pred, + _Alloc, __cache_hash_code>& __y) + { __x.swap(__y); } + + template<class _Value, class _Hash, class _Pred, class _Alloc, + bool __cache_hash_code> + inline void + swap(unordered_multiset<_Value, _Hash, _Pred, + _Alloc, __cache_hash_code>& __x, + unordered_multiset<_Value, _Hash, _Pred, + _Alloc, __cache_hash_code>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NAMESPACE +} + +#endif // _TR1_UNORDERED_SET diff --git a/libstdc++/include/tr1/utility b/libstdc++/include/tr1/utility new file mode 100644 index 0000000..93e00eb --- /dev/null +++ b/libstdc++/include/tr1/utility @@ -0,0 +1,102 @@ +// TR1 utility -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006, 2007 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. + +/** @file tr1/utility + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_UTILITY +#define _TR1_UTILITY 1 + +#include "../utility" + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE(tr1) + + template<class _Tp> class tuple_size; + template<int _Int, class _Tp> class tuple_element; + + // Various functions which give std::pair a tuple-like interface. + template<class _Tp1, class _Tp2> + struct tuple_size<std::pair<_Tp1, _Tp2> > + { static const int value = 2; }; + + template<class _Tp1, class _Tp2> + const int tuple_size<std::pair<_Tp1, _Tp2> >::value; + + template<class _Tp1, class _Tp2> + struct tuple_element<0, std::pair<_Tp1, _Tp2> > + { typedef _Tp1 type; }; + + template<class _Tp1, class _Tp2> + struct tuple_element<1, std::pair<_Tp1, _Tp2> > + { typedef _Tp2 type; }; + + + template<int _Int> struct __pair_get; + + template<> + struct __pair_get<0> + { + template<typename _Tp1, typename _Tp2> + static _Tp1& __get(std::pair<_Tp1, _Tp2>& __pair) + { return __pair.first; } + + template<typename _Tp1, typename _Tp2> + static const _Tp1& __const_get(const std::pair<_Tp1, _Tp2>& __pair) + { return __pair.first; } + }; + + template<> + struct __pair_get<1> + { + template<typename _Tp1, typename _Tp2> + static _Tp2& __get(std::pair<_Tp1, _Tp2>& __pair) + { return __pair.second; } + + template<typename _Tp1, typename _Tp2> + static const _Tp2& __const_get(const std::pair<_Tp1, _Tp2>& __pair) + { return __pair.second; } + }; + + template<int _Int, class _Tp1, class _Tp2> + inline typename tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& + get(std::pair<_Tp1, _Tp2>& __in) + { return __pair_get<_Int>::__get(__in); } + + template<int _Int, class _Tp1, class _Tp2> + inline const typename tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& + get(const std::pair<_Tp1, _Tp2>& __in) + { return __pair_get<_Int>::__const_get(__in); } + +_GLIBCXX_END_NAMESPACE +} + +#endif diff --git a/libstdc++/include/tr1/wchar.h b/libstdc++/include/tr1/wchar.h new file mode 100644 index 0000000..00fb8a0 --- /dev/null +++ b/libstdc++/include/tr1/wchar.h @@ -0,0 +1,39 @@ +// TR1 wchar.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/wchar.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_WCHAR_H +#define _TR1_WCHAR_H 1 + +#include <tr1/cwchar> + +#endif diff --git a/libstdc++/include/tr1/wctype.h b/libstdc++/include/tr1/wctype.h new file mode 100644 index 0000000..9ef23cd --- /dev/null +++ b/libstdc++/include/tr1/wctype.h @@ -0,0 +1,39 @@ +// TR1 wctype.h -*- C++ -*- + +// Copyright (C) 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. + +/** @file tr1/wctype.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_WCTYPE_H +#define _TR1_WCTYPE_H 1 + +#include <tr1/cwctype> + +#endif |