Repository: gatieme/STLSourceAnalysis Branch: master Commit: 55ade9a507a7 Files: 535 Total size: 2.3 MB Directory structure: gitextract_3mc_7onk/ ├── stl-3.3-source/ │ ├── algo.h │ ├── algobase.h │ ├── algorithm │ ├── alloc.h │ ├── bitset │ ├── bvector.h │ ├── char_traits.h │ ├── concept_checks.h │ ├── container_concepts.h │ ├── defalloc.h │ ├── deque │ ├── deque.h │ ├── function.h │ ├── functional │ ├── hash_map │ ├── hash_map.h │ ├── hash_set │ ├── hash_set.h │ ├── hashtable.h │ ├── heap.h │ ├── iterator │ ├── iterator.h │ ├── limits │ ├── list │ ├── list.h │ ├── map │ ├── map.h │ ├── memory │ ├── multimap.h │ ├── multiset.h │ ├── numeric │ ├── pair.h │ ├── pthread_alloc │ ├── pthread_alloc.h │ ├── queue │ ├── rope │ ├── rope.h │ ├── ropeimpl.h │ ├── sequence_concepts.h │ ├── set │ ├── set.h │ ├── slist │ ├── slist.h │ ├── stack │ ├── stack.h │ ├── stdexcept │ ├── stl-3.3.IAB │ ├── stl-3.3.IAD │ ├── stl-3.3.IMB │ ├── stl-3.3.IMD │ ├── stl-3.3.PFI │ ├── stl-3.3.PO │ ├── stl-3.3.PR │ ├── stl-3.3.PRI │ ├── stl-3.3.PS │ ├── stl-3.3.SearchResults │ ├── stl-3.3.WK3 │ ├── stl_algo.h │ ├── stl_algobase.h │ ├── stl_alloc.h │ ├── stl_bvector.h │ ├── stl_config.h │ ├── stl_construct.h │ ├── stl_ctraits_fns.h │ ├── stl_deque.h │ ├── stl_exception.h │ ├── stl_function.h │ ├── stl_hash_fun.h │ ├── stl_hash_map.h │ ├── stl_hash_set.h │ ├── stl_hashtable.h │ ├── stl_heap.h │ ├── stl_iterator.h │ ├── stl_iterator_base.h │ ├── stl_list.h │ ├── stl_map.h │ ├── stl_multimap.h │ ├── stl_multiset.h │ ├── stl_numeric.h │ ├── stl_pair.h │ ├── stl_queue.h │ ├── stl_range_errors.h │ ├── stl_raw_storage_iter.h │ ├── stl_relops.h │ ├── stl_rope.h │ ├── stl_set.h │ ├── stl_slist.h │ ├── stl_stack.h │ ├── stl_string_fwd.h │ ├── stl_tempbuf.h │ ├── stl_threads.h │ ├── stl_tree.h │ ├── stl_uninitialized.h │ ├── stl_vector.h │ ├── string │ ├── tempbuf.h │ ├── tree.h │ ├── type_traits.h │ ├── utility │ ├── valarray │ ├── vector │ └── vector.h ├── stl-gatieme/ │ ├── 1-stl_config/ │ │ ├── 1config-inclass-init.cpp │ │ ├── 1config-inclass-init.o │ │ ├── 1config-operator-overloading.cpp │ │ ├── 1config-operator-overloading.o │ │ ├── 1config-template-exp-special.cpp │ │ ├── 1config-template-exp-special.o │ │ ├── 1config-temporary-object.cpp │ │ ├── 1config-temporary-object.o │ │ ├── 1config.cpp │ │ ├── 1config.o │ │ ├── 1config10.cpp │ │ ├── 1config10.o │ │ ├── 1config11.cpp │ │ ├── 1config11.o │ │ ├── 1config2.cpp │ │ ├── 1config2.o │ │ ├── 1config3.cpp │ │ ├── 1config5.cpp │ │ ├── 1config5.o │ │ ├── 1config8.cpp │ │ ├── 1config8.o │ │ ├── 1functor.cpp │ │ ├── 1functor.o │ │ ├── 1qsort.cpp │ │ ├── 1qsort.o │ │ ├── Makefile │ │ └── stl_config.h │ ├── 2-defalloc/ │ │ ├── 2jjalloc.h │ │ ├── Makefile │ │ ├── README.md │ │ ├── defalloc.h │ │ ├── simple_jjallocator.h │ │ ├── stl_alloc.h │ │ └── test.cpp │ ├── 3-iterator/ │ │ ├── 3autoptr.cpp │ │ ├── 3find.cpp │ │ ├── 3function_template1.cpp │ │ ├── 3function_template2.cpp │ │ ├── 3function_template3.cpp │ │ ├── 3mylist.h │ │ ├── 3mylist_iter.h │ │ ├── 3mylist_iter_stl.h │ │ ├── 3mylist_iter_test.cpp │ │ ├── 3tag_test.cpp │ │ ├── 3templatespecial_class.cpp │ │ ├── 3templatespecial_func.cpp │ │ ├── 3test_typeid.cpp │ │ ├── Makefile │ │ ├── test_auto_ptr.cpp │ │ ├── test_bad_typeid.cpp │ │ └── typeinfo.h │ ├── 4-sequence-containers/ │ │ ├── 4deque_test.cpp │ │ ├── 4heap_test.cpp │ │ ├── 4queue_test.cpp │ │ ├── 4stack_test.cpp │ │ ├── 4vector_reset.cpp │ │ └── 4vector_test.cpp │ ├── Make.defines.freebsd │ ├── Make.defines.linux │ ├── Make.defines.macos │ ├── Make.defines.solaris │ ├── Makefile │ └── systype.sh ├── stl侯杰源码/ │ ├── Makefile │ ├── Makefile.h │ ├── README │ ├── algo/ │ │ ├── Makefile │ │ ├── accu1.cpp │ │ ├── adjdiff1.cpp │ │ ├── adjfind1.cpp │ │ ├── algostuff.hpp │ │ ├── bounds1.cpp │ │ ├── bsearch1.cpp │ │ ├── copy1.cpp │ │ ├── copy2.cpp │ │ ├── copy3.cpp │ │ ├── count1.cpp │ │ ├── eqrange1.cpp │ │ ├── equal1.cpp │ │ ├── fill1.cpp │ │ ├── find1.cpp │ │ ├── find2.cpp │ │ ├── findend1.cpp │ │ ├── findof1.cpp │ │ ├── foreach1.cpp │ │ ├── foreach2.cpp │ │ ├── foreach3.cpp │ │ ├── generate.cpp │ │ ├── heap1.cpp │ │ ├── imerge1.cpp │ │ ├── includes.cpp │ │ ├── inner1.cpp │ │ ├── lexico1.cpp │ │ ├── merge1.cpp │ │ ├── minmax1.cpp │ │ ├── misma1.cpp │ │ ├── nth1.cpp │ │ ├── part1.cpp │ │ ├── partsum1.cpp │ │ ├── perm1.cpp │ │ ├── psort1.cpp │ │ ├── psort2.cpp │ │ ├── random1.cpp │ │ ├── relabs.cpp │ │ ├── remove1.cpp │ │ ├── remove2.cpp │ │ ├── replace1.cpp │ │ ├── replace2.cpp │ │ ├── reverse1.cpp │ │ ├── rotate1.cpp │ │ ├── rotate2.cpp │ │ ├── search1.cpp │ │ ├── search2.cpp │ │ ├── searchn1.cpp │ │ ├── setalgos.cpp │ │ ├── sort1.cpp │ │ ├── sort2.cpp │ │ ├── swap1.cpp │ │ ├── transf1.cpp │ │ ├── transf2.cpp │ │ ├── unique1.cpp │ │ ├── unique2.cpp │ │ └── unique3.cpp │ ├── cont/ │ │ ├── Makefile │ │ ├── Queue.hpp │ │ ├── Stack.hpp │ │ ├── array1.cpp │ │ ├── bitset1.cpp │ │ ├── bitset2.cpp │ │ ├── carray.hpp │ │ ├── carray1.cpp │ │ ├── countptr.hpp │ │ ├── deque1.cpp │ │ ├── list1.cpp │ │ ├── map1.cpp │ │ ├── mapcmp.cpp │ │ ├── mapfind.cpp │ │ ├── mmap1.cpp │ │ ├── mset1.cpp │ │ ├── newkey.hpp │ │ ├── pqueue1.cpp │ │ ├── print.hpp │ │ ├── queue1.cpp │ │ ├── queue2.cpp │ │ ├── refsem1.cpp │ │ ├── set1.cpp │ │ ├── set2.cpp │ │ ├── setcmp.cpp │ │ ├── sortset.cpp │ │ ├── sortvec.cpp │ │ ├── stack1.cpp │ │ ├── stack2.cpp │ │ └── vector1.cpp │ ├── fo/ │ │ ├── Makefile │ │ ├── compose1.cpp │ │ ├── compose10.hpp │ │ ├── compose11.hpp │ │ ├── compose12.hpp │ │ ├── compose2.cpp │ │ ├── compose21.hpp │ │ ├── compose22.hpp │ │ ├── compose3.cpp │ │ ├── compose4.cpp │ │ ├── fopow.hpp │ │ ├── fopow1.cpp │ │ ├── foreach3.cpp │ │ ├── genera1.cpp │ │ ├── genera2.cpp │ │ ├── memfun1.cpp │ │ ├── nullary.hpp │ │ ├── print.hpp │ │ ├── removeif.cpp │ │ └── sort1.cpp │ ├── i18n/ │ │ ├── Makefile │ │ ├── loc1.cpp │ │ ├── loc2.cpp │ │ └── numget.cpp │ ├── io/ │ │ ├── Makefile │ │ ├── cat1.cpp │ │ ├── cat2.cpp │ │ ├── charcat1.cpp │ │ ├── charcat2.cpp │ │ ├── charset.cpp │ │ ├── copy1.cpp │ │ ├── copy2.cpp │ │ ├── countlines.cpp │ │ ├── frac1in.hpp │ │ ├── frac1out.hpp │ │ ├── frac2in.hpp │ │ ├── frac2out.hpp │ │ ├── ignore.hpp │ │ ├── ignore1.cpp │ │ ├── ignoreparam.hpp │ │ ├── ignoreparam1.cpp │ │ ├── inbuf1.cpp │ │ ├── inbuf1.hpp │ │ ├── io1.cpp │ │ ├── outbuf1.cpp │ │ ├── outbuf1.hpp │ │ ├── outbuf1x.cpp │ │ ├── outbuf1x.hpp │ │ ├── outbuf2.cpp │ │ ├── outbuf2.hpp │ │ ├── outbuf3.cpp │ │ ├── outbuf3.hpp │ │ ├── rdbuf1.cpp │ │ ├── rdbuf2.cpp │ │ ├── redirect.cpp │ │ ├── rw1.cpp │ │ ├── sstr1.cpp │ │ ├── sum1.cpp │ │ └── sum2.cpp │ ├── iter/ │ │ ├── Makefile │ │ ├── advance1.cpp │ │ ├── advance2.cpp │ │ ├── assoiter.cpp │ │ ├── assoiter.hpp │ │ ├── backins.cpp │ │ ├── distance.cpp │ │ ├── distance.hpp │ │ ├── frontins.cpp │ │ ├── inserter.cpp │ │ ├── istriter.cpp │ │ ├── itercat.cpp │ │ ├── ostriter.cpp │ │ ├── print.hpp │ │ ├── reviter1.cpp │ │ ├── reviter2.cpp │ │ ├── reviter3.cpp │ │ ├── reviter4.cpp │ │ └── swap1.cpp │ ├── memory/ │ │ ├── Makefile │ │ ├── myalloc.hpp │ │ └── myalloc1.cpp │ ├── num/ │ │ ├── Makefile │ │ ├── complex1.cpp │ │ ├── complex2.cpp │ │ ├── gslice1.cpp │ │ ├── indi1.cpp │ │ ├── masked1.cpp │ │ ├── slice1.cpp │ │ ├── val1.cpp │ │ └── val2.cpp │ ├── stl/ │ │ ├── Makefile │ │ ├── add1.cpp │ │ ├── algo1.cpp │ │ ├── copy1.cpp │ │ ├── copy2.cpp │ │ ├── copy3.cpp │ │ ├── deque1.cpp │ │ ├── find1.cpp │ │ ├── fo1.cpp │ │ ├── foreach1.cpp │ │ ├── foreach2.cpp │ │ ├── ioiter1.cpp │ │ ├── iterbug1.cpp │ │ ├── list1.cpp │ │ ├── list2.cpp │ │ ├── map1.cpp │ │ ├── mmap1.cpp │ │ ├── prime1.cpp │ │ ├── print.hpp │ │ ├── remove1.cpp │ │ ├── remove2.cpp │ │ ├── remove3.cpp │ │ ├── remove4.cpp │ │ ├── riter1.cpp │ │ ├── set1.cpp │ │ ├── sort1.cpp │ │ ├── transform1.cpp │ │ └── vector1.cpp │ ├── string/ │ │ ├── Makefile │ │ ├── icstring.hpp │ │ ├── icstring1.cpp │ │ ├── iter1.cpp │ │ ├── iter2.cpp │ │ ├── iter3.cpp │ │ ├── string1.cpp │ │ ├── string2.cpp │ │ └── unique.cpp │ └── util/ │ ├── Makefile │ ├── autoptr.hpp │ ├── autoptr1.cpp │ ├── autoptr2.cpp │ ├── defalloc.hpp │ ├── limits1.cpp │ └── minmax1.cpp └── tass-sgi-stl-2.91.57-source/ ├── JJHOU.TXT ├── PlotFile.h ├── SFile.h ├── algo.h ├── algobase.h ├── algorithm ├── alloc.h ├── builtinbuf.h ├── bvector.h ├── cassert ├── cctype ├── cerrno ├── cfloat ├── ciso646 ├── climits ├── clocale ├── cmath ├── complex ├── complex.h ├── csetjmp ├── csignal ├── cstdarg ├── cstddef ├── cstdio ├── cstdlib ├── cstring ├── ctime ├── cwchar ├── cwctype ├── defalloc.h ├── deque ├── deque.h ├── editbuf.h ├── floatio.h ├── fstream ├── fstream.h ├── function.h ├── functional ├── hash_map ├── hash_map.h ├── hash_set ├── hash_set.h ├── hashtable.h ├── heap.h ├── indstream.h ├── iolibio.h ├── iomanip ├── iomanip.h ├── iosfwd ├── iostdio.h ├── iostream ├── iostream.h ├── iostreamP.h ├── istream.h ├── iterator ├── iterator.h ├── libio.h ├── libioP.h ├── list ├── list.h ├── map ├── map.h ├── memory ├── multimap.h ├── multiset.h ├── numeric ├── ostream.h ├── pair.h ├── parsestream.h ├── pfstream.h ├── procbuf.h ├── pthread_alloc ├── pthread_alloc.h ├── queue ├── rope ├── rope.h ├── ropeimpl.h ├── set ├── set.h ├── sgi-stl-2.91.57-source.IAB ├── sgi-stl-2.91.57-source.IAD ├── sgi-stl-2.91.57-source.IMB ├── sgi-stl-2.91.57-source.IMD ├── sgi-stl-2.91.57-source.PFI ├── sgi-stl-2.91.57-source.PO ├── sgi-stl-2.91.57-source.PR ├── sgi-stl-2.91.57-source.PS ├── sgi-stl-2.91.57-source.WK3 ├── slist ├── slist.h ├── stack ├── stack.h ├── std/ │ ├── bastring.cc │ ├── bastring.h │ ├── complext.cc │ ├── complext.h │ ├── dcomplex.h │ ├── fcomplex.h │ ├── ldcomplex.h │ └── straits.h ├── stdexcept ├── stdiostream.h ├── stl.h ├── stl_algo.h ├── stl_algobase.h ├── stl_alloc.h ├── stl_bvector.h ├── stl_config.h ├── stl_construct.h ├── stl_deque.h ├── stl_function.h ├── stl_hash_fun.h ├── stl_hash_map.h ├── stl_hash_set.h ├── stl_hashtable.h ├── stl_heap.h ├── stl_iterator.h ├── stl_list.h ├── stl_map.h ├── stl_multimap.h ├── stl_multiset.h ├── stl_numeric.h ├── stl_pair.h ├── stl_queue.h ├── stl_raw_storage_iter.h ├── stl_relops.h ├── stl_rope.h ├── stl_set.h ├── stl_slist.h ├── stl_stack.h ├── stl_tempbuf.h ├── stl_tree.h ├── stl_uninitialized.h ├── stl_vector.h ├── stream.h ├── streambuf.h ├── strfile.h ├── string ├── strstream ├── strstream.h ├── tempbuf.h ├── tree.h ├── type_traits.h ├── utility ├── vector └── vector.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: stl-3.3-source/algo.h ================================================ /* * * 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 __SGI_STL_ALGO_H #define __SGI_STL_ALGO_H #include #include #include #include #ifdef __STL_USE_NAMESPACES // Names from 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::random_sample; using __STD::random_sample_n; 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; using __STD::is_sorted; using __STD::is_heap; // Names from stl_heap.h using __STD::push_heap; using __STD::pop_heap; using __STD::make_heap; using __STD::sort_heap; // Names from using __STD::accumulate; using __STD::inner_product; using __STD::partial_sum; using __STD::adjacent_difference; using __STD::power; using __STD::iota; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ALGO_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/algobase.h ================================================ /* * * 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 __SGI_STL_ALGOBASE_H #define __SGI_STL_ALGOBASE_H #ifndef __SGI_STL_PAIR_H #include #endif #ifndef __SGI_STL_ITERATOR_H #include #endif #ifndef __SGI_STL_INTERNAL_ALGOBASE_H #include #endif #ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H #include #endif #ifdef __STL_USE_NAMESPACES // 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::copy_n; using __STD::fill; using __STD::fill_n; using __STD::mismatch; using __STD::equal; using __STD::lexicographical_compare; using __STD::lexicographical_compare_3way; // Names from stl_uninitialized.h using __STD::uninitialized_copy; using __STD::uninitialized_copy_n; using __STD::uninitialized_fill; using __STD::uninitialized_fill_n; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ALGOBASE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/algorithm ================================================ /* * * 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 __SGI_STL_ALGORITHM #define __SGI_STL_ALGORITHM #include #include #include #include #include #endif /* __SGI_STL_ALGORITHM */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/alloc.h ================================================ /* * 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 __SGI_STL_ALLOC_H #define __SGI_STL_ALLOC_H #ifndef __STL_CONFIG_H #include #endif #ifndef __SGI_STL_INTERNAL_ALLOC_H #include #endif #ifdef __STL_USE_NAMESPACES using __STD::__malloc_alloc_template; using __STD::malloc_alloc; using __STD::simple_alloc; using __STD::debug_alloc; using __STD::__default_alloc_template; using __STD::alloc; using __STD::single_client_alloc; #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG using __STD::__malloc_alloc_oom_handler; #endif /* __STL_STATIC_TEMPLATE_MEMBER_BUG */ #ifdef __STL_USE_STD_ALLOCATORS using __STD::allocator; #endif /* __STL_USE_STD_ALLOCATORS */ #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ALLOC_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/bitset ================================================ /* * 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. */ #ifndef __SGI_STL_BITSET #define __SGI_STL_BITSET // A bitset of size N has N % (sizeof(unsigned long) * CHAR_BIT) unused // bits. (They are the high- order bits in the highest word.) It is // a class invariant of class bitset<> that those unused bits are // always zero. // 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. // The C++ standard does not define the precise semantics of operator[]. // In this implementation the const version of operator[] is equivalent // to test(), except that it does no range checking. The non-const version // returns a reference to a bit, again without doing any range checking. #include // for size_t #include // for memset #include #include // for invalid_argument, out_of_range, overflow_error #ifdef __STL_USE_NEW_IOSTREAMS #include #else #include // for istream, ostream #endif #define __BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long)) #define __BITSET_WORDS(__n) \ ((__n) < 1 ? 1 : ((__n) + __BITS_PER_WORD - 1)/__BITS_PER_WORD) __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1209 #endif // structure to aid in counting bits template struct _Bit_count { static unsigned char _S_bit_count[256]; }; // Mapping from 8 bit unsigned integers to the index of the first one // bit: template struct _First_one { static unsigned char _S_first_one[256]; }; // // Base class: general case. // template struct _Base_bitset { typedef unsigned long _WordT; _WordT _M_w[_Nw]; // 0 is the least significant word. _Base_bitset( void ) { _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 / __BITS_PER_WORD; } static size_t _S_whichbyte( size_t __pos ) { return (__pos % __BITS_PER_WORD) / CHAR_BIT; } static size_t _S_whichbit( size_t __pos ) { return __pos % __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() { 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; const unsigned char* __byte_ptr = (const unsigned char*)_M_w; const unsigned char* __end_ptr = (const unsigned char*)(_M_w+_Nw); while ( __byte_ptr < __end_ptr ) { __result += _Bit_count::_S_bit_count[*__byte_ptr]; __byte_ptr++; } 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 void _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) { if (__shift != 0) { const size_t __wshift = __shift / __BITS_PER_WORD; const size_t __offset = __shift % __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 = __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; } fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); } } template void _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) { if (__shift != 0) { const size_t __wshift = __shift / __BITS_PER_WORD; const size_t __offset = __shift % __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 = __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; } fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); } } template unsigned long _Base_bitset<_Nw>::_M_do_to_ulong() const { for (size_t __i = 1; __i < _Nw; ++__i) if (_M_w[__i]) __STL_THROW(overflow_error("bitset")); return _M_w[0]; } template 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) ) { // find byte within word for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { unsigned char __this_byte = static_cast(__thisword & (~(unsigned char)0)); if ( __this_byte ) return __i*__BITS_PER_WORD + __j*CHAR_BIT + _First_one::_S_first_one[__this_byte]; __thisword >>= CHAR_BIT; } } } // not found, so return an indication of failure. return __not_found; } template 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 * __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) ) { // find byte within word // get first byte into place __thisword >>= _S_whichbyte(__prev) * CHAR_BIT; for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) { unsigned char __this_byte = static_cast(__thisword & (~(unsigned char)0)); if ( __this_byte ) return __i*__BITS_PER_WORD + __j*CHAR_BIT + _First_one::_S_first_one[__this_byte]; __thisword >>= CHAR_BIT; } } // check subsequent words __i++; for ( ; __i < _Nw; __i++ ) { _WordT __thisword = _M_w[__i]; if ( __thisword != static_cast<_WordT>(0) ) { // find byte within word for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { unsigned char __this_byte = static_cast(__thisword & (~(unsigned char)0)); if ( __this_byte ) return __i*__BITS_PER_WORD + __j*CHAR_BIT + _First_one::_S_first_one[__this_byte]; __thisword >>= CHAR_BIT; } } } // not found, so return an indication of failure. return __not_found; } // end _M_do_find_next // ------------------------------------------------------------ // // Base class: specialization for a single word. // __STL_TEMPLATE_NULL 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 / __BITS_PER_WORD; } static size_t _S_whichbyte( size_t __pos ) { return (__pos % __BITS_PER_WORD) / CHAR_BIT; } static size_t _S_whichbit( size_t __pos ) { return __pos % __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 { size_t __result = 0; const unsigned char* __byte_ptr = (const unsigned char*)&_M_w; const unsigned char* __end_ptr = ((const unsigned char*)&_M_w)+sizeof(_M_w); while ( __byte_ptr < __end_ptr ) { __result += _Bit_count::_S_bit_count[*__byte_ptr]; __byte_ptr++; } return __result; } unsigned long _M_do_to_ulong() const { return _M_w; } 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 the single-word version of // _Base_bitset. // size_t _Base_bitset<1>::_M_do_find_first(size_t __not_found) const { _WordT __thisword = _M_w; if ( __thisword != static_cast<_WordT>(0) ) { // find byte within word for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { unsigned char __this_byte = static_cast(__thisword & (~(unsigned char)0)); if ( __this_byte ) return __j*CHAR_BIT + _First_one::_S_first_one[__this_byte]; __thisword >>= CHAR_BIT; } } // not found, so return a value that indicates failure. return __not_found; } size_t _Base_bitset<1>::_M_do_find_next(size_t __prev, size_t __not_found ) const { // make bound inclusive ++__prev; // check out of bounds if ( __prev >= __BITS_PER_WORD ) return __not_found; // search first (and only) word _WordT __thisword = _M_w; // mask off bits below bound __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); if ( __thisword != static_cast<_WordT>(0) ) { // find byte within word // get first byte into place __thisword >>= _S_whichbyte(__prev) * CHAR_BIT; for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) { unsigned char __this_byte = static_cast(__thisword & (~(unsigned char)0)); if ( __this_byte ) return __j*CHAR_BIT + _First_one::_S_first_one[__this_byte]; __thisword >>= CHAR_BIT; } } // not found, so return a value that indicates failure. return __not_found; } // end _M_do_find_next // ------------------------------------------------------------ // Helper class to zero out the unused high-order bits in the highest word. template struct _Sanitize { static void _M_do_sanitize(unsigned long& __val) { __val &= ~((~static_cast(0)) << _Extrabits); } }; __STL_TEMPLATE_NULL struct _Sanitize<0> { static void _M_do_sanitize(unsigned long) {} }; // ------------------------------------------------------------ // Class bitset. // _Nb may be any nonzero number of type size_t. template class bitset : private _Base_bitset<__BITSET_WORDS(_Nb)> { private: typedef _Base_bitset<__BITSET_WORDS(_Nb)> _Base; typedef unsigned long _WordT; private: void _M_do_sanitize() { _Sanitize<_Nb%__BITS_PER_WORD>::_M_do_sanitize(this->_M_hiword()); } public: // bit reference: class reference; friend class reference; 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; } }; // 23.3.5.1 constructors: bitset() {} bitset(unsigned long __val) : _Base_bitset<__BITSET_WORDS(_Nb)>(__val) { _M_do_sanitize(); } #ifdef __STL_MEMBER_TEMPLATES template explicit bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, size_t __pos = 0) : _Base() { if (__pos > __s.size()) __STL_THROW(out_of_range("bitset")); _M_copy_from_string(__s, __pos, basic_string<_CharT, _Traits, _Alloc>::npos); } template bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, size_t __pos, size_t __n) : _Base() { if (__pos > __s.size()) __STL_THROW(out_of_range("bitset")); _M_copy_from_string(__s, __pos, __n); } #else /* __STL_MEMBER_TEMPLATES */ explicit bitset(const basic_string& __s, size_t __pos = 0, size_t __n = basic_string::npos) : _Base() { if (__pos > __s.size()) __STL_THROW(out_of_range("bitset")); _M_copy_from_string(__s, __pos, __n); } #endif /* __STL_MEMBER_TEMPLATES */ // 23.3.5.2 bitset operations: 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; } bitset<_Nb>& operator<<=(size_t __pos) { this->_M_do_left_shift(__pos); this->_M_do_sanitize(); return *this; } bitset<_Nb>& operator>>=(size_t __pos) { this->_M_do_right_shift(__pos); this->_M_do_sanitize(); return *this; } // // Extension: // Versions of single-bit set, reset, flip, test with no range checking. // 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. bitset<_Nb>& set() { this->_M_do_set(); this->_M_do_sanitize(); return *this; } bitset<_Nb>& set(size_t __pos) { if (__pos >= _Nb) __STL_THROW(out_of_range("bitset")); return _Unchecked_set(__pos); } bitset<_Nb>& set(size_t __pos, int __val) { if (__pos >= _Nb) __STL_THROW(out_of_range("bitset")); return _Unchecked_set(__pos, __val); } bitset<_Nb>& reset() { this->_M_do_reset(); return *this; } bitset<_Nb>& reset(size_t __pos) { if (__pos >= _Nb) __STL_THROW(out_of_range("bitset")); return _Unchecked_reset(__pos); } bitset<_Nb>& flip() { this->_M_do_flip(); this->_M_do_sanitize(); return *this; } bitset<_Nb>& flip(size_t __pos) { if (__pos >= _Nb) __STL_THROW(out_of_range("bitset")); return _Unchecked_flip(__pos); } bitset<_Nb> operator~() const { return bitset<_Nb>(*this).flip(); } // element access: //for b[i]; reference operator[](size_t __pos) { return reference(*this,__pos); } bool operator[](size_t __pos) const { return _Unchecked_test(__pos); } unsigned long to_ulong() const { return this->_M_do_to_ulong(); } #if defined(__STL_MEMBER_TEMPLATES) && \ defined(__STL_EXPLICIT_FUNCTION_TMPL_ARGS) template basic_string<_CharT, _Traits, _Alloc> to_string() const { basic_string<_CharT, _Traits, _Alloc> __result; _M_copy_to_string(__result); return __result; } #endif /* member templates and explicit function template args */ // Helper functions for string operations. #ifdef __STL_MEMBER_TEMPLATES template void _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, size_t, size_t); template void _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const; #else /* __STL_MEMBER_TEMPLATES */ void _M_copy_from_string(const basic_string&, size_t, size_t); void _M_copy_to_string(basic_string&) const; #endif /* __STL_MEMBER_TEMPLATES */ size_t count() const { return this->_M_do_count(); } size_t size() const { return _Nb; } 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); } bool test(size_t __pos) const { if (__pos > _Nb) __STL_THROW(out_of_range("bitset")); return _Unchecked_test(__pos); } bool any() const { return this->_M_is_any(); } bool none() const { return !this->_M_is_any(); } bitset<_Nb> operator<<(size_t __pos) const { return bitset<_Nb>(*this) <<= __pos; } bitset<_Nb> operator>>(size_t __pos) const { return bitset<_Nb>(*this) >>= __pos; } // // EXTENSIONS: bit-find operations. These operations are // experimental, and are subject to change or removal in future // versions. // // find the index of the first "on" bit size_t _Find_first() const { return this->_M_do_find_first(_Nb); } // find the index of the next "on" bit after prev size_t _Find_next( size_t __prev ) const { return this->_M_do_find_next(__prev, _Nb); } }; // // Definitions of non-inline member functions. // #ifdef __STL_MEMBER_TEMPLATES template template void bitset<_Nb> ::_M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, size_t __pos, size_t __n) { reset(); const size_t __nbits = min(_Nb, min(__n, __s.size() - __pos)); for (size_t __i = 0; __i < __nbits; ++__i) { switch(__s[__pos + __nbits - __i - 1]) { case '0': break; case '1': set(__i); break; default: __STL_THROW(invalid_argument("bitset")); } } } template template void bitset<_Nb> ::_M_copy_to_string(basic_string<_CharT, _Traits, _Alloc>& __s) const { __s.assign(_Nb, '0'); for (size_t __i = 0; __i < _Nb; ++__i) if (_Unchecked_test(__i)) __s[_Nb - 1 - __i] = '1'; } #else /* __STL_MEMBER_TEMPLATES */ template void bitset<_Nb>::_M_copy_from_string(const basic_string& __s, size_t __pos, size_t __n) { reset(); size_t __tmp = _Nb; const size_t __nbits = min(__tmp, min(__n, __s.size() - __pos)); for (size_t __i = 0; __i < __nbits; ++__i) { switch(__s[__pos + __nbits - __i - 1]) { case '0': break; case '1': set(__i); break; default: __STL_THROW(invalid_argument("bitset")); } } } template void bitset<_Nb>::_M_copy_to_string(basic_string& __s) const { __s.assign(_Nb, '0'); for (size_t __i = 0; __i < _Nb; ++__i) if (_Unchecked_test(__i)) __s[_Nb - 1 - __i] = '1'; } #endif /* __STL_MEMBER_TEMPLATES */ // ------------------------------------------------------------ // // 23.3.5.3 bitset operations: // template inline bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { bitset<_Nb> __result(__x); __result &= __y; return __result; } template inline bitset<_Nb> operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { bitset<_Nb> __result(__x); __result |= __y; return __result; } template inline bitset<_Nb> operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { bitset<_Nb> __result(__x); __result ^= __y; return __result; } #ifdef __STL_USE_NEW_IOSTREAMS template basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) { basic_string<_CharT, _Traits> __tmp; __tmp.reserve(_Nb); // Skip whitespace typename basic_istream<_CharT, _Traits>::sentry __sentry(__is); if (__sentry) { basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); for (size_t __i = 0; __i < _Nb; ++__i) { static _Traits::int_type __eof = _Traits::eof(); typename _Traits::int_type __c1 = __buf->sbumpc(); if (_Traits::eq_int_type(__c1, __eof)) { __is.setstate(ios_base::eofbit); break; } else { char __c2 = _Traits::to_char_type(__c1); char __c = __is.narrow(__c2, '*'); if (__c == '0' || __c == '1') __tmp.push_back(__c); else if (_Traits::eq_int_type(__buf->sputbackc(__c2), __eof)) { __is.setstate(ios_base::failbit); break; } } } if (__tmp.empty()) __is.setstate(ios_base::failbit); else __x._M_copy_from_string(__tmp, static_cast(0), _Nb); } return __is; } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) { basic_string<_CharT, _Traits> __tmp; __x._M_copy_to_string(__tmp); return __os << __tmp; } #else /* __STL_USE_NEW_IOSTREAMS */ template istream& operator>>(istream& __is, bitset<_Nb>& __x) { string __tmp; __tmp.reserve(_Nb); if (__is.flags() & ios::skipws) { char __c; do __is.get(__c); while (__is && isspace(__c)); if (__is) __is.putback(__c); } for (size_t __i = 0; __i < _Nb; ++__i) { char __c; __is.get(__c); if (!__is) break; else if (__c != '0' && __c != '1') { __is.putback(__c); break; } else __tmp.push_back(__c); } if (__tmp.empty()) __is.clear(__is.rdstate() | ios::failbit); else __x._M_copy_from_string(__tmp, static_cast(0), _Nb); return __is; } template ostream& operator<<(ostream& __os, const bitset<_Nb>& __x) { string __tmp; __x._M_copy_to_string(__tmp); return __os << __tmp; } #endif /* __STL_USE_NEW_IOSTREAMS */ // ------------------------------------------------------------ // Lookup tables for find and count operations. template unsigned char _Bit_count<__dummy>::_S_bit_count[] = { 0, /* 0 */ 1, /* 1 */ 1, /* 2 */ 2, /* 3 */ 1, /* 4 */ 2, /* 5 */ 2, /* 6 */ 3, /* 7 */ 1, /* 8 */ 2, /* 9 */ 2, /* 10 */ 3, /* 11 */ 2, /* 12 */ 3, /* 13 */ 3, /* 14 */ 4, /* 15 */ 1, /* 16 */ 2, /* 17 */ 2, /* 18 */ 3, /* 19 */ 2, /* 20 */ 3, /* 21 */ 3, /* 22 */ 4, /* 23 */ 2, /* 24 */ 3, /* 25 */ 3, /* 26 */ 4, /* 27 */ 3, /* 28 */ 4, /* 29 */ 4, /* 30 */ 5, /* 31 */ 1, /* 32 */ 2, /* 33 */ 2, /* 34 */ 3, /* 35 */ 2, /* 36 */ 3, /* 37 */ 3, /* 38 */ 4, /* 39 */ 2, /* 40 */ 3, /* 41 */ 3, /* 42 */ 4, /* 43 */ 3, /* 44 */ 4, /* 45 */ 4, /* 46 */ 5, /* 47 */ 2, /* 48 */ 3, /* 49 */ 3, /* 50 */ 4, /* 51 */ 3, /* 52 */ 4, /* 53 */ 4, /* 54 */ 5, /* 55 */ 3, /* 56 */ 4, /* 57 */ 4, /* 58 */ 5, /* 59 */ 4, /* 60 */ 5, /* 61 */ 5, /* 62 */ 6, /* 63 */ 1, /* 64 */ 2, /* 65 */ 2, /* 66 */ 3, /* 67 */ 2, /* 68 */ 3, /* 69 */ 3, /* 70 */ 4, /* 71 */ 2, /* 72 */ 3, /* 73 */ 3, /* 74 */ 4, /* 75 */ 3, /* 76 */ 4, /* 77 */ 4, /* 78 */ 5, /* 79 */ 2, /* 80 */ 3, /* 81 */ 3, /* 82 */ 4, /* 83 */ 3, /* 84 */ 4, /* 85 */ 4, /* 86 */ 5, /* 87 */ 3, /* 88 */ 4, /* 89 */ 4, /* 90 */ 5, /* 91 */ 4, /* 92 */ 5, /* 93 */ 5, /* 94 */ 6, /* 95 */ 2, /* 96 */ 3, /* 97 */ 3, /* 98 */ 4, /* 99 */ 3, /* 100 */ 4, /* 101 */ 4, /* 102 */ 5, /* 103 */ 3, /* 104 */ 4, /* 105 */ 4, /* 106 */ 5, /* 107 */ 4, /* 108 */ 5, /* 109 */ 5, /* 110 */ 6, /* 111 */ 3, /* 112 */ 4, /* 113 */ 4, /* 114 */ 5, /* 115 */ 4, /* 116 */ 5, /* 117 */ 5, /* 118 */ 6, /* 119 */ 4, /* 120 */ 5, /* 121 */ 5, /* 122 */ 6, /* 123 */ 5, /* 124 */ 6, /* 125 */ 6, /* 126 */ 7, /* 127 */ 1, /* 128 */ 2, /* 129 */ 2, /* 130 */ 3, /* 131 */ 2, /* 132 */ 3, /* 133 */ 3, /* 134 */ 4, /* 135 */ 2, /* 136 */ 3, /* 137 */ 3, /* 138 */ 4, /* 139 */ 3, /* 140 */ 4, /* 141 */ 4, /* 142 */ 5, /* 143 */ 2, /* 144 */ 3, /* 145 */ 3, /* 146 */ 4, /* 147 */ 3, /* 148 */ 4, /* 149 */ 4, /* 150 */ 5, /* 151 */ 3, /* 152 */ 4, /* 153 */ 4, /* 154 */ 5, /* 155 */ 4, /* 156 */ 5, /* 157 */ 5, /* 158 */ 6, /* 159 */ 2, /* 160 */ 3, /* 161 */ 3, /* 162 */ 4, /* 163 */ 3, /* 164 */ 4, /* 165 */ 4, /* 166 */ 5, /* 167 */ 3, /* 168 */ 4, /* 169 */ 4, /* 170 */ 5, /* 171 */ 4, /* 172 */ 5, /* 173 */ 5, /* 174 */ 6, /* 175 */ 3, /* 176 */ 4, /* 177 */ 4, /* 178 */ 5, /* 179 */ 4, /* 180 */ 5, /* 181 */ 5, /* 182 */ 6, /* 183 */ 4, /* 184 */ 5, /* 185 */ 5, /* 186 */ 6, /* 187 */ 5, /* 188 */ 6, /* 189 */ 6, /* 190 */ 7, /* 191 */ 2, /* 192 */ 3, /* 193 */ 3, /* 194 */ 4, /* 195 */ 3, /* 196 */ 4, /* 197 */ 4, /* 198 */ 5, /* 199 */ 3, /* 200 */ 4, /* 201 */ 4, /* 202 */ 5, /* 203 */ 4, /* 204 */ 5, /* 205 */ 5, /* 206 */ 6, /* 207 */ 3, /* 208 */ 4, /* 209 */ 4, /* 210 */ 5, /* 211 */ 4, /* 212 */ 5, /* 213 */ 5, /* 214 */ 6, /* 215 */ 4, /* 216 */ 5, /* 217 */ 5, /* 218 */ 6, /* 219 */ 5, /* 220 */ 6, /* 221 */ 6, /* 222 */ 7, /* 223 */ 3, /* 224 */ 4, /* 225 */ 4, /* 226 */ 5, /* 227 */ 4, /* 228 */ 5, /* 229 */ 5, /* 230 */ 6, /* 231 */ 4, /* 232 */ 5, /* 233 */ 5, /* 234 */ 6, /* 235 */ 5, /* 236 */ 6, /* 237 */ 6, /* 238 */ 7, /* 239 */ 4, /* 240 */ 5, /* 241 */ 5, /* 242 */ 6, /* 243 */ 5, /* 244 */ 6, /* 245 */ 6, /* 246 */ 7, /* 247 */ 5, /* 248 */ 6, /* 249 */ 6, /* 250 */ 7, /* 251 */ 6, /* 252 */ 7, /* 253 */ 7, /* 254 */ 8 /* 255 */ }; // end _Bit_count template unsigned char _First_one<__dummy>::_S_first_one[] = { 0, /* 0 */ 0, /* 1 */ 1, /* 2 */ 0, /* 3 */ 2, /* 4 */ 0, /* 5 */ 1, /* 6 */ 0, /* 7 */ 3, /* 8 */ 0, /* 9 */ 1, /* 10 */ 0, /* 11 */ 2, /* 12 */ 0, /* 13 */ 1, /* 14 */ 0, /* 15 */ 4, /* 16 */ 0, /* 17 */ 1, /* 18 */ 0, /* 19 */ 2, /* 20 */ 0, /* 21 */ 1, /* 22 */ 0, /* 23 */ 3, /* 24 */ 0, /* 25 */ 1, /* 26 */ 0, /* 27 */ 2, /* 28 */ 0, /* 29 */ 1, /* 30 */ 0, /* 31 */ 5, /* 32 */ 0, /* 33 */ 1, /* 34 */ 0, /* 35 */ 2, /* 36 */ 0, /* 37 */ 1, /* 38 */ 0, /* 39 */ 3, /* 40 */ 0, /* 41 */ 1, /* 42 */ 0, /* 43 */ 2, /* 44 */ 0, /* 45 */ 1, /* 46 */ 0, /* 47 */ 4, /* 48 */ 0, /* 49 */ 1, /* 50 */ 0, /* 51 */ 2, /* 52 */ 0, /* 53 */ 1, /* 54 */ 0, /* 55 */ 3, /* 56 */ 0, /* 57 */ 1, /* 58 */ 0, /* 59 */ 2, /* 60 */ 0, /* 61 */ 1, /* 62 */ 0, /* 63 */ 6, /* 64 */ 0, /* 65 */ 1, /* 66 */ 0, /* 67 */ 2, /* 68 */ 0, /* 69 */ 1, /* 70 */ 0, /* 71 */ 3, /* 72 */ 0, /* 73 */ 1, /* 74 */ 0, /* 75 */ 2, /* 76 */ 0, /* 77 */ 1, /* 78 */ 0, /* 79 */ 4, /* 80 */ 0, /* 81 */ 1, /* 82 */ 0, /* 83 */ 2, /* 84 */ 0, /* 85 */ 1, /* 86 */ 0, /* 87 */ 3, /* 88 */ 0, /* 89 */ 1, /* 90 */ 0, /* 91 */ 2, /* 92 */ 0, /* 93 */ 1, /* 94 */ 0, /* 95 */ 5, /* 96 */ 0, /* 97 */ 1, /* 98 */ 0, /* 99 */ 2, /* 100 */ 0, /* 101 */ 1, /* 102 */ 0, /* 103 */ 3, /* 104 */ 0, /* 105 */ 1, /* 106 */ 0, /* 107 */ 2, /* 108 */ 0, /* 109 */ 1, /* 110 */ 0, /* 111 */ 4, /* 112 */ 0, /* 113 */ 1, /* 114 */ 0, /* 115 */ 2, /* 116 */ 0, /* 117 */ 1, /* 118 */ 0, /* 119 */ 3, /* 120 */ 0, /* 121 */ 1, /* 122 */ 0, /* 123 */ 2, /* 124 */ 0, /* 125 */ 1, /* 126 */ 0, /* 127 */ 7, /* 128 */ 0, /* 129 */ 1, /* 130 */ 0, /* 131 */ 2, /* 132 */ 0, /* 133 */ 1, /* 134 */ 0, /* 135 */ 3, /* 136 */ 0, /* 137 */ 1, /* 138 */ 0, /* 139 */ 2, /* 140 */ 0, /* 141 */ 1, /* 142 */ 0, /* 143 */ 4, /* 144 */ 0, /* 145 */ 1, /* 146 */ 0, /* 147 */ 2, /* 148 */ 0, /* 149 */ 1, /* 150 */ 0, /* 151 */ 3, /* 152 */ 0, /* 153 */ 1, /* 154 */ 0, /* 155 */ 2, /* 156 */ 0, /* 157 */ 1, /* 158 */ 0, /* 159 */ 5, /* 160 */ 0, /* 161 */ 1, /* 162 */ 0, /* 163 */ 2, /* 164 */ 0, /* 165 */ 1, /* 166 */ 0, /* 167 */ 3, /* 168 */ 0, /* 169 */ 1, /* 170 */ 0, /* 171 */ 2, /* 172 */ 0, /* 173 */ 1, /* 174 */ 0, /* 175 */ 4, /* 176 */ 0, /* 177 */ 1, /* 178 */ 0, /* 179 */ 2, /* 180 */ 0, /* 181 */ 1, /* 182 */ 0, /* 183 */ 3, /* 184 */ 0, /* 185 */ 1, /* 186 */ 0, /* 187 */ 2, /* 188 */ 0, /* 189 */ 1, /* 190 */ 0, /* 191 */ 6, /* 192 */ 0, /* 193 */ 1, /* 194 */ 0, /* 195 */ 2, /* 196 */ 0, /* 197 */ 1, /* 198 */ 0, /* 199 */ 3, /* 200 */ 0, /* 201 */ 1, /* 202 */ 0, /* 203 */ 2, /* 204 */ 0, /* 205 */ 1, /* 206 */ 0, /* 207 */ 4, /* 208 */ 0, /* 209 */ 1, /* 210 */ 0, /* 211 */ 2, /* 212 */ 0, /* 213 */ 1, /* 214 */ 0, /* 215 */ 3, /* 216 */ 0, /* 217 */ 1, /* 218 */ 0, /* 219 */ 2, /* 220 */ 0, /* 221 */ 1, /* 222 */ 0, /* 223 */ 5, /* 224 */ 0, /* 225 */ 1, /* 226 */ 0, /* 227 */ 2, /* 228 */ 0, /* 229 */ 1, /* 230 */ 0, /* 231 */ 3, /* 232 */ 0, /* 233 */ 1, /* 234 */ 0, /* 235 */ 2, /* 236 */ 0, /* 237 */ 1, /* 238 */ 0, /* 239 */ 4, /* 240 */ 0, /* 241 */ 1, /* 242 */ 0, /* 243 */ 2, /* 244 */ 0, /* 245 */ 1, /* 246 */ 0, /* 247 */ 3, /* 248 */ 0, /* 249 */ 1, /* 250 */ 0, /* 251 */ 2, /* 252 */ 0, /* 253 */ 1, /* 254 */ 0, /* 255 */ }; // end _First_one #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1209 #endif __STL_END_NAMESPACE #undef __BITS_PER_WORD #undef __BITSET_WORDS #endif /* __SGI_STL_BITSET */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/bvector.h ================================================ /* * * 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 __SGI_STL_BVECTOR_H #define __SGI_STL_BVECTOR_H #include #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION #include #else #include #include #endif #include #ifdef __STL_USE_NAMESPACES using __STD::bit_vector; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_BVECTOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/char_traits.h ================================================ /* * 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 __SGI_STL_CHAR_TRAITS_H #define __SGI_STL_CHAR_TRAITS_H #include #include #if defined(__STL_USE_NEW_IOSTREAMS) && !defined(__SGI_STL_IOSFWD) #include #endif /* use new iostreams */ __STL_BEGIN_NAMESPACE // Class __char_traits_base. template class __char_traits_base { public: typedef _CharT char_type; typedef _IntT int_type; #ifdef __STL_USE_NEW_IOSTREAMS typedef streamoff off_type; typedef streampos pos_type; typedef mbstate_t state_type; #endif /* __STL_USE_NEW_IOSTREAMS */ static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } static bool eq(const _CharT& __c1, const _CharT& __c2) { return __c1 == __c2; } static bool lt(const _CharT& __c1, const _CharT& __c2) { return __c1 < __c2; } static int compare(const _CharT* __s1, const _CharT* __s2, size_t __n) { for (size_t __i = 0; __i < __n; ++__i) if (!eq(__s1[__i], __s2[__i])) return __s1[__i] < __s2[__i] ? -1 : 1; return 0; } static size_t length(const _CharT* __s) { const _CharT __nullchar = _CharT(); size_t __i; for (__i = 0; !eq(__s[__i], __nullchar); ++__i) {} return __i; } static const _CharT* find(const _CharT* __s, size_t __n, const _CharT& __c) { for ( ; __n > 0 ; ++__s, --__n) if (eq(*__s, __c)) return __s; return 0; } static _CharT* move(_CharT* __s1, const _CharT* __s2, size_t __n) { memmove(__s1, __s2, __n * sizeof(_CharT)); return __s1; } static _CharT* copy(_CharT* __s1, const _CharT* __s2, size_t __n) { memcpy(__s1, __s2, __n * sizeof(_CharT)); return __s1; } static _CharT* assign(_CharT* __s, size_t __n, _CharT __c) { for (size_t __i = 0; __i < __n; ++__i) __s[__i] = __c; return __s; } static int_type not_eof(const int_type& __c) { return !eq_int_type(__c, eof()) ? __c : 0; } static char_type to_char_type(const int_type& __c) { return static_cast(__c); } static int_type to_int_type(const char_type& __c) { return static_cast(__c); } static bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } static int_type eof() { return static_cast(-1); } }; // Generic char_traits class. Note that this class is provided only // as a base for explicit specialization; it is unlikely to be useful // as is for any particular user-defined type. In particular, it // *will not work* for a non-POD type. template class char_traits : public __char_traits_base<_CharT, _CharT> {}; // Specialization for char. __STL_TEMPLATE_NULL class char_traits : public __char_traits_base { public: static char_type to_char_type(const int_type& __c) { return static_cast(static_cast(__c)); } static int_type to_int_type(const char_type& __c) { return static_cast(__c); } static int compare(const char* __s1, const char* __s2, size_t __n) { return memcmp(__s1, __s2, __n); } static size_t length(const char* __s) { return strlen(__s); } static void assign(char& __c1, const char& __c2) { __c1 = __c2; } static char* assign(char* __s, size_t __n, char __c) { memset(__s, __c, __n); return __s; } }; // Specialization for wchar_t. __STL_TEMPLATE_NULL class char_traits : public __char_traits_base {}; __STL_END_NAMESPACE #endif /* __SGI_STL_CHAR_TRAITS_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/concept_checks.h ================================================ /* * Copyright (c) 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. */ #ifndef __CONCEPT_CHECKS_H #define __CONCEPT_CHECKS_H /* Use these macro like assertions, but they assert properties on types (usually template arguments). In technical terms they verify whether a type "models" a "concept". This set of requirements and the terminology used here is derived from the book "Generic Programming and the STL" by Matt Austern (Addison Wesley). For further information please consult that book. The requirements also are intended to match the ANSI/ISO C++ standard. This file covers the basic concepts and the iterator concepts. There are several other files that provide the requirements for the STL containers: container_concepts.h sequence_concepts.h assoc_container_concepts.h Jeremy Siek, 1999 TO DO: - some issues with regards to concept classification and mutability including AssociativeContianer -> ForwardContainer and SortedAssociativeContainer -> ReversibleContainer - HashedAssociativeContainer - Allocator - Function Object Concepts */ #ifndef __STL_USE_CONCEPT_CHECKS // Some compilers lack the features that are necessary for concept checks. // On those compilers we define the concept check macros to do nothing. #define __STL_REQUIRES(__type_var, __concept) do {} while(0) #define __STL_CLASS_REQUIRES(__type_var, __concept) \ static int __##__type_var##_##__concept #define __STL_CONVERTIBLE(__type_x, __type_y) do {} while(0) #define __STL_REQUIRES_SAME_TYPE(__type_x, __type_y) do {} while(0) #define __STL_CLASS_REQUIRES_SAME_TYPE(__type_x, __type_y) \ static int __##__type_x##__type_y##_require_same_type #define __STL_GENERATOR_CHECK(__func, __ret) do {} while(0) #define __STL_CLASS_GENERATOR_CHECK(__func, __ret) \ static int __##__func##__ret##_generator_check #define __STL_UNARY_FUNCTION_CHECK(__func, __ret, __arg) do {} while(0) #define __STL_CLASS_UNARY_FUNCTION_CHECK(__func, __ret, __arg) \ static int __##__func##__ret##__arg##_unary_function_check #define __STL_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ do {} while(0) #define __STL_CLASS_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ static int __##__func##__ret##__first##__second##_binary_function_check #define __STL_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ do {} while(0) #define __STL_CLASS_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ static int __##__opname##__ret##__first##__second##_require_binary_op #else /* __STL_USE_CONCEPT_CHECKS */ // This macro tests whether the template argument "__type_var" // satisfies the requirements of "__concept". Here is a list of concepts // that we know how to check: // _Allocator // _Assignable // _DefaultConstructible // _EqualityComparable // _LessThanComparable // _TrivialIterator // _InputIterator // _OutputIterator // _ForwardIterator // _BidirectionalIterator // _RandomAccessIterator // _Mutable_TrivialIterator // _Mutable_ForwardIterator // _Mutable_BidirectionalIterator // _Mutable_RandomAccessIterator #define __STL_REQUIRES(__type_var, __concept) \ do { \ void (*__x)( __type_var ) = __concept##_concept_specification< __type_var >\ ::__concept##_requirement_violation; __x = __x; } while (0) // Use this to check whether type X is convertible to type Y #define __STL_CONVERTIBLE(__type_x, __type_y) \ do { \ void (*__x)( __type_x , __type_y ) = _STL_CONVERT_ERROR< __type_x , \ __type_y >::__type_X_is_not_convertible_to_type_Y; \ __x = __x; } while (0) // Use this to test whether two template arguments are the same type #define __STL_REQUIRES_SAME_TYPE(__type_x, __type_y) \ do { \ void (*__x)( __type_x , __type_y ) = _STL_SAME_TYPE_ERROR< __type_x, \ __type_y >::__type_X_not_same_as_type_Y; \ __x = __x; } while (0) // function object checks #define __STL_GENERATOR_CHECK(__func, __ret) \ do { \ __ret (*__x)( __func&) = \ _STL_GENERATOR_ERROR< \ __func, __ret>::__generator_requirement_violation; \ __x = __x; } while (0) #define __STL_UNARY_FUNCTION_CHECK(__func, __ret, __arg) \ do { \ __ret (*__x)( __func&, const __arg& ) = \ _STL_UNARY_FUNCTION_ERROR< \ __func, __ret, __arg>::__unary_function_requirement_violation; \ __x = __x; } while (0) #define __STL_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ do { \ __ret (*__x)( __func&, const __first&, const __second& ) = \ _STL_BINARY_FUNCTION_ERROR< \ __func, __ret, __first, __second>::__binary_function_requirement_violation; \ __x = __x; } while (0) #define __STL_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ do { \ __ret (*__x)( __first&, __second& ) = _STL_BINARY##__opname##_ERROR< \ __ret, __first, __second>::__binary_operator_requirement_violation; \ __ret (*__y)( const __first&, const __second& ) = \ _STL_BINARY##__opname##_ERROR< __ret, __first, __second>:: \ __const_binary_operator_requirement_violation; \ __y = __y; __x = __x; } while (0) #ifdef __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE #define __STL_CLASS_REQUIRES(__type_var, __concept) #define __STL_CLASS_REQUIRES_SAME_TYPE(__type_x, __type_y) #define __STL_CLASS_GENERATOR_CHECK(__func, __ret) #define __STL_CLASS_UNARY_FUNCTION_CHECK(__func, __ret, __arg) #define __STL_CLASS_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) #define __STL_CLASS_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) #else // Use this macro inside of template classes, where you would // like to place requirements on the template arguments to the class // Warning: do not pass pointers and such (e.g. T*) in as the __type_var, // since the type_var is used to construct identifiers. Instead typedef // the pointer type, then use the typedef name for the __type_var. #define __STL_CLASS_REQUIRES(__type_var, __concept) \ typedef void (* __func##__type_var##__concept)( __type_var ); \ template <__func##__type_var##__concept _Tp1> \ struct __dummy_struct_##__type_var##__concept { }; \ static __dummy_struct_##__type_var##__concept< \ __concept##_concept_specification< \ __type_var>::__concept##_requirement_violation> \ __dummy_ptr_##__type_var##__concept #define __STL_CLASS_REQUIRES_SAME_TYPE(__type_x, __type_y) \ typedef void (* __func_##__type_x##__type_y##same_type)( __type_x, \ __type_y ); \ template < __func_##__type_x##__type_y##same_type _Tp1> \ struct __dummy_struct_##__type_x##__type_y##_same_type { }; \ static __dummy_struct_##__type_x##__type_y##_same_type< \ _STL_SAME_TYPE_ERROR<__type_x, __type_y>::__type_X_not_same_as_type_Y> \ __dummy_ptr_##__type_x##__type_y##_same_type #define __STL_CLASS_GENERATOR_CHECK(__func, __ret) \ typedef __ret (* __f_##__func##__ret##_generator)( __func& ); \ template <__f_##__func##__ret##_generator _Tp1> \ struct __dummy_struct_##__func##__ret##_generator { }; \ static __dummy_struct_##__func##__ret##_generator< \ _STL_GENERATOR_ERROR< \ __func, __ret>::__generator_requirement_violation> \ __dummy_ptr_##__func##__ret##_generator #define __STL_CLASS_UNARY_FUNCTION_CHECK(__func, __ret, __arg) \ typedef __ret (* __f_##__func##__ret##__arg##_unary_check)( __func&, \ const __arg& ); \ template <__f_##__func##__ret##__arg##_unary_check _Tp1> \ struct __dummy_struct_##__func##__ret##__arg##_unary_check { }; \ static __dummy_struct_##__func##__ret##__arg##_unary_check< \ _STL_UNARY_FUNCTION_ERROR< \ __func, __ret, __arg>::__unary_function_requirement_violation> \ __dummy_ptr_##__func##__ret##__arg##_unary_check #define __STL_CLASS_BINARY_FUNCTION_CHECK(__func, __ret, __first, __second) \ typedef __ret (* __f_##__func##__ret##__first##__second##_binary_check)( __func&, const __first&,\ const __second& ); \ template <__f_##__func##__ret##__first##__second##_binary_check _Tp1> \ struct __dummy_struct_##__func##__ret##__first##__second##_binary_check { }; \ static __dummy_struct_##__func##__ret##__first##__second##_binary_check< \ _STL_BINARY_FUNCTION_ERROR<__func, __ret, __first, __second>:: \ __binary_function_requirement_violation> \ __dummy_ptr_##__func##__ret##__first##__second##_binary_check #define __STL_CLASS_REQUIRES_BINARY_OP(__opname, __ret, __first, __second) \ typedef __ret (* __f_##__func##__ret##__first##__second##_binary_op)(const __first&, \ const __second& ); \ template <__f_##__func##__ret##__first##__second##_binary_op _Tp1> \ struct __dummy_struct_##__func##__ret##__first##__second##_binary_op { }; \ static __dummy_struct_##__func##__ret##__first##__second##_binary_op< \ _STL_BINARY##__opname##_ERROR<__ret, __first, __second>:: \ __binary_operator_requirement_violation> \ __dummy_ptr_##__func##__ret##__first##__second##_binary_op #endif /* helper class for finding non-const version of a type. Need to have something to assign to etc. when testing constant iterators. */ template struct _Mutable_trait { typedef _Tp _Type; }; template struct _Mutable_trait { typedef _Tp _Type; }; /* helper function for avoiding compiler warnings about unused variables */ template void __sink_unused_warning(_Type) { } template struct _STL_CONVERT_ERROR { static void __type_X_is_not_convertible_to_type_Y(_TypeX __x, _TypeY) { _TypeY __y = __x; __sink_unused_warning(__y); } }; template struct __check_equal { }; template struct _STL_SAME_TYPE_ERROR { static void __type_X_not_same_as_type_Y(_TypeX , _TypeY ) { __check_equal<_TypeX> t1 = __check_equal<_TypeY>(); } }; // Some Functon Object Checks template struct _STL_GENERATOR_ERROR { static _Ret __generator_requirement_violation(_Func& __f) { return __f(); } }; template struct _STL_GENERATOR_ERROR<_Func, void> { static void __generator_requirement_violation(_Func& __f) { __f(); } }; template struct _STL_UNARY_FUNCTION_ERROR { static _Ret __unary_function_requirement_violation(_Func& __f, const _Arg& __arg) { return __f(__arg); } }; template struct _STL_UNARY_FUNCTION_ERROR<_Func, void, _Arg> { static void __unary_function_requirement_violation(_Func& __f, const _Arg& __arg) { __f(__arg); } }; template struct _STL_BINARY_FUNCTION_ERROR { static _Ret __binary_function_requirement_violation(_Func& __f, const _First& __first, const _Second& __second) { return __f(__first, __second); } }; template struct _STL_BINARY_FUNCTION_ERROR<_Func, void, _First, _Second> { static void __binary_function_requirement_violation(_Func& __f, const _First& __first, const _Second& __second) { __f(__first, __second); } }; #define __STL_DEFINE_BINARY_OP_CHECK(_OP, _NAME) \ template \ struct _STL_BINARY##_NAME##_ERROR { \ static _Ret \ __const_binary_operator_requirement_violation(const _First& __first, \ const _Second& __second) { \ return __first _OP __second; \ } \ static _Ret \ __binary_operator_requirement_violation(_First& __first, \ _Second& __second) { \ return __first _OP __second; \ } \ } __STL_DEFINE_BINARY_OP_CHECK(==, _OP_EQUAL); __STL_DEFINE_BINARY_OP_CHECK(!=, _OP_NOT_EQUAL); __STL_DEFINE_BINARY_OP_CHECK(<, _OP_LESS_THAN); __STL_DEFINE_BINARY_OP_CHECK(<=, _OP_LESS_EQUAL); __STL_DEFINE_BINARY_OP_CHECK(>, _OP_GREATER_THAN); __STL_DEFINE_BINARY_OP_CHECK(>=, _OP_GREATER_EQUAL); __STL_DEFINE_BINARY_OP_CHECK(+, _OP_PLUS); __STL_DEFINE_BINARY_OP_CHECK(*, _OP_TIMES); __STL_DEFINE_BINARY_OP_CHECK(/, _OP_DIVIDE); __STL_DEFINE_BINARY_OP_CHECK(-, _OP_SUBTRACT); __STL_DEFINE_BINARY_OP_CHECK(%, _OP_MOD); // ... // TODO, add unary operators (prefix and postfix) /* The presence of this class is just to trick EDG into displaying these error messages before any other errors. Without the classes, the errors in the functions get reported after other class errors deep inside the library. The name choice just makes for an eye catching error message :) */ struct _STL_ERROR { template static _Type __default_constructor_requirement_violation(_Type) { return _Type(); } template static _Type __assignment_operator_requirement_violation(_Type __a) { __a = __a; return __a; } template static _Type __copy_constructor_requirement_violation(_Type __a) { _Type __c(__a); return __c; } template static _Type __const_parameter_required_for_copy_constructor(_Type /* __a */, const _Type& __b) { _Type __c(__b); return __c; } template static _Type __const_parameter_required_for_assignment_operator(_Type __a, const _Type& __b) { __a = __b; return __a; } template static _Type __less_than_comparable_requirement_violation(_Type __a, _Type __b) { if (__a < __b || __a > __b || __a <= __b || __a >= __b) return __a; return __b; } template static _Type __equality_comparable_requirement_violation(_Type __a, _Type __b) { if (__a == __b || __a != __b) return __a; return __b; } template static void __dereference_operator_requirement_violation(_Iterator __i) { __sink_unused_warning(*__i); } template static void __dereference_operator_and_assignment_requirement_violation(_Iterator __i) { *__i = *__i; } template static void __preincrement_operator_requirement_violation(_Iterator __i) { ++__i; } template static void __postincrement_operator_requirement_violation(_Iterator __i) { __i++; } template static void __predecrement_operator_requirement_violation(_Iterator __i) { --__i; } template static void __postdecrement_operator_requirement_violation(_Iterator __i) { __i--; } template static void __postincrement_operator_and_assignment_requirement_violation(_Iterator __i, _Type __t) { *__i++ = __t; } template static _Iterator __iterator_addition_assignment_requirement_violation(_Iterator __i, _Distance __n) { __i += __n; return __i; } template static _Iterator __iterator_addition_requirement_violation(_Iterator __i, _Distance __n) { __i = __i + __n; __i = __n + __i; return __i; } template static _Iterator __iterator_subtraction_assignment_requirement_violation(_Iterator __i, _Distance __n) { __i -= __n; return __i; } template static _Iterator __iterator_subtraction_requirement_violation(_Iterator __i, _Distance __n) { __i = __i - __n; return __i; } template static _Distance __difference_operator_requirement_violation(_Iterator __i, _Iterator __j, _Distance __n) { __n = __i - __j; return __n; } template static _Type __element_access_operator_requirement_violation(_Exp __x, _Type*, _Distance __n) { return __x[__n]; } template static void __element_assignment_operator_requirement_violation(_Exp __x, _Type* __t, _Distance __n) { __x[__n] = *__t; } }; /* _STL_ERROR */ /* Associated Type Requirements */ __STL_BEGIN_NAMESPACE template struct iterator_traits; __STL_END_NAMESPACE template struct __value_type_type_definition_requirement_violation { typedef typename __STD::iterator_traits<_Iter>::value_type value_type; }; template struct __difference_type_type_definition_requirement_violation { typedef typename __STD::iterator_traits<_Iter>::difference_type difference_type; }; template struct __reference_type_definition_requirement_violation { typedef typename __STD::iterator_traits<_Iter>::reference reference; }; template struct __pointer_type_definition_requirement_violation { typedef typename __STD::iterator_traits<_Iter>::pointer pointer; }; template struct __iterator_category_type_definition_requirement_violation { typedef typename __STD::iterator_traits<_Iter>::iterator_category iterator_category; }; /* Assignable Requirements */ template struct _Assignable_concept_specification { static void _Assignable_requirement_violation(_Type __a) { _STL_ERROR::__assignment_operator_requirement_violation(__a); _STL_ERROR::__copy_constructor_requirement_violation(__a); _STL_ERROR::__const_parameter_required_for_copy_constructor(__a,__a); _STL_ERROR::__const_parameter_required_for_assignment_operator(__a,__a); } }; /* DefaultConstructible Requirements */ template struct _DefaultConstructible_concept_specification { static void _DefaultConstructible_requirement_violation(_Type __a) { _STL_ERROR::__default_constructor_requirement_violation(__a); } }; /* EqualityComparable Requirements */ template struct _EqualityComparable_concept_specification { static void _EqualityComparable_requirement_violation(_Type __a) { _STL_ERROR::__equality_comparable_requirement_violation(__a, __a); } }; /* LessThanComparable Requirements */ template struct _LessThanComparable_concept_specification { static void _LessThanComparable_requirement_violation(_Type __a) { _STL_ERROR::__less_than_comparable_requirement_violation(__a, __a); } }; /* TrivialIterator Requirements */ template struct _TrivialIterator_concept_specification { static void _TrivialIterator_requirement_violation(_TrivialIterator __i) { typedef typename __value_type_type_definition_requirement_violation<_TrivialIterator>:: value_type __T; // Refinement of Assignable _Assignable_concept_specification<_TrivialIterator>:: _Assignable_requirement_violation(__i); // Refinement of DefaultConstructible _DefaultConstructible_concept_specification<_TrivialIterator>:: _DefaultConstructible_requirement_violation(__i); // Refinement of EqualityComparable _EqualityComparable_concept_specification<_TrivialIterator>:: _EqualityComparable_requirement_violation(__i); // Valid Expressions _STL_ERROR::__dereference_operator_requirement_violation(__i); } }; template struct _Mutable_TrivialIterator_concept_specification { static void _Mutable_TrivialIterator_requirement_violation(_TrivialIterator __i) { _TrivialIterator_concept_specification<_TrivialIterator>:: _TrivialIterator_requirement_violation(__i); // Valid Expressions _STL_ERROR::__dereference_operator_and_assignment_requirement_violation(__i); } }; /* InputIterator Requirements */ template struct _InputIterator_concept_specification { static void _InputIterator_requirement_violation(_InputIterator __i) { // Refinement of TrivialIterator _TrivialIterator_concept_specification<_InputIterator>:: _TrivialIterator_requirement_violation(__i); // Associated Types __difference_type_type_definition_requirement_violation<_InputIterator>(); __reference_type_definition_requirement_violation<_InputIterator>(); __pointer_type_definition_requirement_violation<_InputIterator>(); __iterator_category_type_definition_requirement_violation<_InputIterator>(); // Valid Expressions _STL_ERROR::__preincrement_operator_requirement_violation(__i); _STL_ERROR::__postincrement_operator_requirement_violation(__i); } }; /* OutputIterator Requirements */ template struct _OutputIterator_concept_specification { static void _OutputIterator_requirement_violation(_OutputIterator __i) { // Refinement of Assignable _Assignable_concept_specification<_OutputIterator>:: _Assignable_requirement_violation(__i); // Associated Types __iterator_category_type_definition_requirement_violation<_OutputIterator>(); // Valid Expressions _STL_ERROR::__dereference_operator_requirement_violation(__i); _STL_ERROR::__preincrement_operator_requirement_violation(__i); _STL_ERROR::__postincrement_operator_requirement_violation(__i); _STL_ERROR:: __postincrement_operator_and_assignment_requirement_violation(__i, *__i); } }; /* ForwardIterator Requirements */ template struct _ForwardIterator_concept_specification { static void _ForwardIterator_requirement_violation(_ForwardIterator __i) { // Refinement of InputIterator _InputIterator_concept_specification<_ForwardIterator>:: _InputIterator_requirement_violation(__i); } }; template struct _Mutable_ForwardIterator_concept_specification { static void _Mutable_ForwardIterator_requirement_violation(_ForwardIterator __i) { _ForwardIterator_concept_specification<_ForwardIterator>:: _ForwardIterator_requirement_violation(__i); // Refinement of OutputIterator _OutputIterator_concept_specification<_ForwardIterator>:: _OutputIterator_requirement_violation(__i); } }; /* BidirectionalIterator Requirements */ template struct _BidirectionalIterator_concept_specification { static void _BidirectionalIterator_requirement_violation(_BidirectionalIterator __i) { // Refinement of ForwardIterator _ForwardIterator_concept_specification<_BidirectionalIterator>:: _ForwardIterator_requirement_violation(__i); // Valid Expressions _STL_ERROR::__predecrement_operator_requirement_violation(__i); _STL_ERROR::__postdecrement_operator_requirement_violation(__i); } }; template struct _Mutable_BidirectionalIterator_concept_specification { static void _Mutable_BidirectionalIterator_requirement_violation( _BidirectionalIterator __i) { _BidirectionalIterator_concept_specification<_BidirectionalIterator>:: _BidirectionalIterator_requirement_violation(__i); // Refinement of mutable_ForwardIterator _Mutable_ForwardIterator_concept_specification<_BidirectionalIterator>:: _Mutable_ForwardIterator_requirement_violation(__i); typedef typename __value_type_type_definition_requirement_violation< _BidirectionalIterator>::value_type __T; typename _Mutable_trait<__T>::_Type* __tmp_ptr = 0; // Valid Expressions _STL_ERROR:: __postincrement_operator_and_assignment_requirement_violation(__i, *__tmp_ptr); } }; /* RandomAccessIterator Requirements */ template struct _RandomAccessIterator_concept_specification { static void _RandomAccessIterator_requirement_violation(_RandAccIter __i) { // Refinement of BidirectionalIterator _BidirectionalIterator_concept_specification<_RandAccIter>:: _BidirectionalIterator_requirement_violation(__i); // Refinement of LessThanComparable _LessThanComparable_concept_specification<_RandAccIter>:: _LessThanComparable_requirement_violation(__i); typedef typename __value_type_type_definition_requirement_violation<_RandAccIter> ::value_type value_type; typedef typename __difference_type_type_definition_requirement_violation<_RandAccIter> ::difference_type _Dist; typedef typename _Mutable_trait<_Dist>::_Type _MutDist; // Valid Expressions _STL_ERROR::__iterator_addition_assignment_requirement_violation(__i, _MutDist()); _STL_ERROR::__iterator_addition_requirement_violation(__i, _MutDist()); _STL_ERROR:: __iterator_subtraction_assignment_requirement_violation(__i, _MutDist()); _STL_ERROR::__iterator_subtraction_requirement_violation(__i, _MutDist()); _STL_ERROR::__difference_operator_requirement_violation(__i, __i, _MutDist()); typename _Mutable_trait::_Type* __dummy_ptr = 0; _STL_ERROR::__element_access_operator_requirement_violation(__i, __dummy_ptr, _MutDist()); } }; template struct _Mutable_RandomAccessIterator_concept_specification { static void _Mutable_RandomAccessIterator_requirement_violation(_RandAccIter __i) { _RandomAccessIterator_concept_specification<_RandAccIter>:: _RandomAccessIterator_requirement_violation(__i); // Refinement of mutable_BidirectionalIterator _Mutable_BidirectionalIterator_concept_specification<_RandAccIter>:: _Mutable_BidirectionalIterator_requirement_violation(__i); typedef typename __value_type_type_definition_requirement_violation<_RandAccIter> ::value_type value_type; typedef typename __difference_type_type_definition_requirement_violation<_RandAccIter> ::difference_type _Dist; typename _Mutable_trait::_Type* __tmp_ptr = 0; // Valid Expressions _STL_ERROR::__element_assignment_operator_requirement_violation(__i, __tmp_ptr, _Dist()); } }; #define __STL_TYPEDEF_REQUIREMENT(__REQUIREMENT) \ template \ struct __##__REQUIREMENT##__typedef_requirement_violation { \ typedef typename Type::__REQUIREMENT __REQUIREMENT; \ } __STL_TYPEDEF_REQUIREMENT(value_type); __STL_TYPEDEF_REQUIREMENT(difference_type); __STL_TYPEDEF_REQUIREMENT(size_type); __STL_TYPEDEF_REQUIREMENT(reference); __STL_TYPEDEF_REQUIREMENT(const_reference); __STL_TYPEDEF_REQUIREMENT(pointer); __STL_TYPEDEF_REQUIREMENT(const_pointer); template struct _Allocator_concept_specification { static void _Allocator_requirement_violation(_Alloc __a) { // Refinement of DefaultConstructible _DefaultConstructible_concept_specification<_Alloc>:: _DefaultConstructible_requirement_violation(__a); // Refinement of EqualityComparable _EqualityComparable_concept_specification<_Alloc>:: _EqualityComparable_requirement_violation(__a); // Associated Types __value_type__typedef_requirement_violation<_Alloc>(); __difference_type__typedef_requirement_violation<_Alloc>(); __size_type__typedef_requirement_violation<_Alloc>(); __reference__typedef_requirement_violation<_Alloc>(); __const_reference__typedef_requirement_violation<_Alloc>(); __pointer__typedef_requirement_violation<_Alloc>(); __const_pointer__typedef_requirement_violation<_Alloc>(); typedef typename _Alloc::value_type _Tp; //__STL_REQUIRES_SAME_TYPE(typename _Alloc::__STL_TEMPLATE rebind<_Tp>::other, // _Alloc); } }; #endif /* __STL_USE_CONCEPT_CHECKS */ #endif /* __CONCEPT_CHECKS_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/container_concepts.h ================================================ /* * Copyright (c) 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. */ #ifndef __STL_CONTAINER_CONCEPTS_H #define __STL_CONTAINER_CONCEPTS_H #include #ifdef __STL_USE_CONCEPT_CHECKS // This file covers the following concepts: // _Container // _ForwardContainer // _ReversibleContainer // _const_ReversibleContainer // _RandomAccessContainer // struct _ERROR_IN_STL_CONTAINER { /* Container expresssions */ template static void __begin_iterator_accessor_requirement_violation(_Container __c) { __c.begin(); } template static void __const_begin_iterator_accessor_requirement_violation(const _Container& __c) { __c.begin(); } template static void __end_iterator_accessor_requirement_violation(_Container __c) { __c.end(); } template static void __const_end_iterator_accessor_requirement_violation(const _Container& __c) { __c.end(); } template static void __rbegin_iterator_accessor_requirement_violation(_Container __c) { __c.rbegin(); } template static void __const_rbegin_iterator_accessor_requirement_violation(const _Container& __c) { __c.rbegin(); } template static void __rend_iterator_accessor_requirement_violation(_Container __c) { __c.rend(); } template static void __const_rend_iterator_accessor_requirement_violation(const _Container& __c) { __c.rend(); } template static void __size_function_must_be_const(const _Container& __c) { __c.size(); } template static void __size_function_requirement_violation(_Container& __c) { __c.size(); __size_function_must_be_const(__c); } template static void __max_size_function_must_be_const(const _Container& __c) { __c.max_size(); } template static void __max_size_function_requirement_violation(_Container& __c) { __c.max_size(); __max_size_function_must_be_const(__c); } template static void __empty_function_must_be_const(const _Container& __c) { __c.empty(); } template static void __empty_function_requirement_violation(_Container& __c) { __c.empty(); __empty_function_must_be_const(__c); } template static void __swap_function_requirement_violation(_Container& __c) { __c.swap(__c); } }; __STL_TYPEDEF_REQUIREMENT(iterator); __STL_TYPEDEF_REQUIREMENT(const_iterator); /* Containers */ template struct _Container_concept_specification { static void _Container_requirement_violation(_Container __c) { // Refinement of Assignable _Assignable_concept_specification<_Container>::_Assignable_requirement_violation(__c); // Associated Types __value_type__typedef_requirement_violation<_Container>(); __difference_type__typedef_requirement_violation<_Container>(); __size_type__typedef_requirement_violation<_Container>(); __reference__typedef_requirement_violation<_Container>(); __const_reference__typedef_requirement_violation<_Container>(); __pointer__typedef_requirement_violation<_Container>(); __const_pointer__typedef_requirement_violation<_Container>(); __iterator__typedef_requirement_violation<_Container>(); __const_iterator__typedef_requirement_violation<_Container>(); // Valid Expressions _ERROR_IN_STL_CONTAINER::__const_begin_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__const_end_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__begin_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__end_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__size_function_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__max_size_function_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__empty_function_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__swap_function_requirement_violation(__c); // Requirements on Iterators typedef typename _Container::iterator iter; typedef typename _Container::const_iterator const_iter; _InputIterator_concept_specification::_InputIterator_requirement_violation(const_iter()); _InputIterator_concept_specification::_InputIterator_requirement_violation(iter()); } }; template struct _ForwardContainer_concept_specification { static void _ForwardContainer_requirement_violation(_ForwardContainer __c) { // Refinement of Container _Container_concept_specification<_ForwardContainer>::_Container_requirement_violation(__c); // Requirements on Iterators typedef typename _ForwardContainer::iterator iter; typedef typename _ForwardContainer::const_iterator const_iter; _ForwardIterator_concept_specification::_ForwardIterator_requirement_violation(const_iter()); _Mutable_ForwardIterator_concept_specification::_Mutable_ForwardIterator_requirement_violation(iter()); } }; __STL_TYPEDEF_REQUIREMENT(reverse_iterator); __STL_TYPEDEF_REQUIREMENT(const_reverse_iterator); template struct _ReversibleContainer_concept_specification { static void _ReversibleContainer_requirement_violation(_ReversibleContainer __c) { // Refinement of ForwardContainer _ForwardContainer_concept_specification<_ReversibleContainer>::_ForwardContainer_requirement_violation(__c); // Associated types __reverse_iterator__typedef_requirement_violation<_ReversibleContainer>(); __const_reverse_iterator__typedef_requirement_violation<_ReversibleContainer>(); // Valid Expressions _ERROR_IN_STL_CONTAINER::__const_rbegin_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__const_rend_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__rbegin_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__rend_iterator_accessor_requirement_violation(__c); // Requirements on Iterators typedef typename _ReversibleContainer::iterator iter; typedef typename _ReversibleContainer::const_iterator const_iter; _BidirectionalIterator_concept_specification::_BidirectionalIterator_requirement_violation(const_iter()); _Mutable_BidirectionalIterator_concept_specification::_Mutable_BidirectionalIterator_requirement_violation(iter()); } }; template struct _const_ReversibleContainer_concept_specification { static void _const_ReversibleContainer_requirement_violation(_ReversibleContainer __c) { // Refinement of Container (JGS, not ForwardContainer) _Container_concept_specification<_ReversibleContainer>::_Container_requirement_violation(__c); // Associated types __reverse_iterator__typedef_requirement_violation<_ReversibleContainer>(); __const_reverse_iterator__typedef_requirement_violation<_ReversibleContainer>(); // Valid Expressions _ERROR_IN_STL_CONTAINER::__const_rbegin_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__const_rend_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__rbegin_iterator_accessor_requirement_violation(__c); _ERROR_IN_STL_CONTAINER::__rend_iterator_accessor_requirement_violation(__c); // Requirements on Iterators typedef typename _ReversibleContainer::iterator iter; typedef typename _ReversibleContainer::const_iterator const_iter; // This line won't compile on gcc 2.91 due to a compiler bug. #if !(__GNUC__ == 2 && __GNUC_MINOR__ == 91) __BidirectionalIterator_concept_specification::_BidirectionalIterator_requirement_violation(const_iter()); #endif } }; template struct _RandomAccessContainer_concept_specification { static void _RandomAccessContainer_requirement_violation(_RandomAccessContainer __c) { // Refinement of ReversibleContainer _ReversibleContainer_concept_specification<_RandomAccessContainer>::_ReversibleContainer_requirement_violation(__c); // Valid Expressions typedef typename _RandomAccessContainer::value_type __T; typedef typename _RandomAccessContainer::difference_type _Dist; typedef typename _Mutable_trait<__T>::_Type Type; typedef Type* _TypePtr; typedef typename _Mutable_trait<_Dist>::_Type Dist; _STL_ERROR::__element_access_operator_requirement_violation(__c, _TypePtr(), Dist()); // Requirements on Iterators typedef typename _RandomAccessContainer::iterator iter; typedef typename _RandomAccessContainer::const_iterator const_iter; _RandomAccessIterator_concept_specification::_RandomAccessIterator_requirement_violation(const_iter()); _Mutable_RandomAccessIterator_concept_specification::_Mutable_RandomAccessIterator_requirement_violation(iter()); } }; #endif /* if __STL_USE_CONCEPT_CHECKS */ #endif /* __STL_CONTAINER_CONCEPTS_H */ ================================================ FILE: stl-3.3-source/defalloc.h ================================================ /* * * 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 . #ifndef DEFALLOC_H #define DEFALLOC_H #include #include #include #include #include #include template inline T* allocate(ptrdiff_t size, T*) { set_new_handler(0); T* tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); if (tmp == 0) { cerr << "out of memory" << endl; exit(1); } return tmp; } template inline void deallocate(T* buffer) { ::operator delete(buffer); } template class allocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& 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(T))); } size_type max_size() const { return max(size_type(1), size_type(UINT_MAX/sizeof(T))); } }; class allocator { public: typedef void* pointer; }; #endif ================================================ FILE: stl-3.3-source/deque ================================================ /* * * 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 __SGI_STL_DEQUE #define __SGI_STL_DEQUE #include #include #include #include #include #include #endif /* __SGI_STL_DEQUE */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/deque.h ================================================ /* * * 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 __SGI_STL_DEQUE_H #define __SGI_STL_DEQUE_H #include #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::deque; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_DEQUE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/function.h ================================================ /* * * 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 __SGI_STL_FUNCTION_H #define __SGI_STL_FUNCTION_H #ifndef __STL_CONFIG_H #include #endif #ifndef __SGI_STL_INTERNAL_RELOPS #include #endif #include #ifndef __SGI_STL_INTERNAL_FUNCTION_H #include #endif #ifdef __STL_USE_NAMESPACE_FOR_RELOPS // Names from stl_relops.h using __STD_RELOPS::operator!=; using __STD_RELOPS::operator>; using __STD_RELOPS::operator<=; using __STD_RELOPS::operator>=; #endif /* __STL_USE_NAMESPACE_FOR_RELOPS */ #ifdef __STL_USE_NAMESPACES // 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::identity_element; 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::unary_compose; using __STD::binary_compose; using __STD::compose1; using __STD::compose2; using __STD::pointer_to_unary_function; using __STD::pointer_to_binary_function; using __STD::ptr_fun; using __STD::identity; using __STD::select1st; using __STD::select2nd; using __STD::project1st; using __STD::project2nd; using __STD::constant_void_fun; using __STD::constant_unary_fun; using __STD::constant_binary_fun; using __STD::constant0; using __STD::constant1; using __STD::constant2; using __STD::subtractive_rng; 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; using __STD::mem_fun1; using __STD::mem_fun1_ref; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_FUNCTION_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/functional ================================================ /* * 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 __SGI_STL_FUNCTIONAL #define __SGI_STL_FUNCTIONAL #include #include #include #endif /* __SGI_STL_FUNCTIONAL */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/hash_map ================================================ /* * 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 __SGI_STL_HASH_MAP #define __SGI_STL_HASH_MAP #ifndef __SGI_STL_INTERNAL_HASHTABLE_H #include #endif #include #endif /* __SGI_STL_HASH_MAP */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/hash_map.h ================================================ /* * 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 __SGI_STL_HASH_MAP_H #define __SGI_STL_HASH_MAP_H #ifndef __SGI_STL_INTERNAL_HASHTABLE_H #include #endif #include #include #ifdef __STL_USE_NAMESPACES using __STD::hash; using __STD::hashtable; using __STD::hash_map; using __STD::hash_multimap; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_HASH_MAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/hash_set ================================================ /* * 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 __SGI_STL_HASH_SET #define __SGI_STL_HASH_SET #ifndef __SGI_STL_INTERNAL_HASHTABLE_H #include #endif #include #endif /* __SGI_STL_HASH_SET */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/hash_set.h ================================================ /* * 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 __SGI_STL_HASH_SET_H #define __SGI_STL_HASH_SET_H #ifndef __SGI_STL_INTERNAL_HASHTABLE_H #include #endif #include #include #ifdef __STL_USE_NAMESPACES using __STD::hash; using __STD::hashtable; using __STD::hash_set; using __STD::hash_multiset; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_HASH_SET_H */ ================================================ FILE: stl-3.3-source/hashtable.h ================================================ /* * 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 __SGI_STL_HASHTABLE_H #define __SGI_STL_HASHTABLE_H #include #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::hash; using __STD::hashtable; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_HASHTABLE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/heap.h ================================================ /* * * 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 __SGI_STL_HEAP_H #define __SGI_STL_HEAP_H #include #include #ifdef __STL_USE_NAMESPACES using __STD::push_heap; using __STD::pop_heap; using __STD::make_heap; using __STD::sort_heap; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_HEAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/iterator ================================================ /* * * 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 __SGI_STL_ITERATOR #define __SGI_STL_ITERATOR #include #include #include #ifdef __STL_USE_NEW_IOSTREAMS #include #else /* __STL_USE_NEW_IOSTREAMS */ #include #endif /* __STL_USE_NEW_IOSTREAMS */ #include #include #endif /* __SGI_STL_ITERATOR */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/iterator.h ================================================ /* * * 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 __SGI_STL_ITERATOR_H #define __SGI_STL_ITERATOR_H #ifndef __SGI_STL_FUNCTION_H #include #endif #include #ifdef __STL_USE_NEW_IOSTREAMS #include #else /* __STL_USE_NEW_IOSTREAMS */ #include #endif /* __STL_USE_NEW_IOSTREAMS */ #ifndef __SGI_STL_INTERNAL_ITERATOR_BASE_H #include #endif #ifndef __SGI_STL_INTERNAL_ITERATOR_H #include #endif #ifndef __TYPE_TRAITS_H #include #endif #ifndef __SGI_STL_INTERNAL_CONSTRUCT_H #include #endif #ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H #include #endif #ifdef __STL_USE_NAMESPACES // 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 using __STD::input_iterator; using __STD::output_iterator; using __STD::forward_iterator; using __STD::bidirectional_iterator; using __STD::random_access_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION using __STD::iterator_traits; #endif using __STD::iterator_category; using __STD::distance_type; using __STD::value_type; using __STD::distance; 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::reverse_bidirectional_iterator; using __STD::istream_iterator; using __STD::ostream_iterator; // Names from stl_construct.h using __STD::construct; using __STD::destroy; // Names from stl_raw_storage_iter.h using __STD::raw_storage_iterator; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ITERATOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/limits ================================================ /* * 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. */ /* NOTE: This is not portable code. Parts of numeric_limits<> are * inherently machine-dependent. At present this file is suitable * for the MIPS and ia32 architectures. */ #ifndef __SGI_CPP_LIMITS #define __SGI_CPP_LIMITS #include #include #include __STL_BEGIN_NAMESPACE enum float_round_style { round_indeterminate = -1, round_toward_zero = 0, round_to_nearest = 1, round_toward_infinity = 2, round_toward_neg_infinity = 3 }; enum float_denorm_style { denorm_indeterminate = -1, denorm_absent = 0, denorm_present = 1 }; // The C++ standard (section 18.2.1) requires that some of the members of // numeric_limits be static const data members that are given constant- // initializers within the class declaration. On compilers where the // __STL_STATIC_CONST_INIT_BUG macro is defined, it is impossible to write // a standard-conforming numeric_limits class. // // There are two possible workarounds: either initialize the data // members outside the class, or change them from data members to // enums. Neither workaround is satisfactory: the former makes it // impossible to use the data members in constant-expressions, and the // latter means they have the wrong type and that it is impossible to // take their addresses. We choose the former workaround. #ifdef __STL_STATIC_CONST_INIT_BUG # define __STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ enum { __mem_name = __mem_value } #else /* __STL_STATIC_CONST_INIT_BUG */ # define __STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ static const __mem_type __mem_name = __mem_value #endif /* __STL_STATIC_CONST_INIT_BUG */ // Base class for all specializations of numeric_limits. template class _Numeric_limits_base { public: __STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, false); static __number min() __STL_NOTHROW { return __number(); } static __number max() __STL_NOTHROW { return __number(); } __STL_DECLARE_LIMITS_MEMBER(int, digits, 0); __STL_DECLARE_LIMITS_MEMBER(int, digits10, 0); __STL_DECLARE_LIMITS_MEMBER(bool, is_signed, false); __STL_DECLARE_LIMITS_MEMBER(bool, is_integer, false); __STL_DECLARE_LIMITS_MEMBER(bool, is_exact, false); __STL_DECLARE_LIMITS_MEMBER(int, radix, 0); static __number epsilon() __STL_NOTHROW { return __number(); } static __number round_error() __STL_NOTHROW { return __number(); } __STL_DECLARE_LIMITS_MEMBER(int, min_exponent, 0); __STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, 0); __STL_DECLARE_LIMITS_MEMBER(int, max_exponent, 0); __STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, 0); __STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, false); __STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, false); __STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, false); __STL_DECLARE_LIMITS_MEMBER(float_denorm_style, has_denorm, denorm_absent); __STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); static __number infinity() __STL_NOTHROW { return __number(); } static __number quiet_NaN() __STL_NOTHROW { return __number(); } static __number signaling_NaN() __STL_NOTHROW { return __number(); } static __number denorm_min() __STL_NOTHROW { return __number(); } __STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, false); __STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, false); __STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, false); __STL_DECLARE_LIMITS_MEMBER(bool, traps, false); __STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); __STL_DECLARE_LIMITS_MEMBER(float_round_style, round_style, round_toward_zero); }; #ifdef __STL_STATIC_CONST_INIT_BUG # define __STL_DEFINE_NUMERIC_BASE_MEMBER(__type, __mem) #else /* __STL_STATIC_CONST_INIT_BUG */ # define __STL_DEFINE_NUMERIC_BASE_MEMBER(__type, __mem) \ template \ const __type _Numeric_limits_base<__number>:: __mem #endif /* __STL_STATIC_CONST_INIT_BUG */ __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_specialized); __STL_DEFINE_NUMERIC_BASE_MEMBER(int, digits); __STL_DEFINE_NUMERIC_BASE_MEMBER(int, digits10); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_signed); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_integer); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_exact); __STL_DEFINE_NUMERIC_BASE_MEMBER(int, radix); __STL_DEFINE_NUMERIC_BASE_MEMBER(int, min_exponent); __STL_DEFINE_NUMERIC_BASE_MEMBER(int, max_exponent); __STL_DEFINE_NUMERIC_BASE_MEMBER(int, min_exponent10); __STL_DEFINE_NUMERIC_BASE_MEMBER(int, max_exponent10); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, has_infinity); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, has_quiet_NaN); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, has_signaling_NaN); __STL_DEFINE_NUMERIC_BASE_MEMBER(float_denorm_style, has_denorm); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, has_denorm_loss); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_iec559); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_bounded); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, is_modulo); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, traps); __STL_DEFINE_NUMERIC_BASE_MEMBER(bool, tinyness_before); __STL_DEFINE_NUMERIC_BASE_MEMBER(float_round_style, round_style); // Base class for integers. template class _Integer_limits : public _Numeric_limits_base<_Int> { public: __STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); static _Int min() __STL_NOTHROW { return __imin; } static _Int max() __STL_NOTHROW { return __imax; } __STL_DECLARE_LIMITS_MEMBER(int, digits, (__idigits < 0) ? (int)(sizeof(_Int) * CHAR_BIT) - (__imin == 0 ? 0 : 1) : __idigits); __STL_DECLARE_LIMITS_MEMBER(int, digits10, (digits * 301) / 1000); // log 2 = 0.301029995664... __STL_DECLARE_LIMITS_MEMBER(bool, is_signed, __imin != 0); __STL_DECLARE_LIMITS_MEMBER(bool, is_integer, true); __STL_DECLARE_LIMITS_MEMBER(bool, is_exact, true); __STL_DECLARE_LIMITS_MEMBER(int, radix, 2); __STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); __STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, __ismod); }; #ifdef __STL_STATIC_CONST_INIT_BUG # define __STL_DEFINE_INTEGER_LIMITS_MEMBER(__type, __mem) #else /* __STL_STATIC_CONST_INIT_BUG */ # define __STL_DEFINE_INTEGER_LIMITS_MEMBER(__type, __mem) \ template \ const __type _Integer_limits<_Int, __imin, __imax, __idig, __ismod>::__mem #endif /* __STL_STATIC_CONST_INIT_BUG */ __STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_specialized); __STL_DEFINE_INTEGER_LIMITS_MEMBER(int, digits); __STL_DEFINE_INTEGER_LIMITS_MEMBER(int, digits10); __STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_signed); __STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_integer); __STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_exact); __STL_DEFINE_INTEGER_LIMITS_MEMBER(int, radix); __STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_bounded); __STL_DEFINE_INTEGER_LIMITS_MEMBER(bool, is_modulo); // Base class for floating-point numbers. template class _Floating_limits : public _Numeric_limits_base<__number> { public: __STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); __STL_DECLARE_LIMITS_MEMBER(int, digits, __Digits); __STL_DECLARE_LIMITS_MEMBER(int, digits10, __Digits10); __STL_DECLARE_LIMITS_MEMBER(bool, is_signed, true); __STL_DECLARE_LIMITS_MEMBER(int, radix, 2); __STL_DECLARE_LIMITS_MEMBER(int, min_exponent, __MinExp); __STL_DECLARE_LIMITS_MEMBER(int, max_exponent, __MaxExp); __STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, __MinExp10); __STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, __MaxExp10); __STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, true); __STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, true); __STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, true); __STL_DECLARE_LIMITS_MEMBER(float_denorm_style, has_denorm, denorm_indeterminate); __STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); __STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, __IsIEC559); __STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); __STL_DECLARE_LIMITS_MEMBER(bool, traps, true); __STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); __STL_DECLARE_LIMITS_MEMBER(float_round_style, round_style, __RoundStyle); }; #ifdef __STL_STATIC_CONST_INIT_BUG # define __STL_DEFINE_FLOAT_LIMITS_MEMBER(__type, __mem) #else /* __STL_STATIC_CONST_INIT_BUG */ # define __STL_DEFINE_FLOAT_LIMITS_MEMBER(__type, __mem) \ template \ const __type _Floating_limits<__Num, __Dig, __Dig10, \ __MnX, __MxX, __MnX10, __MxX10, \ __IsIEEE, __Sty>:: __mem #endif /* __STL_STATIC_CONST_INIT_BUG */ __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, is_specialized); __STL_DEFINE_FLOAT_LIMITS_MEMBER(int, digits); __STL_DEFINE_FLOAT_LIMITS_MEMBER(int, digits10); __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, is_signed); __STL_DEFINE_FLOAT_LIMITS_MEMBER(int, radix); __STL_DEFINE_FLOAT_LIMITS_MEMBER(int, min_exponent); __STL_DEFINE_FLOAT_LIMITS_MEMBER(int, max_exponent); __STL_DEFINE_FLOAT_LIMITS_MEMBER(int, min_exponent10); __STL_DEFINE_FLOAT_LIMITS_MEMBER(int, max_exponent10); __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, has_infinity); __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, has_quiet_NaN); __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, has_signaling_NaN); __STL_DEFINE_FLOAT_LIMITS_MEMBER(float_denorm_style, has_denorm); __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, has_denorm_loss); __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, is_iec559); __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, is_bounded); __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, traps); __STL_DEFINE_FLOAT_LIMITS_MEMBER(bool, tinyness_before); __STL_DEFINE_FLOAT_LIMITS_MEMBER(float_round_style, round_style); #undef __STL_DECLARE_NUMERIC_LIMITS_MEMBER #undef __STL_DEFINE_NUMERIC_BASE_MEMBER #undef __STL_DEFINE_INTEGER_LIMITS_MEMBER #undef __STL_DEFINE_FLOAT_LIMITS_MEMBER // Class numeric_limits // The unspecialized class. template class numeric_limits : public _Numeric_limits_base<_Tp> {}; // Specializations for all built-in integral types. #ifndef __STL_NO_BOOL __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; #endif /* __STL_NO_BOOL */ __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; #ifdef __STL_HAS_WCHAR_T __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; #endif __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; #ifdef __STL_LONG_LONG // Some compilers have long long, but don't define the // LONGLONG_MIN and LONGLONG_MAX macros in limits.h. This // assumes that long long is 64 bits. #if !defined(LONGLONG_MIN) && !defined(LONGLONG_MAX) \ && !defined(ULONGLONG_MAX) #define ULONGLONG_MAX 0xffffffffffffffffLLU #define LONGLONG_MAX 0x7fffffffffffffffLL #define LONGLONG_MIN (-LONGLONG_MAX - 1LL) #endif __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; __STL_TEMPLATE_NULL class numeric_limits : public _Integer_limits {}; #endif /* __STL_LONG_LONG */ // Specializations for all built-in floating-point type. __STL_TEMPLATE_NULL class numeric_limits : public _Floating_limits { public: static float min() __STL_NOTHROW { return FLT_MIN; } static float denorm_min() __STL_NOTHROW { return FLT_MIN; } static float max() __STL_NOTHROW { return FLT_MAX; } static float epsilon() __STL_NOTHROW { return FLT_EPSILON; } static float round_error() __STL_NOTHROW { return 0.5f; } // Units: ulps. static float infinity() __STL_NOTHROW; static float quiet_NaN() __STL_NOTHROW; static float signaling_NaN() __STL_NOTHROW; }; __STL_TEMPLATE_NULL class numeric_limits : public _Floating_limits { public: static double min() __STL_NOTHROW { return DBL_MIN; } static double denorm_min() __STL_NOTHROW { return DBL_MIN; } static double max() __STL_NOTHROW { return DBL_MAX; } static double epsilon() __STL_NOTHROW { return DBL_EPSILON; } static double round_error() __STL_NOTHROW { return 0.5; } // Units: ulps. static double infinity() __STL_NOTHROW; static double quiet_NaN() __STL_NOTHROW; static double signaling_NaN() __STL_NOTHROW; }; __STL_TEMPLATE_NULL class numeric_limits : public _Floating_limits { public: static long double min() __STL_NOTHROW { return LDBL_MIN; } static long double denorm_min() __STL_NOTHROW { return LDBL_MIN; } static long double max() __STL_NOTHROW { return LDBL_MAX; } static long double epsilon() __STL_NOTHROW { return LDBL_EPSILON; } static long double round_error() __STL_NOTHROW { return 4; } // Units: ulps. static long double infinity() __STL_NOTHROW; static long double quiet_NaN() __STL_NOTHROW; static long double signaling_NaN() __STL_NOTHROW; }; // We write special values (Inf and NaN) as bit patterns and // cast the the appropriate floating-point types. #if defined(_MIPSEB) // Big-endian MIPS. float is 32 bits, double 64, long double 128. #define _Define_float(__f, __h, __l) \ inline float numeric_limits::__f() __STL_NOTHROW { \ static const unsigned short __x[2] = { __h, __l }; \ return *reinterpret_cast(__x); } #define _Define_double(__f, __h, __l) \ inline double numeric_limits::__f() __STL_NOTHROW { \ static const unsigned short __x[4] = { __h, __l }; \ return *reinterpret_cast(__x); } #define _Define_ldouble(__f, __h, __l) \ inline long double numeric_limits::__f() __STL_NOTHROW { \ static const unsigned short __x[8] = { __h, __l }; \ return *reinterpret_cast(__x); } _Define_float(infinity, 0x7f80, 0) _Define_float(quiet_NaN, 0x7f81, 0) _Define_float(signaling_NaN, 0x7fc1, 0) _Define_double(infinity, 0x7ff0, 0) _Define_double(quiet_NaN, 0x7ff1, 0) _Define_double(signaling_NaN, 0x7ff9, 0) _Define_ldouble(infinity, 0x7ff0, 0) _Define_ldouble(quiet_NaN, 0x7ff1, 0) _Define_ldouble(signaling_NaN, 0x7ff9, 0) #elif defined(__i386) || defined(_M_IX86) // Little-endian ia32. float is 32 bits, double 64, long double 80. #define _Define_float(__f, __h, __l) \ inline float numeric_limits::__f() __STL_NOTHROW { \ static const unsigned short __x[2] = { __l, __h }; \ return *reinterpret_cast(__x); } #define _Define_double(__f, __h, __l) \ inline double numeric_limits::__f() __STL_NOTHROW { \ static const unsigned short __x[4] = { 0, 0, __l, __h }; \ return *reinterpret_cast(__x); } #define _Define_ldouble(__f, __h, __l) \ inline long double numeric_limits::__f() __STL_NOTHROW { \ static const unsigned short __x[5] = { 0, 0, 0, __l, __h }; \ return *reinterpret_cast(__x); } _Define_float(infinity, 0x7f80, 0) _Define_float(quiet_NaN, 0x7fa0, 0) _Define_float(signaling_NaN, 0x7fc0, 0) _Define_double(infinity, 0x7ff0, 0) _Define_double(quiet_NaN, 0x7ff4, 0) _Define_double(signaling_NaN, 0x7ff8, 0) _Define_ldouble(infinity, 0x7fff, 0x8000) _Define_ldouble(quiet_NaN, 0x7fff, 0xa000) _Define_ldouble(signaling_NaN, 0x7fff, 0xc000) #else /* This is an architecture we don't know how to handle. Return some obviously wrong values. */ #define _Define_float(__f) \ inline float numeric_limits::__f() __STL_NOTHROW { \ return 0; } #define _Define_double(__f) \ inline double numeric_limits::__f() __STL_NOTHROW { \ return 0; } #define _Define_ldouble(__f) \ inline long double numeric_limits::__f() __STL_NOTHROW { \ return 0; } _Define_float(infinity) _Define_float(quiet_NaN) _Define_float(signaling_NaN) _Define_double(infinity) _Define_double(quiet_NaN) _Define_double(signaling_NaN) _Define_ldouble(infinity) _Define_ldouble(quiet_NaN) _Define_ldouble(signaling_NaN) #endif #undef _Define_float #undef _Define_double #undef _Define_ldouble __STL_END_NAMESPACE #endif /* __SGI_CPP_LIMITS */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/list ================================================ /* * * 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 __SGI_STL_LIST #define __SGI_STL_LIST #include #include #include #include #include #endif /* __SGI_STL_LIST */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/list.h ================================================ /* * * 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 __SGI_STL_LIST_H #define __SGI_STL_LIST_H #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::list; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_LIST_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/map ================================================ /* * * 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 __SGI_STL_MAP #define __SGI_STL_MAP #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #endif /* __SGI_STL_MAP */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/map.h ================================================ /* * * 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 __SGI_STL_MAP_H #define __SGI_STL_MAP_H #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::rb_tree; using __STD::map; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_MAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/memory ================================================ /* * 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. * */ #ifndef __SGI_STL_MEMORY #define __SGI_STL_MEMORY #include #include #include #include #include #include __STL_BEGIN_NAMESPACE #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \ defined(__STL_MEMBER_TEMPLATES) template struct auto_ptr_ref { _Tp1* _M_ptr; auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} }; #endif template class auto_ptr { private: _Tp* _M_ptr; public: typedef _Tp element_type; explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {} auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {} #ifdef __STL_MEMBER_TEMPLATES template auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW : _M_ptr(__a.release()) {} #endif /* __STL_MEMBER_TEMPLATES */ auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW { if (&__a != this) { delete _M_ptr; _M_ptr = __a.release(); } return *this; } #ifdef __STL_MEMBER_TEMPLATES template auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW { if (__a.get() != this->get()) { delete _M_ptr; _M_ptr = __a.release(); } return *this; } #endif /* __STL_MEMBER_TEMPLATES */ // Note: 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 (17.4.3.6/2) // this is prohibited. ~auto_ptr() { delete _M_ptr; } _Tp& operator*() const __STL_NOTHROW { return *_M_ptr; } _Tp* operator->() const __STL_NOTHROW { return _M_ptr; } _Tp* get() const __STL_NOTHROW { return _M_ptr; } _Tp* release() __STL_NOTHROW { _Tp* __tmp = _M_ptr; _M_ptr = 0; return __tmp; } void reset(_Tp* __p = 0) __STL_NOTHROW { if (__p != _M_ptr) { delete _M_ptr; _M_ptr = __p; } } // According to the C++ standard, these conversions are required. Most // present-day compilers, however, do not enforce that requirement---and, // in fact, most present-day compilers do not support the language // features that these conversions rely on. #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \ defined(__STL_MEMBER_TEMPLATES) public: auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW : _M_ptr(__ref._M_ptr) {} auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW { if (__ref._M_ptr != this->get()) { delete _M_ptr; _M_ptr = __ref._M_ptr; } return *this; } template operator auto_ptr_ref<_Tp1>() __STL_NOTHROW { return auto_ptr_ref<_Tp1>(this->release()); } template operator auto_ptr<_Tp1>() __STL_NOTHROW { return auto_ptr<_Tp1>(this->release()); } #endif /* auto ptr conversions && member templates */ }; __STL_END_NAMESPACE #endif /* __SGI_STL_MEMORY */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/multimap.h ================================================ /* * * 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 __SGI_STL_MULTIMAP_H #define __SGI_STL_MULTIMAP_H #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::rb_tree; using __STD::multimap; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_MULTIMAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/multiset.h ================================================ /* * * 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 __SGI_STL_MULTISET_H #define __SGI_STL_MULTISET_H #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::rb_tree; using __STD::multiset; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_MULTISET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/numeric ================================================ /* * * 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 __SGI_STL_NUMERIC #define __SGI_STL_NUMERIC #include #include #include #ifdef __STL_USE_NEW_IOSTREAMS #include #else /* __STL_USE_NEW_IOSTREAMS */ #include #endif /* __STL_USE_NEW_IOSTREAMS */ #include #include #include #include #endif /* __SGI_STL_NUMERIC */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/pair.h ================================================ /* * * 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 __SGI_STL_PAIR_H #define __SGI_STL_PAIR_H #ifndef __STL_CONFIG_H #include #endif #ifndef __SGI_STL_INTERNAL_RELOPS #include #endif #ifndef __SGI_STL_INTERNAL_PAIR_H #include #endif #ifdef __STL_USE_NAMESPACES using __STD::pair; using __STD::make_pair; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_PAIR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/pthread_alloc ================================================ /* * 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 __SGI_STL_PTHREAD_ALLOC #define __SGI_STL_PTHREAD_ALLOC // Pthread-specific node allocator. // This is similar to the default allocator, except that free-list // information is kept separately for each thread, avoiding locking. // This should be reasonably fast even in the presence of threads. // The down side is that storage may not be well-utilized. // It is not an error to allocate memory in thread A and deallocate // it in thread B. But this effectively transfers ownership of the memory, // so that it can only be reallocated by thread B. Thus this can effectively // result in a storage leak if it's done on a regular basis. // It can also result in frequent sharing of // cache lines among processors, with potentially serious performance // consequences. #include #include #include #ifndef __RESTRICT # define __RESTRICT #endif #ifndef __STL_NO_BAD_ALLOC # include #endif __STL_BEGIN_NAMESPACE #define __STL_DATA_ALIGNMENT 8 union _Pthread_alloc_obj { union _Pthread_alloc_obj * __free_list_link; char __client_data[__STL_DATA_ALIGNMENT]; /* The client sees this. */ }; // Pthread allocators don't appear to the client to have meaningful // instances. We do in fact need to associate some state with each // thread. That state is represented by // _Pthread_alloc_per_thread_state<_Max_size>. template struct _Pthread_alloc_per_thread_state { typedef _Pthread_alloc_obj __obj; enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT }; _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS]; _Pthread_alloc_per_thread_state<_Max_size> * __next; // Free list link for list of available per thread structures. // When one of these becomes available for reuse due to thread // termination, any objects in its free list remain associated // with it. The whole structure may then be used by a newly // created thread. _Pthread_alloc_per_thread_state() : __next(0) { memset((void *)__free_list, 0, (size_t) _S_NFREELISTS * sizeof(__obj *)); } // Returns an object of size __n, and possibly adds to size n free list. void *_M_refill(size_t __n); }; // Pthread-specific allocator. // The argument specifies the largest object size allocated from per-thread // free lists. Larger objects are allocated using malloc_alloc. // Max_size must be a power of 2. template class _Pthread_alloc_template { public: // but only for internal use: typedef _Pthread_alloc_obj __obj; // Allocates a chunk for nobjs of size size. nobjs may be reduced // if it is inconvenient to allocate the requested number. static char *_S_chunk_alloc(size_t __size, int &__nobjs); enum {_S_ALIGN = __STL_DATA_ALIGNMENT}; static size_t _S_round_up(size_t __bytes) { return (((__bytes) + (int) _S_ALIGN-1) & ~((int) _S_ALIGN - 1)); } static size_t _S_freelist_index(size_t __bytes) { return (((__bytes) + (int) _S_ALIGN-1)/(int)_S_ALIGN - 1); } private: // Chunk allocation state. And other shared state. // Protected by _S_chunk_allocator_lock. static pthread_mutex_t _S_chunk_allocator_lock; static char *_S_start_free; static char *_S_end_free; static size_t _S_heap_size; static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states; static pthread_key_t _S_key; static bool _S_key_initialized; // Pthread key under which per thread state is stored. // Allocator instances that are currently unclaimed by any thread. static void _S_destructor(void *instance); // Function to be called on thread exit to reclaim per thread // state. static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state(); // Return a recycled or new per thread state. static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state(); // ensure that the current thread has an associated // per thread state. class _M_lock; friend class _M_lock; class _M_lock { public: _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); } ~_M_lock () { pthread_mutex_unlock(&_S_chunk_allocator_lock); } }; public: /* n must be > 0 */ static void * allocate(size_t __n) { __obj * volatile * __my_free_list; __obj * __RESTRICT __result; _Pthread_alloc_per_thread_state<_Max_size>* __a; if (__n > _Max_size) { return(malloc_alloc::allocate(__n)); } if (!_S_key_initialized || !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*) pthread_getspecific(_S_key))) { __a = _S_get_per_thread_state(); } __my_free_list = __a -> __free_list + _S_freelist_index(__n); __result = *__my_free_list; if (__result == 0) { void *__r = __a -> _M_refill(_S_round_up(__n)); return __r; } *__my_free_list = __result -> __free_list_link; return (__result); }; /* p may not be 0 */ static void deallocate(void *__p, size_t __n) { __obj *__q = (__obj *)__p; __obj * volatile * __my_free_list; _Pthread_alloc_per_thread_state<_Max_size>* __a; if (__n > _Max_size) { malloc_alloc::deallocate(__p, __n); return; } if (!_S_key_initialized || !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *) pthread_getspecific(_S_key))) { __a = _S_get_per_thread_state(); } __my_free_list = __a->__free_list + _S_freelist_index(__n); __q -> __free_list_link = *__my_free_list; *__my_free_list = __q; } static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz); } ; typedef _Pthread_alloc_template<> pthread_alloc; template void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance) { _M_lock __lock_instance; // Need to acquire lock here. _Pthread_alloc_per_thread_state<_Max_size>* __s = (_Pthread_alloc_per_thread_state<_Max_size> *)__instance; __s -> __next = _S_free_per_thread_states; _S_free_per_thread_states = __s; } template _Pthread_alloc_per_thread_state<_Max_size> * _Pthread_alloc_template<_Max_size>::_S_new_per_thread_state() { /* lock already held here. */ if (0 != _S_free_per_thread_states) { _Pthread_alloc_per_thread_state<_Max_size> *__result = _S_free_per_thread_states; _S_free_per_thread_states = _S_free_per_thread_states -> __next; return __result; } else { return new _Pthread_alloc_per_thread_state<_Max_size>; } } template _Pthread_alloc_per_thread_state<_Max_size> * _Pthread_alloc_template<_Max_size>::_S_get_per_thread_state() { /*REFERENCED*/ _M_lock __lock_instance; // Need to acquire lock here. int __ret_code; _Pthread_alloc_per_thread_state<_Max_size> * __result; if (!_S_key_initialized) { if (pthread_key_create(&_S_key, _S_destructor)) { __THROW_BAD_ALLOC; // defined in stl_alloc.h } _S_key_initialized = true; } __result = _S_new_per_thread_state(); __ret_code = pthread_setspecific(_S_key, __result); if (__ret_code) { if (__ret_code == ENOMEM) { __THROW_BAD_ALLOC; } else { // EINVAL abort(); } } return __result; } /* We allocate memory in large chunks in order to avoid fragmenting */ /* the malloc heap too much. */ /* We assume that size is properly aligned. */ template char *_Pthread_alloc_template<_Max_size> ::_S_chunk_alloc(size_t __size, int &__nobjs) { { char * __result; size_t __total_bytes; size_t __bytes_left; /*REFERENCED*/ _M_lock __lock_instance; // Acquire lock for this routine __total_bytes = __size * __nobjs; __bytes_left = _S_end_free - _S_start_free; if (__bytes_left >= __total_bytes) { __result = _S_start_free; _S_start_free += __total_bytes; return(__result); } else if (__bytes_left >= __size) { __nobjs = __bytes_left/__size; __total_bytes = __size * __nobjs; __result = _S_start_free; _S_start_free += __total_bytes; return(__result); } else { size_t __bytes_to_get = 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); // Try to make use of the left-over piece. if (__bytes_left > 0) { _Pthread_alloc_per_thread_state<_Max_size>* __a = (_Pthread_alloc_per_thread_state<_Max_size>*) pthread_getspecific(_S_key); __obj * volatile * __my_free_list = __a->__free_list + _S_freelist_index(__bytes_left); ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list; *__my_free_list = (__obj *)_S_start_free; } # ifdef _SGI_SOURCE // Try to get memory that's aligned on something like a // cache line boundary, so as to avoid parceling out // parts of the same line to different threads and thus // possibly different processors. { const int __cache_line_size = 128; // probable upper bound __bytes_to_get &= ~(__cache_line_size-1); _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get); if (0 == _S_start_free) { _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); } } # else /* !SGI_SOURCE */ _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); # endif _S_heap_size += __bytes_to_get; _S_end_free = _S_start_free + __bytes_to_get; } } // lock is released here return(_S_chunk_alloc(__size, __nobjs)); } /* Returns an object of size n, and optionally adds to size n free list.*/ /* We assume that n is properly aligned. */ /* We hold the allocation lock. */ template void *_Pthread_alloc_per_thread_state<_Max_size> ::_M_refill(size_t __n) { int __nobjs = 128; char * __chunk = _Pthread_alloc_template<_Max_size>::_S_chunk_alloc(__n, __nobjs); __obj * volatile * __my_free_list; __obj * __result; __obj * __current_obj, * __next_obj; int __i; if (1 == __nobjs) { return(__chunk); } __my_free_list = __free_list + _Pthread_alloc_template<_Max_size>::_S_freelist_index(__n); /* Build free list in chunk */ __result = (__obj *)__chunk; *__my_free_list = __next_obj = (__obj *)(__chunk + __n); for (__i = 1; ; __i++) { __current_obj = __next_obj; __next_obj = (__obj *)((char *)__next_obj + __n); if (__nobjs - 1 == __i) { __current_obj -> __free_list_link = 0; break; } else { __current_obj -> __free_list_link = __next_obj; } } return(__result); } template void *_Pthread_alloc_template<_Max_size> ::reallocate(void *__p, size_t __old_sz, size_t __new_sz) { void * __result; size_t __copy_sz; if (__old_sz > _Max_size && __new_sz > _Max_size) { return(realloc(__p, __new_sz)); } if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); __result = allocate(__new_sz); __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; memcpy(__result, __p, __copy_sz); deallocate(__p, __old_sz); return(__result); } template _Pthread_alloc_per_thread_state<_Max_size> * _Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0; template pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key; template bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false; template pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock = PTHREAD_MUTEX_INITIALIZER; template char *_Pthread_alloc_template<_Max_size> ::_S_start_free = 0; template char *_Pthread_alloc_template<_Max_size> ::_S_end_free = 0; template size_t _Pthread_alloc_template<_Max_size> ::_S_heap_size = 0; #ifdef __STL_USE_STD_ALLOCATORS template class pthread_allocator { typedef pthread_alloc _S_Alloc; // The underlying 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 struct rebind { typedef pthread_allocator<_NewType> other; }; pthread_allocator() __STL_NOTHROW {} pthread_allocator(const pthread_allocator& a) __STL_NOTHROW {} template pthread_allocator(const pthread_allocator<_OtherType>&) __STL_NOTHROW {} ~pthread_allocator() __STL_NOTHROW {} pointer address(reference __x) const { return &__x; } const_pointer address(const_reference __x) const { return &__x; } // __n is permitted to be 0. The C++ standard says nothing about what // the return value is when __n == 0. _Tp* allocate(size_type __n, const void* = 0) { return __n != 0 ? static_cast<_Tp*>(_S_Alloc::allocate(__n * sizeof(_Tp))) : 0; } // p is not permitted to be a null pointer. void deallocate(pointer __p, size_type __n) { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); } size_type max_size() const __STL_NOTHROW { return size_t(-1) / sizeof(_Tp); } void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } void destroy(pointer _p) { _p->~_Tp(); } }; template<> class pthread_allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef pthread_allocator<_NewType> other; }; }; template inline bool operator==(const _Pthread_alloc_template<_Max_size>&, const _Pthread_alloc_template<_Max_size>&) { return true; } template inline bool operator==(const pthread_allocator<_T1>&, const pthread_allocator<_T2>& a2) { return true; } template inline bool operator!=(const pthread_allocator<_T1>&, const pthread_allocator<_T2>&) { return false; } template struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type; typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> > allocator_type; }; template struct _Alloc_traits<_Tp, __allocator<_Atype, _Pthread_alloc_template<_Max> > > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type; typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type; }; template struct _Alloc_traits<_Tp, pthread_allocator<_Atype> > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type; typedef pthread_allocator<_Tp> allocator_type; }; #endif /* __STL_USE_STD_ALLOCATORS */ __STL_END_NAMESPACE #endif /* __SGI_STL_PTHREAD_ALLOC */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/pthread_alloc.h ================================================ /* * 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 __SGI_STL_PTHREAD_ALLOC_H #define __SGI_STL_PTHREAD_ALLOC_H #include #ifdef __STL_USE_NAMESPACES using __STD::_Pthread_alloc_template; using __STD::pthread_alloc; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_PTHREAD_ALLOC_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/queue ================================================ /* * * 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 __SGI_STL_QUEUE #define __SGI_STL_QUEUE #include #include #include #include #include #include #include #include #include #include #endif /* __SGI_STL_QUEUE */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/rope ================================================ /* * 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 __SGI_STL_ROPE #define __SGI_STL_ROPE #include #include #include #include #include #include #include #include #include #include #endif /* __SGI_STL_ROPE */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/rope.h ================================================ /* * 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 __SGI_STL_ROPE_H #define __SGI_STL_ROPE_H #include #include #ifdef __STL_USE_NAMESPACES using __STD::char_producer; using __STD::sequence_buffer; using __STD::rope; using __STD::crope; using __STD::wrope; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ROPE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/ropeimpl.h ================================================ /* * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ # include #ifdef __STL_USE_NEW_IOSTREAMS # include #else /* __STL_USE_NEW_IOSTREAMS */ # include #endif /* __STL_USE_NEW_IOSTREAMS */ #ifdef __STL_USE_EXCEPTIONS # include #endif __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif // 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 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 _RopeRep::_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 _RopeRep::_S_function: case _RopeRep::_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: __stl_assert(0); } } // Set path and buffer inside a rope iterator. We assume that // pos and root are already set. template void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache (_Rope_iterator_base<_CharT,_Alloc>& __x) { const _RopeRep* __path[_RopeRep::_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 __stl_assert(__pos <= __x._M_root->_M_size); 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; __stl_assert(__curr_depth <= _RopeRep::_S_max_rope_depth); __path[__curr_depth] = __curr_rope; switch(__curr_rope->_M_tag) { case _RopeRep::_S_leaf: case _RopeRep::_S_function: case _RopeRep::_S_substringfn: __x._M_leaf_pos = __curr_start_pos; goto done; case _RopeRep::_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 - _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 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; __stl_assert(__x._M_current_pos <= __x._M_root->_M_size); if (__x._M_current_pos - __node_start_pos < __len) { /* More stuff in this leaf, we just didn't cache it. */ _S_setbuf(__x); return; } __stl_assert(__node_start_pos + __len == __x._M_current_pos); // 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 (_RopeRep::_S_concat == __current_node->_M_tag) { ++__current_index; if (_S_path_cache_len == __current_index) { int __i; for (__i = 0; __i < _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 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 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 void _Rope_iterator<_CharT,_Alloc>::_M_check() { if (_M_root_rope->_M_tree_ptr != _M_root) { // _Rope was modified. Get things fixed up. _RopeRep::_S_unref(_M_root); _M_root = _M_root_rope->_M_tree_ptr; _RopeRep::_S_ref(_M_root); _M_buf_ptr = 0; } } template inline _Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator( const _Rope_iterator<_CharT,_Alloc>& __x) : _Rope_iterator_base<_CharT,_Alloc>(__x) { } template 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(_M_root); } template 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 inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string() { _CharT* __cstr = _M_c_string; if (0 != __cstr) { size_t __size = _M_size + 1; destroy(__cstr, __cstr + __size); _Data_deallocate(__cstr, __size); } } template #ifdef __STL_USE_STD_ALLOCATORS inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, size_t __n, allocator_type __a) #else inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, size_t __n) #endif { if (!_S_is_basic_char_type((_CharT*)0)) { destroy(__s, __s + __n); } // This has to be a static member, so this gets a bit messy # ifdef __STL_USE_STD_ALLOCATORS __a.deallocate( __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); # else _Data_deallocate( __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); # endif } // 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 void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() { switch(_M_tag) { case _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 _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 _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 _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 #ifdef __STL_USE_STD_ALLOCATORS inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string (const _CharT*, size_t, allocator_type) #else inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string (const _CharT*, size_t) #endif {} #endif // Concatenate a C string onto a leaf rope by copying the rope data. // Used for short ropes. template 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]); __STL_TRY { __result = _S_new_RopeLeaf(__new_data, __old_len + __len, __r->get_allocator()); } __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, __r->get_allocator())); return __result; } #ifndef __GC // As above, but it's OK to clobber original if refcount is 1 template rope<_CharT,_Alloc>::_RopeLeaf* rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter (_RopeLeaf* __r, const _CharT* __iter, size_t __len) { __stl_assert(__r->_M_ref_count >= 1); 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]); __stl_assert(__r->_M_c_string == __r->_M_data); } 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; __stl_assert(__r->_M_ref_count == 1); __r->_M_ref_count = 2; return __r; } else { _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); __stl_assert(__result->_M_ref_count == 1); 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 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; # ifdef __STL_USE_STD_ALLOCATORS __stl_assert(__left->get_allocator() == __right->get_allocator()); # endif if (__depth > 20 && (__result->_M_size < 1000 || __depth > _RopeRep::_S_max_rope_depth)) { _RopeRep* __balanced; __STL_TRY { __balanced = _S_balance(__result); # ifndef __GC if (__result != __balanced) { __stl_assert(1 == __result->_M_ref_count && 1 == __balanced->_M_ref_count); } # endif __result->_M_unref_nonnil(); } __STL_UNWIND((_C_deallocate(__result,1))); // 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 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 (_RopeRep::_S_leaf == __r->_M_tag && __r->_M_size + __slen <= _S_copy_max) { __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); # ifndef __GC __stl_assert(1 == __result->_M_ref_count); # endif return __result; } if (_RopeRep::_S_concat == __r->_M_tag && _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) { _RopeLeaf* __right = (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); if (__right->_M_size + __slen <= _S_copy_max) { _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; _RopeRep* __nright = _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); __left->_M_ref_nonnil(); __STL_TRY { __result = _S_tree_concat(__left, __nright); } __STL_UNWIND(_S_unref(__left); _S_unref(__nright)); # ifndef __GC __stl_assert(1 == __result->_M_ref_count); # endif return __result; } } _RopeRep* __nright = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); __STL_TRY { __r->_M_ref_nonnil(); __result = _S_tree_concat(__r, __nright); } __STL_UNWIND(_S_unref(__r); _S_unref(__nright)); # ifndef __GC __stl_assert(1 == __result->_M_ref_count); # endif return __result; } #ifndef __GC template 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; __stl_assert(__count >= 1); 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 <= _S_copy_max && _RopeRep::_S_leaf == __r->_M_tag) { __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); return __result; } if (_RopeRep::_S_concat == __r->_M_tag) { _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)__r)->_M_right); if (_RopeRep::_S_leaf == __right->_M_tag && __right->_M_size + __slen <= _S_copy_max) { _RopeRep* __new_right = _S_destr_leaf_concat_char_iter(__right, __s, __slen); if (__right == __new_right) { __stl_assert(__new_right->_M_ref_count == 2); __new_right->_M_ref_count = 1; } else { __stl_assert(__new_right->_M_ref_count >= 1); __right->_M_unref_nonnil(); } __stl_assert(__r->_M_ref_count == 1); __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(); __STL_TRY { __result = _S_tree_concat(__r, __right); } __STL_UNWIND(_S_unref(__r); _S_unref(__right)) __stl_assert(1 == __result->_M_ref_count); return __result; } #endif /* !__GC */ template 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 (_RopeRep::_S_leaf == __right->_M_tag) { if (_RopeRep::_S_leaf == __left->_M_tag) { if (__right->_M_size + __left->_M_size <= _S_copy_max) { return _S_leaf_concat_char_iter((_RopeLeaf*)__left, ((_RopeLeaf*)__right)->_M_data, __right->_M_size); } } else if (_RopeRep::_S_concat == __left->_M_tag && _RopeRep::_S_leaf == ((_RopeConcatenation*)__left)->_M_right->_M_tag) { _RopeLeaf* __leftright = (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); if (__leftright->_M_size + __right->_M_size <= _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(); __STL_TRY { return(_S_tree_concat(__leftleft, __rest)); } __STL_UNWIND(_S_unref(__leftleft); _S_unref(__rest)) } } } __left->_M_ref_nonnil(); __right->_M_ref_nonnil(); __STL_TRY { return(_S_tree_concat(__left, __right)); } __STL_UNWIND(_S_unref(__left); _S_unref(__right)); } template 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 _RopeRep::_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); # ifndef __GC __stl_assert(1 == __result->_M_ref_count); # endif return __result; } case _RopeRep::_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 _RopeRep::_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 _RopeRep::_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)); __STL_TRY { (*(__f->_M_fn))(__start, __result_len, __section); } __STL_UNWIND(_RopeRep::__STL_FREE_STRING( __section, __result_len, __base->get_allocator())); _S_cond_store_eos(__section[__result_len]); return _S_new_RopeLeaf(__section, __result_len, __base->get_allocator()); } } /*NOTREACHED*/ __stl_assert(false); lazy: { // Create substring node. return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start, __base->get_allocator()); } } template 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 _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; } }; #ifdef __STL_USE_NEW_IOSTREAMS template // Here _CharT is both the stream and rope character type. #else template // Here _CharT is the rope character type. Unlike in the // above case, we somewhat handle the case in which it doesn't // match the stream character type, i.e. char. #endif class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { private: # ifdef __STL_USE_NEW_IOSTREAMS typedef basic_ostream<_CharT,_Traits> _Insert_ostream; # else typedef ostream _Insert_ostream; # endif _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. }; #ifdef __STL_USE_NEW_IOSTREAMS template 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; } #else template bool _Rope_insert_char_consumer<_CharT>::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 << __leaf[__i]; return true; } __STL_TEMPLATE_NULL inline bool _Rope_insert_char_consumer::operator() (const char* __leaf, size_t __n) { size_t __i; for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); return true; } #endif template 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 _RopeRep::_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 = 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 = max(__left_len, __begin); if (!_S_apply_to_pieces(__c, __right, __right_start - __left_len, __end - __left_len)) { return false; } } } return true; case _RopeRep::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; return __c(__l->_M_data + __begin, __end - __begin); } case _RopeRep::_S_function: case _RopeRep::_S_substringfn: { _RopeFunction* __f = (_RopeFunction*)__r; size_t __len = __end - __begin; bool __result; _CharT* __buffer = (_CharT*)alloc::allocate(__len * sizeof(_CharT)); __STL_TRY { (*(__f->_M_fn))(__begin, __len, __buffer); __result = __c(__buffer, __len); alloc::deallocate(__buffer, __len * sizeof(_CharT)); } __STL_UNWIND((alloc::deallocate(__buffer, __len * sizeof(_CharT)))) return __result; } default: __stl_assert(false); /*NOTREACHED*/ return false; } } #ifdef __STL_USE_NEW_IOSTREAMS template inline void _Rope_fill(basic_ostream<_CharT, _Traits>& __o, size_t __n) #else inline void _Rope_fill(ostream& __o, size_t __n) #endif { char __f = __o.fill(); size_t __i; for (__i = 0; __i < __n; __i++) __o.put(__f); } template 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; } #ifdef __STL_USE_NEW_IOSTREAMS template basic_ostream<_CharT, _Traits>& operator<< (basic_ostream<_CharT, _Traits>& __o, const rope<_CharT, _Alloc>& __r) #else template ostream& operator<< (ostream& __o, const rope<_CharT, _Alloc>& __r) #endif { size_t __w = __o.width(); bool __left = bool(__o.flags() & ios::left); size_t __pad_len; size_t __rope_len = __r.size(); # ifdef __STL_USE_NEW_IOSTREAMS _Rope_insert_char_consumer<_CharT, _Traits> __c(__o); # else _Rope_insert_char_consumer<_CharT> __c(__o); # endif 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); __STL_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); } __STL_UNWIND(if (!__is_simple) __o.width(__w)) return __o; } template _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 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, _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 _CharT* rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) { if (0 == __r) return __buffer; switch(__r->_M_tag) { case _RopeRep::_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 _RopeRep::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; return copy_n(__l->_M_data, __l->_M_size, __buffer).second; } case _RopeRep::_S_function: case _RopeRep::_S_substringfn: // We dont 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: __stl_assert(false); /*NOTREACHED*/ return 0; } } // This needs work for _CharT != char template 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 (_RopeRep::_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 _RopeRep::_S_leaf: __kind = "Leaf"; break; case _RopeRep::_S_function: __kind = "Function"; break; case _RopeRep::_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 const unsigned long rope<_CharT,_Alloc>::_S_min_len[ _Rope_RopeRep<_CharT,_Alloc>::_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 rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) { _RopeRep* __forest[_RopeRep::_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 <= _RopeRep::_S_max_rope_depth; ++__i) __forest[__i] = 0; __STL_TRY { _S_add_to_forest(__r, __forest); for (__i = 0; __i <= _RopeRep::_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(__STL_USE_EXCEPTIONS) __forest[__i] = 0; # endif } } __STL_UNWIND(for(__i = 0; __i <= _RopeRep::_S_max_rope_depth; __i++) _S_unref(__forest[__i])) if (__result->_M_depth > _RopeRep::_S_max_rope_depth) { # ifdef __STL_USE_EXCEPTIONS __STL_THROW(length_error("rope too long")); # else abort(); # endif } return(__result); } template 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; } __stl_assert(__r->_M_tag == _RopeRep::_S_concat); { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _S_add_to_forest(__c->_M_left, __forest); _S_add_to_forest(__c->_M_right, __forest); } } template 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. __stl_assert(_S_is_almost_balanced(__insertee)); __stl_assert(__insertee->_M_depth <= __r->_M_depth + 1); 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; __stl_assert(_S_is_almost_balanced(__insertee)); } __stl_assert(_S_min_len[__i] <= __insertee->_M_size); __stl_assert(__forest[__i] == 0); if (__i == _RopeRep::_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 _CharT rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i) { __GC_CONST _CharT* __cstr = __r->_M_c_string; __stl_assert(__i < __r->_M_size); if (0 != __cstr) return __cstr[__i]; for(;;) { switch(__r->_M_tag) { case _RopeRep::_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 _RopeRep::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; return __l->_M_data[__i]; } case _RopeRep::_S_function: case _RopeRep::_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 _CharT* rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) { _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth]; size_t __csptr = 0; for(;;) { if (__r->_M_ref_count > 1) return 0; switch(__r->_M_tag) { case _RopeRep::_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 _RopeRep::_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 _RopeRep::_S_function: case _RopeRep::_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 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 (_RopeRep::_S_leaf == __left->_M_tag) { _RopeLeaf* __l = (_RopeLeaf*) __left; if (_RopeRep::_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 (_RopeRep::_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 _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)); # ifndef __GC __stl_assert(__left == __result_left || 1 == __result_left->_M_ref_count); # endif _RopeRep* __result = _My_rope::_S_concat(__result_left, __right); # ifndef __GC __stl_assert(1 <= __result->_M_ref_count); _RopeRep::_S_unref(__old); # endif _M_root->_M_tree_ptr = __result; return *this; } template 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 _Rope_char_ptr_proxy<_CharT, _Alloc> _Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const { return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); } template 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 = _Data_allocate(_S_rounded_up_size(__rest)); uninitialized_fill_n(__rest_buffer, __rest, __c); _S_cond_store_eos(__rest_buffer[__rest]); __STL_TRY { __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); } __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a)) } __remainder_rope._M_tree_ptr = __remainder; if (__exponent != 0) { _CharT* __base_buffer = _Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); _RopeLeaf* __base_leaf; rope __base_rope; uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c); _S_cond_store_eos(__base_buffer[__exponentiate_threshold]); __STL_TRY { __base_leaf = _S_new_RopeLeaf(__base_buffer, __exponentiate_threshold, __a); } __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__base_buffer, __exponentiate_threshold, __a)) __base_rope._M_tree_ptr = __base_leaf; if (1 == __exponent) { __result = __base_rope; # ifndef __GC __stl_assert(2 == __result._M_tree_ptr->_M_ref_count); // One each for base_rope and __result # endif } else { __result = power(__base_rope, __exponent, _Rope_Concat_fn<_CharT,_Alloc>()); } if (0 != __remainder) { __result += __remainder_rope; } } else { __result = __remainder_rope; } _M_tree_ptr = __result._M_tree_ptr; _M_tree_ptr->_M_ref_nonnil(); } template _CharT rope<_CharT,_Alloc>::_S_empty_c_str[1]; template const _CharT* rope<_CharT,_Alloc>::c_str() const { if (0 == _M_tree_ptr) { _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, // but probably fast. return _S_empty_c_str; } __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; if (0 != __old_c_string) return(__old_c_string); size_t __s = size(); _CharT* __result = _Data_allocate(__s + 1); _S_flatten(_M_tree_ptr, __result); __result[__s] = _S_eos((_CharT*)0); # ifdef __GC _M_tree_ptr->_M_c_string = __result; # else if ((__old_c_string = (__GC_CONST _CharT*) _Atomic_swap((unsigned long *)(&(_M_tree_ptr->_M_c_string)), (unsigned long)__result)) != 0) { // It must have been added in the interim. Hence it had to have been // separately allocated. Deallocate the old copy, since we just // replaced it. destroy(__old_c_string, __old_c_string + __s + 1); _Data_deallocate(__old_c_string, __s + 1); } # endif return(__result); } template const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() { if (0 == _M_tree_ptr) { _S_empty_c_str[0] = _S_eos((_CharT*)0); return _S_empty_c_str; } __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && 0 != __old_c_string) { return(__old_c_string); } size_t __s = size(); _CharT* __result = _Data_allocate(_S_rounded_up_size(__s)); _S_flatten(_M_tree_ptr, __result); __result[__s] = _S_eos((_CharT*)0); _M_tree_ptr->_M_unref_nonnil(); _M_tree_ptr = _S_new_RopeLeaf(__result, __s, get_allocator()); return(__result); } // Algorithm specializations. More should be added. template // 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; __stl_assert(__first.container() == __middle.container() && __middle.container() == __last.container()); 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 __first, _Rope_iterator __middle, _Rope_iterator __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 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 __first, _Rope_iterator __middle, _Rope_iterator __last) { _Rope_rotate(__first, __middle, __last); } # endif #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/sequence_concepts.h ================================================ /* * Copyright (c) 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. */ #ifndef STL_SEQUENCE_CONCEPTS_H #define STL_SEQUENCE_CONCEPTS_H #include #ifdef __STL_USE_CONCEPT_CHECKS // This file covers the following concepts: // _Sequence // _FrontInsertionSequence // _BackInsertionSequence struct _ERROR_IN_STL_SEQ { template static void __fill_constructor_requirement_violation(_XX& __s) { typename _XX::value_type __t = typename _XX::value_type(); typename _XX::difference_type __n = typename _XX::difference_type(); _XX __x(__n, __t); __sink_unused_warning(__x); } template static void __fill_default_constructor_requirement_violation(_XX& __s) { _STL_ERROR::__default_constructor_requirement_violation(*__s.begin()); typename _XX::difference_type __n = typename _XX::difference_type(); _XX __x(__n); __sink_unused_warning(__x); } template static void __range_constructor_requirement_violation(_XX& __s) { _XX __x(__s.begin(), __s.end()); __sink_unused_warning(__x); } template static void __insert_function_requirement_violation(_XX& __s) { typename _XX::value_type __t = typename _XX::value_type(); typename _XX::iterator __p = typename _XX::iterator(); __p = __s.insert(__p, __t); } template static void __fill_insert_function_requirement_violation(_XX& __s) { typename _XX::value_type __t = typename _XX::value_type(); typename _XX::iterator __p = typename _XX::iterator(); typename _XX::difference_type __n = typename _XX::difference_type(); __s.insert(__p, __n, __t); } template static void __range_insert_function_requirement_violation(_XX& __s) { typename _XX::iterator __p = typename _XX::iterator(); typename _XX::iterator __i = typename _XX::iterator(); typename _XX::iterator __j = typename _XX::iterator(); __s.insert(__p, __i, __j); } template static void __insert_element_function_requirement_violation(_XX& __s) { typename _XX::value_type __t = typename _XX::value_type(); std::pair __r; __r = __s.insert(__t); __sink_unused_warning(__r); } template static void __unconditional_insert_element_function_requirement_violation(_XX& __s) { typename _XX::value_type __t = typename _XX::value_type(); typename _XX::iterator __p; __p = __s.insert(__t); __sink_unused_warning(__p); } template static void __erase_function_requirement_violation(_XX& __s) { typename _XX::iterator __p = typename _XX::iterator(); __p = __s.erase(__p); } template static void __range_erase_function_requirement_violation(_XX& __s) { typename _XX::iterator __p = typename _XX::iterator(); typename _XX::iterator __q = typename _XX::iterator(); __p = __s.erase(__p, __q); } template static void __const_front_function_requirement_violation(const _XX& __s) { typename _XX::const_reference __t = __s.front(); __sink_unused_warning(__t); } template static void __front_function_requirement_violation(_XX& __s) { typename _XX::reference __t = __s.front(); __const_front_function_requirement_violation(__s); __sink_unused_warning(__t); } template static void __const_back_function_requirement_violation(const _XX& __s) { typename _XX::const_reference __t = __s.back(); __sink_unused_warning(__t); } template static void __back_function_requirement_violation(_XX& __s) { typename _XX::reference __t = __s.back(); __const_back_function_requirement_violation(__s); __sink_unused_warning(__t); } template static void __push_front_function_requirement_violation(_XX& __s) { typename _XX::value_type __t = typename _XX::value_type(); __s.push_front(__t); } template static void __pop_front_function_requirement_violation(_XX& __s) { __s.pop_front(); } template static void __push_back_function_requirement_violation(_XX& __s) { typename _XX::value_type __t = typename _XX::value_type(); __s.push_back(__t); } template static void __pop_back_function_requirement_violation(_XX& __s) { __s.pop_back(); } }; /* Sequence Containers */ template struct _Sequence_concept_specification { static void _Sequence_requirement_violation(_Sequence __s) { // Refinement of ForwardContainer _ForwardContainer_concept_specification<_Sequence>::_ForwardContainer_requirement_violation(__s); // Refinement of DefaultConstructible _DefaultConstructible_concept_specification<_Sequence>::_DefaultConstructible_requirement_violation(__s); // Valid Expressions _ERROR_IN_STL_SEQ::__fill_constructor_requirement_violation(__s); _ERROR_IN_STL_SEQ::__fill_default_constructor_requirement_violation(__s); _ERROR_IN_STL_SEQ::__range_constructor_requirement_violation(__s); _ERROR_IN_STL_SEQ::__insert_function_requirement_violation(__s); _ERROR_IN_STL_SEQ::__fill_insert_function_requirement_violation(__s); _ERROR_IN_STL_SEQ::__range_insert_function_requirement_violation(__s); _ERROR_IN_STL_SEQ::__erase_function_requirement_violation(__s); _ERROR_IN_STL_SEQ::__range_erase_function_requirement_violation(__s); _ERROR_IN_STL_SEQ::__front_function_requirement_violation(__s); } }; template struct _FrontInsertionSequence_concept_specification { static void _FrontInsertionSequence_requirement_violation(_FrontInsertionSequence __s) { // Refinement of Sequence _Sequence_concept_specification<_FrontInsertionSequence>::_Sequence_requirement_violation(__s); // Valid Expressions _ERROR_IN_STL_SEQ::__push_front_function_requirement_violation(__s); _ERROR_IN_STL_SEQ::__pop_front_function_requirement_violation(__s); } }; template struct _BackInsertionSequence_concept_specification { static void _BackInsertionSequence_requirement_violation(_BackInsertionSequence __s) { // Refinement of Sequence _Sequence_concept_specification<_BackInsertionSequence>::_Sequence_requirement_violation(__s); // Valid Expressions _ERROR_IN_STL_SEQ::__back_function_requirement_violation(__s); _ERROR_IN_STL_SEQ::__push_back_function_requirement_violation(__s); _ERROR_IN_STL_SEQ::__pop_back_function_requirement_violation(__s); } }; #endif /* if __STL_USE_CONCEPT_CHECKS */ #endif /* STL_SEQUENCE_CONCEPTS_H */ ================================================ FILE: stl-3.3-source/set ================================================ /* * * 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 __SGI_STL_SET #define __SGI_STL_SET #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #endif /* __SGI_STL_SET */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/set.h ================================================ /* * * 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 __SGI_STL_SET_H #define __SGI_STL_SET_H #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::rb_tree; using __STD::set; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_SET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/slist ================================================ /* * 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 __SGI_STL_SLIST #define __SGI_STL_SLIST #include #include #include #include #include #endif /* __SGI_STL_SLIST */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/slist.h ================================================ /* * 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 __SGI_STL_SLIST_H #define __SGI_STL_SLIST_H #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::slist; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_SLIST_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stack ================================================ /* * * 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 __SGI_STL_STACK #define __SGI_STL_STACK #include #include #include #include #include #include #endif /* __SGI_STL_STACK */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stack.h ================================================ /* * * 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 __SGI_STL_STACK_H #define __SGI_STL_STACK_H #include #include #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::stack; using __STD::queue; using __STD::priority_queue; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_STACK_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stdexcept ================================================ /* * 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 __SGI_STDEXCEPT #define __SGI_STDEXCEPT #include #if defined(__STL_USE_EXCEPTIONS) || \ !(defined(_MIPS_SIM) && defined(_ABIO32) && _MIPS_SIM == _ABIO32) #include __STL_BEGIN_NAMESPACE class __Named_exception : public __STL_EXCEPTION_BASE { public: __Named_exception(const string& __str) { strncpy(_M_name, __get_c_string(__str), _S_bufsize); _M_name[_S_bufsize - 1] = '\0'; } virtual const char* what() const __STL_NOTHROW { return _M_name; } private: enum { _S_bufsize = 256 }; char _M_name[_S_bufsize]; }; class logic_error : public __Named_exception { public: logic_error(const string& __s) : __Named_exception(__s) {} }; class runtime_error : public __Named_exception { public: runtime_error(const string& __s) : __Named_exception(__s) {} }; class domain_error : public logic_error { public: domain_error(const string& __arg) : logic_error(__arg) {} }; class invalid_argument : public logic_error { public: invalid_argument(const string& __arg) : logic_error(__arg) {} }; class length_error : public logic_error { public: length_error(const string& __arg) : logic_error(__arg) {} }; class out_of_range : public logic_error { public: out_of_range(const string& __arg) : logic_error(__arg) {} }; class range_error : public runtime_error { public: range_error(const string& __arg) : runtime_error(__arg) {} }; class overflow_error : public runtime_error { public: overflow_error(const string& __arg) : runtime_error(__arg) {} }; class underflow_error : public runtime_error { public: underflow_error(const string& __arg) : runtime_error(__arg) {} }; __STL_END_NAMESPACE #ifndef __SGI_STL_STRING #include #endif #endif /* Not o32, and no exceptions */ #endif /* __SGI_STDEXCEPT */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl-3.3.SearchResults ================================================ ---- pop_heap Matches (18 in 5 files) ---- Algo.h:using __STD::pop_heap; Heap.h:using __STD::pop_heap; Stl_algo.h: __pop_heap(__first, __middle, __i, _Tp(*__i), Stl_algo.h: __pop_heap(__first, __middle, __i, _Tp(*__i), __comp, Stl_heap.h:// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. Stl_heap.h:__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, Stl_heap.h:__pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, Stl_heap.h: __pop_heap(__first, __last - 1, __last - 1, Stl_heap.h:inline void pop_heap(_RandomAccessIterator __first, Stl_heap.h: __pop_heap_aux(__first, __last, __VALUE_TYPE(__first)); Stl_heap.h:__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, Stl_heap.h:__pop_heap_aux(_RandomAccessIterator __first, Stl_heap.h: __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp, Stl_heap.h:pop_heap(_RandomAccessIterator __first, Stl_heap.h: __pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp); Stl_heap.h: pop_heap(__first, __last--); Stl_heap.h: pop_heap(__first, __last--, __comp); Stl_queue.h: pop_heap(c.begin(), c.end(), comp); ================================================ FILE: stl-3.3-source/stl_algo.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ALGO_H #define __SGI_STL_INTERNAL_ALGO_H #include // See concept_checks.h for the concept-checking macros // __STL_REQUIRES, __STL_CONVERTIBLE, etc. __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1209 #endif // __median (an extension, not present in the C++ standard). template inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { __STL_REQUIRES(_Tp, _LessThanComparable); 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; } template inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { __STL_BINARY_FUNCTION_CHECK(_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; } // for_each. Apply a function to every element of a range. template _Function for_each(_InputIter __first, _InputIter __last, _Function __f) { __STL_REQUIRES(_InputIter, _InputIterator); for ( ; __first != __last; ++__first) __f(*__first); return __f; } // find and find_if. template inline _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val, input_iterator_tag) { while (__first != __last && !(*__first == __val)) ++__first; return __first; } template inline _InputIter find_if(_InputIter __first, _InputIter __last, _Predicate __pred, input_iterator_tag) { while (__first != __last && !__pred(*__first)) ++__first; return __first; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template _RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last, const _Tp& __val, random_access_iterator_tag) { typename iterator_traits<_RandomAccessIter>::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; } } template _RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last, _Predicate __pred, random_access_iterator_tag) { typename iterator_traits<_RandomAccessIter>::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; } } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, _Tp); return find(__first, __last, __val, __ITERATOR_CATEGORY(__first)); } template inline _InputIter find_if(_InputIter __first, _InputIter __last, _Predicate __pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); } // adjacent_find. template _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _EqualityComparable); if (__first == __last) return __last; _ForwardIter __next = __first; while(++__next != __last) { if (*__first == *__next) return __first; __first = __next; } return __last; } template _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __last; _ForwardIter __next = __first; while(++__next != __last) { if (__binary_pred(*__first, *__next)) return __first; __first = __next; } return __last; } // count and count_if. There are two version of each, one whose return type // type is void and one (present only if we have partial specialization) // whose return type is iterator_traits<_InputIter>::difference_type. The // C++ standard only has the latter version, but the former, which was present // in the HP STL, is retained for backward compatibility. template void count(_InputIter __first, _InputIter __last, const _Tp& __value, _Size& __n) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _EqualityComparable); __STL_REQUIRES(_Tp, _EqualityComparable); for ( ; __first != __last; ++__first) if (*__first == __value) ++__n; } template void count_if(_InputIter __first, _InputIter __last, _Predicate __pred, _Size& __n) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); for ( ; __first != __last; ++__first) if (__pred(*__first)) ++__n; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template typename iterator_traits<_InputIter>::difference_type count(_InputIter __first, _InputIter __last, const _Tp& __value) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _EqualityComparable); __STL_REQUIRES(_Tp, _EqualityComparable); typename iterator_traits<_InputIter>::difference_type __n = 0; for ( ; __first != __last; ++__first) if (*__first == __value) ++__n; return __n; } template typename iterator_traits<_InputIter>::difference_type count_if(_InputIter __first, _InputIter __last, _Predicate __pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); typename iterator_traits<_InputIter>::difference_type __n = 0; for ( ; __first != __last; ++__first) if (__pred(*__first)) ++__n; return __n; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // search. template _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. _ForwardIter2 __tmp(__first2); ++__tmp; if (__tmp == __last2) return find(__first1, __last1, *__first2); // General case. _ForwardIter2 __p1, __p; __p1 = __first2; ++__p1; _ForwardIter1 __current = __first1; while (__first1 != __last1) { __first1 = 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; } template _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, _BinaryPred __predicate) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. _ForwardIter2 __tmp(__first2); ++__tmp; if (__tmp == __last2) { while (__first1 != __last1 && !__predicate(*__first1, *__first2)) ++__first1; return __first1; } // General case. _ForwardIter2 __p1, __p; __p1 = __first2; ++__p1; _ForwardIter1 __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; } // search_n. Search for __count consecutive copies of __val. template _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, _Integer __count, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _EqualityComparable); __STL_REQUIRES(_Tp, _EqualityComparable); if (__count <= 0) return __first; else { __first = find(__first, __last, __val); while (__first != __last) { _Integer __n = __count - 1; _ForwardIter __i = __first; ++__i; while (__i != __last && __n != 0 && *__i == __val) { ++__i; --__n; } if (__n == 0) return __first; else __first = find(__i, __last, __val); } return __last; } } template _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, _Integer __count, const _Tp& __val, _BinaryPred __binary_pred) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool, typename iterator_traits<_ForwardIter>::value_type, _Tp); if (__count <= 0) return __first; else { while (__first != __last) { if (__binary_pred(*__first, __val)) break; ++__first; } while (__first != __last) { _Integer __n = __count - 1; _ForwardIter __i = __first; ++__i; while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) { ++__i; --__n; } if (__n == 0) return __first; else { while (__i != __last) { if (__binary_pred(*__i, __val)) break; ++__i; } __first = __i; } } return __last; } } // swap_ranges template _ForwardIter2 swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2) { __STL_REQUIRES(_ForwardIter1, _Mutable_ForwardIterator); __STL_REQUIRES(_ForwardIter2, _Mutable_ForwardIterator); __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter2>::value_type, typename iterator_traits<_ForwardIter1>::value_type); for ( ; __first1 != __last1; ++__first1, ++__first2) iter_swap(__first1, __first2); return __first2; } // transform template _OutputIter transform(_InputIter __first, _InputIter __last, _OutputIter __result, _UnaryOperation __opr) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); for ( ; __first != __last; ++__first, ++__result) *__result = __opr(*__first); return __result; } template _OutputIter transform(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _OutputIter __result, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) *__result = __binary_op(*__first1, *__first2); return __result; } // replace, replace_if, replace_copy, replace_copy_if template void replace(_ForwardIter __first, _ForwardIter __last, const _Tp& __old_value, const _Tp& __new_value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter>::value_type, _Tp); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first != __last; ++__first) if (*__first == __old_value) *__first = __new_value; } template void replace_if(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, const _Tp& __new_value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first != __last; ++__first) if (__pred(*__first)) *__first = __new_value; } template _OutputIter replace_copy(_InputIter __first, _InputIter __last, _OutputIter __result, const _Tp& __old_value, const _Tp& __new_value) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, _Tp); for ( ; __first != __last; ++__first, ++__result) *__result = *__first == __old_value ? __new_value : *__first; return __result; } template _OutputIter replace_copy_if(_InputIter __first, _InputIter __last, _OutputIter __result, _Predicate __pred, const _Tp& __new_value) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); for ( ; __first != __last; ++__first, ++__result) *__result = __pred(*__first) ? __new_value : *__first; return __result; } // generate and generate_n template void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_GENERATOR_CHECK(_Generator, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first != __last; ++__first) *__first = __gen(); } template _OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) { __STL_REQUIRES(_OutputIter, _OutputIterator); for ( ; __n > 0; --__n, ++__first) *__first = __gen(); return __first; } // remove, remove_if, remove_copy, remove_copy_if template _OutputIter remove_copy(_InputIter __first, _InputIter __last, _OutputIter __result, const _Tp& __value) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, _Tp); for ( ; __first != __last; ++__first) if (!(*__first == __value)) { *__result = *__first; ++__result; } return __result; } template _OutputIter remove_copy_if(_InputIter __first, _InputIter __last, _OutputIter __result, _Predicate __pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_InputIter>::value_type); for ( ; __first != __last; ++__first) if (!__pred(*__first)) { *__result = *__first; ++__result; } return __result; } template _ForwardIter remove(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter>::value_type, _Tp); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __first = find(__first, __last, __value); _ForwardIter __i = __first; return __first == __last ? __first : remove_copy(++__i, __last, __first, __value); } template _ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); __first = find_if(__first, __last, __pred); _ForwardIter __i = __first; return __first == __last ? __first : remove_copy_if(++__i, __last, __first, __pred); } // unique and unique_copy template _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _Tp*) { _Tp __value = *__first; *__result = __value; while (++__first != __last) if (!(__value == *__first)) { __value = *__first; *++__result = __value; } return ++__result; } template inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, output_iterator_tag) { return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first)); } template _ForwardIter __unique_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, forward_iterator_tag) { *__result = *__first; while (++__first != __last) if (!(*__result == *__first)) *++__result = *__first; return ++__result; } template inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _EqualityComparable); if (__first == __last) return __result; return __unique_copy(__first, __last, __result, __ITERATOR_CATEGORY(__result)); } template _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _BinaryPredicate __binary_pred, _Tp*) { __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, _Tp, _Tp); _Tp __value = *__first; *__result = __value; while (++__first != __last) if (!__binary_pred(__value, *__first)) { __value = *__first; *++__result = __value; } return ++__result; } template inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _BinaryPredicate __binary_pred, output_iterator_tag) { return __unique_copy(__first, __last, __result, __binary_pred, __VALUE_TYPE(__first)); } template _ForwardIter __unique_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, _BinaryPredicate __binary_pred, forward_iterator_tag) { __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_InputIter>::value_type); *__result = *__first; while (++__first != __last) if (!__binary_pred(*__result, *__first)) *++__result = *__first; return ++__result; } template inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); if (__first == __last) return __result; return __unique_copy(__first, __last, __result, __binary_pred, __ITERATOR_CATEGORY(__result)); } template _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _EqualityComparable); __first = adjacent_find(__first, __last); return unique_copy(__first, __last, __first); } template _ForwardIter unique(_ForwardIter __first, _ForwardIter __last, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); __first = adjacent_find(__first, __last, __binary_pred); return unique_copy(__first, __last, __first, __binary_pred); } // reverse and reverse_copy, and their auxiliary functions template void __reverse(_BidirectionalIter __first, _BidirectionalIter __last, bidirectional_iterator_tag) { while (true) if (__first == __last || __first == --__last) return; else iter_swap(__first++, __last); } template void __reverse(_RandomAccessIter __first, _RandomAccessIter __last, random_access_iterator_tag) { while (__first < __last) iter_swap(__first++, --__last); } template inline void reverse(_BidirectionalIter __first, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); __reverse(__first, __last, __ITERATOR_CATEGORY(__first)); } template _OutputIter reverse_copy(_BidirectionalIter __first, _BidirectionalIter __last, _OutputIter __result) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); while (__first != __last) { --__last; *__result = *__last; ++__result; } return __result; } // rotate and rotate_copy, and their auxiliary functions template _EuclideanRingElement __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) { while (__n != 0) { _EuclideanRingElement __t = __m % __n; __m = __n; __n = __t; } return __m; } template _ForwardIter __rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last, _Distance*, forward_iterator_tag) { if (__first == __middle) return __last; if (__last == __middle) return __first; _ForwardIter __first2 = __middle; do { swap(*__first++, *__first2++); if (__first == __middle) __middle = __first2; } while (__first2 != __last); _ForwardIter __new_middle = __first; __first2 = __middle; while (__first2 != __last) { swap (*__first++, *__first2++); if (__first == __middle) __middle = __first2; else if (__first2 == __last) __first2 = __middle; } return __new_middle; } template _BidirectionalIter __rotate(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance*, bidirectional_iterator_tag) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); if (__first == __middle) return __last; if (__last == __middle) return __first; __reverse(__first, __middle, bidirectional_iterator_tag()); __reverse(__middle, __last, bidirectional_iterator_tag()); while (__first != __middle && __middle != __last) swap (*__first++, *--__last); if (__first == __middle) { __reverse(__middle, __last, bidirectional_iterator_tag()); return __last; } else { __reverse(__first, __middle, bidirectional_iterator_tag()); return __first; } } template _RandomAccessIter __rotate(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Distance *, _Tp *) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); _Distance __n = __last - __first; _Distance __k = __middle - __first; _Distance __l = __n - __k; _RandomAccessIter __result = __first + (__last - __middle); if (__k == 0) return __last; else if (__k == __l) { swap_ranges(__first, __middle, __middle); return __result; } _Distance __d = __gcd(__n, __k); for (_Distance __i = 0; __i < __d; __i++) { _Tp __tmp = *__first; _RandomAccessIter __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; } return __result; } template inline _ForwardIter rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); return __rotate(__first, __middle, __last, __DISTANCE_TYPE(__first), __ITERATOR_CATEGORY(__first)); } template _OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last, _OutputIter __result) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); return copy(__first, __middle, copy(__middle, __last, __result)); } // Return a random number in the range [0, __n). This function encapsulates // whether we're using rand (part of the standard C library) or lrand48 // (not standard, but a much better choice whenever it's available). template inline _Distance __random_number(_Distance __n) { #ifdef __STL_NO_DRAND48 return rand() % __n; #else return lrand48() % __n; #endif } // random_shuffle template inline void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) iter_swap(__i, __first + __random_number((__i - __first) + 1)); } template void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last, _RandomNumberGenerator& __rand) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) iter_swap(__i, __first + __rand((__i - __first) + 1)); } // random_sample and random_sample_n (extensions, not part of the standard). template _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, _OutputIter __out, const _Distance __n) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); _Distance __remaining = 0; distance(__first, __last, __remaining); _Distance __m = min(__n, __remaining); while (__m > 0) { if (__random_number(__remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } template _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, _OutputIter __out, const _Distance __n, _RandomNumberGenerator& __rand) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance); _Distance __remaining = 0; distance(__first, __last, __remaining); _Distance __m = min(__n, __remaining); while (__m > 0) { if (__rand(__remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } template _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __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 = __random_number(__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } template _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out, _RandomNumberGenerator& __rand, const _Distance __n) { __STL_UNARY_FUNCTION_CHECK(_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; } template inline _RandomAccessIter random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out_first, _RandomAccessIter __out_last) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); return __random_sample(__first, __last, __out_first, __out_last - __out_first); } template inline _RandomAccessIter random_sample(_InputIter __first, _InputIter __last, _RandomAccessIter __out_first, _RandomAccessIter __out_last, _RandomNumberGenerator& __rand) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); return __random_sample(__first, __last, __out_first, __rand, __out_last - __out_first); } // partition, stable_partition, and their auxiliary functions template _ForwardIter __partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, forward_iterator_tag) { if (__first == __last) return __first; while (__pred(*__first)) if (++__first == __last) return __first; _ForwardIter __next = __first; while (++__next != __last) if (__pred(*__next)) { swap(*__first, *__next); ++__first; } return __first; } template _BidirectionalIter __partition(_BidirectionalIter __first, _BidirectionalIter __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; iter_swap(__first, __last); ++__first; } } template inline _ForwardIter partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); } template _ForwardIter __inplace_stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, _Distance __len) { if (__len == 1) return __pred(*__first) ? __last : __first; _ForwardIter __middle = __first; advance(__middle, __len / 2); return rotate(__inplace_stable_partition(__first, __middle, __pred, __len / 2), __middle, __inplace_stable_partition(__middle, __last, __pred, __len - __len / 2)); } template _ForwardIter __stable_partition_adaptive(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, _Distance __len, _Pointer __buffer, _Distance __buffer_size) { if (__len <= __buffer_size) { _ForwardIter __result1 = __first; _Pointer __result2 = __buffer; for ( ; __first != __last ; ++__first) if (__pred(*__first)) { *__result1 = *__first; ++__result1; } else { *__result2 = *__first; ++__result2; } copy(__buffer, __result2, __result1); return __result1; } else { _ForwardIter __middle = __first; advance(__middle, __len / 2); return rotate(__stable_partition_adaptive( __first, __middle, __pred, __len / 2, __buffer, __buffer_size), __middle, __stable_partition_adaptive( __middle, __last, __pred, __len - __len / 2, __buffer, __buffer_size)); } } template inline _ForwardIter __stable_partition_aux(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, _Tp*, _Distance*) { _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last); if (__buf.size() > 0) return __stable_partition_adaptive(__first, __last, __pred, _Distance(__buf.requested_size()), __buf.begin(), __buf.size()); else return __inplace_stable_partition(__first, __last, __pred, _Distance(__buf.requested_size())); } template inline _ForwardIter stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __first; else return __stable_partition_aux(__first, __last, __pred, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } template _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last, _Tp __pivot) { while (true) { while (*__first < __pivot) ++__first; --__last; while (__pivot < *__last) --__last; if (!(__first < __last)) return __first; iter_swap(__first, __last); ++__first; } } template _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last, _Tp __pivot, _Compare __comp) { while (true) { while (__comp(*__first, __pivot)) ++__first; --__last; while (__comp(__pivot, *__last)) --__last; if (!(__first < __last)) return __first; iter_swap(__first, __last); ++__first; } } const int __stl_threshold = 16; // sort() and its auxiliary functions. template void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) { _RandomAccessIter __next = __last; --__next; while (__val < *__next) { *__last = *__next; __last = __next; --__next; } *__last = __val; } template void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, _Compare __comp) { _RandomAccessIter __next = __last; --__next; while (__comp(__val, *__next)) { *__last = *__next; __last = __next; --__next; } *__last = __val; } template inline void __linear_insert(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*) { _Tp __val = *__last; if (__val < *__first) { copy_backward(__first, __last, __last + 1); *__first = __val; } else __unguarded_linear_insert(__last, __val); } template inline void __linear_insert(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Compare __comp) { _Tp __val = *__last; if (__comp(__val, *__first)) { copy_backward(__first, __last, __last + 1); *__first = __val; } else __unguarded_linear_insert(__last, __val, __comp); } template void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) __linear_insert(__first, __i, __VALUE_TYPE(__first)); } template void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__first == __last) return; for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp); } template void __unguarded_insertion_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*) { for (_RandomAccessIter __i = __first; __i != __last; ++__i) __unguarded_linear_insert(__i, _Tp(*__i)); } template inline void __unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first)); } template void __unguarded_insertion_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Compare __comp) { for (_RandomAccessIter __i = __first; __i != __last; ++__i) __unguarded_linear_insert(__i, _Tp(*__i), __comp); } template inline void __unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first), __comp); } template void __final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { if (__last - __first > __stl_threshold) { __insertion_sort(__first, __first + __stl_threshold); __unguarded_insertion_sort(__first + __stl_threshold, __last); } else __insertion_sort(__first, __last); } template void __final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__last - __first > __stl_threshold) { __insertion_sort(__first, __first + __stl_threshold, __comp); __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp); } else __insertion_sort(__first, __last, __comp); } template inline _Size __lg(_Size __n) { _Size __k; for (__k = 0; __n != 1; __n >>= 1) ++__k; return __k; } template void __introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Size __depth_limit) { while (__last - __first > __stl_threshold) { if (__depth_limit == 0) { partial_sort(__first, __last, __last); return; } --__depth_limit; _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1)))); __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit); __last = __cut; } } template void __introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Size __depth_limit, _Compare __comp) { while (__last - __first > __stl_threshold) { if (__depth_limit == 0) { partial_sort(__first, __last, __last, __comp); return; } --__depth_limit; _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1), __comp)), __comp); __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp); __last = __cut; } } template inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); if (__first != __last) { __introsort_loop(__first, __last, __VALUE_TYPE(__first), __lg(__last - __first) * 2); __final_insertion_sort(__first, __last); } } template inline void sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); if (__first != __last) { __introsort_loop(__first, __last, __VALUE_TYPE(__first), __lg(__last - __first) * 2, __comp); __final_insertion_sort(__first, __last, __comp); } } // stable_sort() and its auxiliary functions. template void __inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last) { if (__last - __first < 15) { __insertion_sort(__first, __last); return; } _RandomAccessIter __middle = __first + (__last - __first) / 2; __inplace_stable_sort(__first, __middle); __inplace_stable_sort(__middle, __last); __merge_without_buffer(__first, __middle, __last, __middle - __first, __last - __middle); } template void __inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__last - __first < 15) { __insertion_sort(__first, __last, __comp); return; } _RandomAccessIter __middle = __first + (__last - __first) / 2; __inplace_stable_sort(__first, __middle, __comp); __inplace_stable_sort(__middle, __last, __comp); __merge_without_buffer(__first, __middle, __last, __middle - __first, __last - __middle, __comp); } template void __merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last, _RandomAccessIter2 __result, _Distance __step_size) { _Distance __two_step = 2 * __step_size; while (__last - __first >= __two_step) { __result = merge(__first, __first + __step_size, __first + __step_size, __first + __two_step, __result); __first += __two_step; } __step_size = min(_Distance(__last - __first), __step_size); merge(__first, __first + __step_size, __first + __step_size, __last, __result); } template void __merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last, _RandomAccessIter2 __result, _Distance __step_size, _Compare __comp) { _Distance __two_step = 2 * __step_size; while (__last - __first >= __two_step) { __result = merge(__first, __first + __step_size, __first + __step_size, __first + __two_step, __result, __comp); __first += __two_step; } __step_size = min(_Distance(__last - __first), __step_size); merge(__first, __first + __step_size, __first + __step_size, __last, __result, __comp); } const int __stl_chunk_size = 7; template void __chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Distance __chunk_size) { while (__last - __first >= __chunk_size) { __insertion_sort(__first, __first + __chunk_size); __first += __chunk_size; } __insertion_sort(__first, __last); } template void __chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Distance __chunk_size, _Compare __comp) { while (__last - __first >= __chunk_size) { __insertion_sort(__first, __first + __chunk_size, __comp); __first += __chunk_size; } __insertion_sort(__first, __last, __comp); } template void __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance*) { _Distance __len = __last - __first; _Pointer __buffer_last = __buffer + __len; _Distance __step_size = __stl_chunk_size; __chunk_insertion_sort(__first, __last, __step_size); while (__step_size < __len) { __merge_sort_loop(__first, __last, __buffer, __step_size); __step_size *= 2; __merge_sort_loop(__buffer, __buffer_last, __first, __step_size); __step_size *= 2; } } template void __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance*, _Compare __comp) { _Distance __len = __last - __first; _Pointer __buffer_last = __buffer + __len; _Distance __step_size = __stl_chunk_size; __chunk_insertion_sort(__first, __last, __step_size, __comp); while (__step_size < __len) { __merge_sort_loop(__first, __last, __buffer, __step_size, __comp); __step_size *= 2; __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp); __step_size *= 2; } } template void __stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance __buffer_size) { _Distance __len = (__last - __first + 1) / 2; _RandomAccessIter __middle = __first + __len; if (__len > __buffer_size) { __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size); __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size); } else { __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0); __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0); } __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), _Distance(__last - __middle), __buffer, __buffer_size); } template void __stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last, _Pointer __buffer, _Distance __buffer_size, _Compare __comp) { _Distance __len = (__last - __first + 1) / 2; _RandomAccessIter __middle = __first + __len; if (__len > __buffer_size) { __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, __comp); __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, __comp); } else { __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0, __comp); __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0, __comp); } __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), _Distance(__last - __middle), __buffer, __buffer_size, __comp); } template inline void __stable_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Distance*) { _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); if (buf.begin() == 0) __inplace_stable_sort(__first, __last); else __stable_sort_adaptive(__first, __last, buf.begin(), _Distance(buf.size())); } template inline void __stable_sort_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Tp*, _Distance*, _Compare __comp) { _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); if (buf.begin() == 0) __inplace_stable_sort(__first, __last, __comp); else __stable_sort_adaptive(__first, __last, buf.begin(), _Distance(buf.size()), __comp); } template inline void stable_sort(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __stable_sort_aux(__first, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } template inline void stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __stable_sort_aux(__first, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), __comp); } // partial_sort, partial_sort_copy, and auxiliary functions. template void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Tp*) { make_heap(__first, __middle); for (_RandomAccessIter __i = __middle; __i < __last; ++__i) if (*__i < *__first) __pop_heap(__first, __middle, __i, _Tp(*__i), __DISTANCE_TYPE(__first)); sort_heap(__first, __middle); } template inline void partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first)); } template void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Tp*, _Compare __comp) { make_heap(__first, __middle, __comp); for (_RandomAccessIter __i = __middle; __i < __last; ++__i) if (__comp(*__i, *__first)) __pop_heap(__first, __middle, __i, _Tp(*__i), __comp, __DISTANCE_TYPE(__first)); sort_heap(__first, __middle, __comp); } template inline void partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp); } template _RandomAccessIter __partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last, _Distance*, _Tp*) { if (__result_first == __result_last) return __result_last; _RandomAccessIter __result_real_last = __result_first; while(__first != __last && __result_real_last != __result_last) { *__result_real_last = *__first; ++__result_real_last; ++__first; } make_heap(__result_first, __result_real_last); while (__first != __last) { if (*__first < *__result_first) __adjust_heap(__result_first, _Distance(0), _Distance(__result_real_last - __result_first), _Tp(*__first)); ++__first; } sort_heap(__result_first, __result_real_last); return __result_real_last; } template inline _RandomAccessIter partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type, _LessThanComparable); return __partial_sort_copy(__first, __last, __result_first, __result_last, __DISTANCE_TYPE(__result_first), __VALUE_TYPE(__first)); } template _RandomAccessIter __partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last, _Compare __comp, _Distance*, _Tp*) { if (__result_first == __result_last) return __result_last; _RandomAccessIter __result_real_last = __result_first; while(__first != __last && __result_real_last != __result_last) { *__result_real_last = *__first; ++__result_real_last; ++__first; } make_heap(__result_first, __result_real_last, __comp); while (__first != __last) { if (__comp(*__first, *__result_first)) __adjust_heap(__result_first, _Distance(0), _Distance(__result_real_last - __result_first), _Tp(*__first), __comp); ++__first; } sort_heap(__result_first, __result_real_last, __comp); return __result_real_last; } template inline _RandomAccessIter partial_sort_copy(_InputIter __first, _InputIter __last, _RandomAccessIter __result_first, _RandomAccessIter __result_last, _Compare __comp) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); return __partial_sort_copy(__first, __last, __result_first, __result_last, __comp, __DISTANCE_TYPE(__result_first), __VALUE_TYPE(__first)); } // nth_element() and its auxiliary functions. template void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Tp*) { while (__last - __first > 3) { _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1)))); if (__cut <= __nth) __first = __cut; else __last = __cut; } __insertion_sort(__first, __last); } template inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); __nth_element(__first, __nth, __last, __VALUE_TYPE(__first)); } template void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Tp*, _Compare __comp) { while (__last - __first > 3) { _RandomAccessIter __cut = __unguarded_partition(__first, __last, _Tp(__median(*__first, *(__first + (__last - __first)/2), *(__last - 1), __comp)), __comp); if (__cut <= __nth) __first = __cut; else __last = __cut; } __insertion_sort(__first, __last, __comp); } template inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp); } // Binary search (lower_bound, upper_bound, equal_range, binary_search). template _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (*__middle < __val) { __first = __middle; ++__first; __len = __len - __half - 1; } else __len = __half; } return __first; } template inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); return __lower_bound(__first, __last, __val, __DISTANCE_TYPE(__first)); } template _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (__comp(*__middle, __val)) { __first = __middle; ++__first; __len = __len - __half - 1; } else __len = __half; } return __first; } template inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); return __lower_bound(__first, __last, __val, __comp, __DISTANCE_TYPE(__first)); } template _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (__val < *__middle) __len = __half; else { __first = __middle; ++__first; __len = __len - __half - 1; } } return __first; } template inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); return __upper_bound(__first, __last, __val, __DISTANCE_TYPE(__first)); } template _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (__comp(__val, *__middle)) __len = __half; else { __first = __middle; ++__first; __len = __len - __half - 1; } } return __first; } template inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); return __upper_bound(__first, __last, __val, __comp, __DISTANCE_TYPE(__first)); } template pair<_ForwardIter, _ForwardIter> __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle, __left, __right; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (*__middle < __val) { __first = __middle; ++__first; __len = __len - __half - 1; } else if (__val < *__middle) __len = __half; else { __left = lower_bound(__first, __middle, __val); advance(__first, __len); __right = upper_bound(++__middle, __first, __val); return pair<_ForwardIter, _ForwardIter>(__left, __right); } } return pair<_ForwardIter, _ForwardIter>(__first, __first); } template inline pair<_ForwardIter, _ForwardIter> equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); return __equal_range(__first, __last, __val, __DISTANCE_TYPE(__first)); } template pair<_ForwardIter, _ForwardIter> __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp, _Distance*) { _Distance __len = 0; distance(__first, __last, __len); _Distance __half; _ForwardIter __middle, __left, __right; while (__len > 0) { __half = __len >> 1; __middle = __first; advance(__middle, __half); if (__comp(*__middle, __val)) { __first = __middle; ++__first; __len = __len - __half - 1; } else if (__comp(__val, *__middle)) __len = __half; else { __left = lower_bound(__first, __middle, __val, __comp); advance(__first, __len); __right = upper_bound(++__middle, __first, __val, __comp); return pair<_ForwardIter, _ForwardIter>(__left, __right); } } return pair<_ForwardIter, _ForwardIter>(__first, __first); } template inline pair<_ForwardIter, _ForwardIter> equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); return __equal_range(__first, __last, __val, __comp, __DISTANCE_TYPE(__first)); } template bool binary_search(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_REQUIRES(_Tp, _LessThanComparable); _ForwardIter __i = lower_bound(__first, __last, __val); return __i != __last && !(__val < *__i); } template bool binary_search(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_SAME_TYPE(_Tp, typename iterator_traits<_ForwardIter>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); _ForwardIter __i = lower_bound(__first, __last, __val, __comp); return __i != __last && !__comp(__val, *__i); } // merge, with and without an explicitly supplied comparison function. template _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); while (__first1 != __last1 && __first2 != __last2) { if (*__first2 < *__first1) { *__result = *__first2; ++__first2; } else { *__result = *__first1; ++__first1; } ++__result; } return copy(__first2, __last2, copy(__first1, __last1, __result)); } template _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter1>::value_type); while (__first1 != __last1 && __first2 != __last2) { if (__comp(*__first2, *__first1)) { *__result = *__first2; ++__first2; } else { *__result = *__first1; ++__first1; } ++__result; } return copy(__first2, __last2, copy(__first1, __last1, __result)); } // inplace_merge and its auxiliary functions. template void __merge_without_buffer(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2) { if (__len1 == 0 || __len2 == 0) return; if (__len1 + __len2 == 2) { if (*__middle < *__first) iter_swap(__first, __middle); return; } _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = rotate(__first_cut, __middle, __second_cut); __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22); __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22); } template void __merge_without_buffer(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2, _Compare __comp) { if (__len1 == 0 || __len2 == 0) return; if (__len1 + __len2 == 2) { if (__comp(*__middle, *__first)) iter_swap(__first, __middle); return; } _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = rotate(__first_cut, __middle, __second_cut); __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22, __comp); __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __comp); } template _BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first, _BidirectionalIter1 __middle, _BidirectionalIter1 __last, _Distance __len1, _Distance __len2, _BidirectionalIter2 __buffer, _Distance __buffer_size) { _BidirectionalIter2 __buffer_end; if (__len1 > __len2 && __len2 <= __buffer_size) { __buffer_end = copy(__middle, __last, __buffer); copy_backward(__first, __middle, __last); return copy(__buffer, __buffer_end, __first); } else if (__len1 <= __buffer_size) { __buffer_end = copy(__first, __middle, __buffer); copy(__middle, __last, __first); return copy_backward(__buffer, __buffer_end, __last); } else return rotate(__first, __middle, __last); } template _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, _BidirectionalIter3 __result) { if (__first1 == __last1) return copy_backward(__first2, __last2, __result); if (__first2 == __last2) return copy_backward(__first1, __last1, __result); --__last1; --__last2; while (true) { if (*__last2 < *__last1) { *--__result = *__last1; if (__first1 == __last1) return copy_backward(__first2, ++__last2, __result); --__last1; } else { *--__result = *__last2; if (__first2 == __last2) return copy_backward(__first1, ++__last1, __result); --__last2; } } } template _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, _BidirectionalIter3 __result, _Compare __comp) { if (__first1 == __last1) return copy_backward(__first2, __last2, __result); if (__first2 == __last2) return copy_backward(__first1, __last1, __result); --__last1; --__last2; while (true) { if (__comp(*__last2, *__last1)) { *--__result = *__last1; if (__first1 == __last1) return copy_backward(__first2, ++__last2, __result); --__last1; } else { *--__result = *__last2; if (__first2 == __last2) return copy_backward(__first1, ++__last1, __result); --__last2; } } } template void __merge_adaptive(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2, _Pointer __buffer, _Distance __buffer_size) { if (__len1 <= __len2 && __len1 <= __buffer_size) { _Pointer __buffer_end = copy(__first, __middle, __buffer); merge(__buffer, __buffer_end, __middle, __last, __first); } else if (__len2 <= __buffer_size) { _Pointer __buffer_end = copy(__middle, __last, __buffer); __merge_backward(__first, __middle, __buffer, __buffer_end, __last); } else { _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, __len22, __buffer, __buffer_size); __merge_adaptive(__first, __first_cut, __new_middle, __len11, __len22, __buffer, __buffer_size); __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __buffer, __buffer_size); } } template void __merge_adaptive(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Distance __len1, _Distance __len2, _Pointer __buffer, _Distance __buffer_size, _Compare __comp) { if (__len1 <= __len2 && __len1 <= __buffer_size) { _Pointer __buffer_end = copy(__first, __middle, __buffer); merge(__buffer, __buffer_end, __middle, __last, __first, __comp); } else if (__len2 <= __buffer_size) { _Pointer __buffer_end = copy(__middle, __last, __buffer); __merge_backward(__first, __middle, __buffer, __buffer_end, __last, __comp); } else { _BidirectionalIter __first_cut = __first; _BidirectionalIter __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; advance(__first_cut, __len11); __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); distance(__middle, __second_cut, __len22); } else { __len22 = __len2 / 2; advance(__second_cut, __len22); __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); distance(__first, __first_cut, __len11); } _BidirectionalIter __new_middle = __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, __len22, __buffer, __buffer_size); __merge_adaptive(__first, __first_cut, __new_middle, __len11, __len22, __buffer, __buffer_size, __comp); __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __buffer, __buffer_size, __comp); } } template inline void __inplace_merge_aux(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Tp*, _Distance*) { _Distance __len1 = 0; distance(__first, __middle, __len1); _Distance __len2 = 0; distance(__middle, __last, __len2); _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); if (__buf.begin() == 0) __merge_without_buffer(__first, __middle, __last, __len1, __len2); else __merge_adaptive(__first, __middle, __last, __len1, __len2, __buf.begin(), _Distance(__buf.size())); } template inline void __inplace_merge_aux(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Tp*, _Distance*, _Compare __comp) { _Distance __len1 = 0; distance(__first, __middle, __len1); _Distance __len2 = 0; distance(__middle, __last, __len2); _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); if (__buf.begin() == 0) __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp); else __merge_adaptive(__first, __middle, __last, __len1, __len2, __buf.begin(), _Distance(__buf.size()), __comp); } template inline void inplace_merge(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, _LessThanComparable); if (__first == __middle || __middle == __last) return; __inplace_merge_aux(__first, __middle, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } template inline void inplace_merge(_BidirectionalIter __first, _BidirectionalIter __middle, _BidirectionalIter __last, _Compare __comp) { __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_BidirectionalIter>::value_type, typename iterator_traits<_BidirectionalIter>::value_type); if (__first == __middle || __middle == __last) return; __inplace_merge_aux(__first, __middle, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), __comp); } // 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. template bool includes(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); while (__first1 != __last1 && __first2 != __last2) if (*__first2 < *__first1) return false; else if(*__first1 < *__first2) ++__first1; else ++__first1, ++__first2; return __first2 == __last2; } template bool includes(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first2, *__first1)) return false; else if(__comp(*__first1, *__first2)) ++__first1; else ++__first1, ++__first2; return __first2 == __last2; } template _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); 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 copy(__first2, __last2, copy(__first1, __last1, __result)); } template _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); 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 copy(__first2, __last2, copy(__first1, __last1, __result)); } template _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); while (__first1 != __last1 && __first2 != __last2) if (*__first1 < *__first2) ++__first1; else if (*__first2 < *__first1) ++__first2; else { *__result = *__first1; ++__first1; ++__first2; ++__result; } return __result; } template _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) ++__first1; else if (__comp(*__first2, *__first1)) ++__first2; else { *__result = *__first1; ++__first1; ++__first2; ++__result; } return __result; } template _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); while (__first1 != __last1 && __first2 != __last2) if (*__first1 < *__first2) { *__result = *__first1; ++__first1; ++__result; } else if (*__first2 < *__first1) ++__first2; else { ++__first1; ++__first2; } return copy(__first1, __last1, __result); } template _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) { *__result = *__first1; ++__first1; ++__result; } else if (__comp(*__first2, *__first1)) ++__first2; else { ++__first1; ++__first2; } return copy(__first1, __last1, __result); } template _OutputIter set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); while (__first1 != __last1 && __first2 != __last2) if (*__first1 < *__first2) { *__result = *__first1; ++__first1; ++__result; } else if (*__first2 < *__first1) { *__result = *__first2; ++__first2; ++__result; } else { ++__first1; ++__first2; } return copy(__first2, __last2, copy(__first1, __last1, __result)); } template _OutputIter set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); __STL_REQUIRES_SAME_TYPE( typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_InputIter1>::value_type, typename iterator_traits<_InputIter2>::value_type); 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 copy(__first2, __last2, copy(__first1, __last1, __result)); } // min_element and max_element, with and without an explicitly supplied // comparison function. template _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _LessThanComparable); if (__first == __last) return __first; _ForwardIter __result = __first; while (++__first != __last) if (*__result < *__first) __result = __first; return __result; } template _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __first; _ForwardIter __result = __first; while (++__first != __last) if (__comp(*__result, *__first)) __result = __first; return __result; } template _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _LessThanComparable); if (__first == __last) return __first; _ForwardIter __result = __first; while (++__first != __last) if (*__first < *__result) __result = __first; return __result; } template _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last, _Compare __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return __first; _ForwardIter __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. template bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, _LessThanComparable); if (__first == __last) return false; _BidirectionalIter __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIter __ii = __i; --__i; if (*__i < *__ii) { _BidirectionalIter __j = __last; while (!(*__i < *--__j)) {} iter_swap(__i, __j); reverse(__ii, __last); return true; } if (__i == __first) { reverse(__first, __last); return false; } } } template bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, _Compare __comp) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_BidirectionalIter>::value_type, typename iterator_traits<_BidirectionalIter>::value_type); if (__first == __last) return false; _BidirectionalIter __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIter __ii = __i; --__i; if (__comp(*__i, *__ii)) { _BidirectionalIter __j = __last; while (!__comp(*__i, *--__j)) {} iter_swap(__i, __j); reverse(__ii, __last); return true; } if (__i == __first) { reverse(__first, __last); return false; } } } template bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type, _LessThanComparable); if (__first == __last) return false; _BidirectionalIter __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIter __ii = __i; --__i; if (*__ii < *__i) { _BidirectionalIter __j = __last; while (!(*--__j < *__i)) {} iter_swap(__i, __j); reverse(__ii, __last); return true; } if (__i == __first) { reverse(__first, __last); return false; } } } template bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, _Compare __comp) { __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator); __STL_BINARY_FUNCTION_CHECK(_Compare, bool, typename iterator_traits<_BidirectionalIter>::value_type, typename iterator_traits<_BidirectionalIter>::value_type); if (__first == __last) return false; _BidirectionalIter __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIter __ii = __i; --__i; if (__comp(*__ii, *__i)) { _BidirectionalIter __j = __last; while (!__comp(*--__j, *__i)) {} iter_swap(__i, __j); reverse(__ii, __last); return true; } if (__i == __first) { reverse(__first, __last); return false; } } } // find_first_of, with and without an explicitly supplied comparison function. template _InputIter find_first_of(_InputIter __first1, _InputIter __last1, _ForwardIter __first2, _ForwardIter __last2) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first1 != __last1; ++__first1) for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) if (*__first1 == *__iter) return __first1; return __last1; } template _InputIter find_first_of(_InputIter __first1, _InputIter __last1, _ForwardIter __first2, _ForwardIter __last2, _BinaryPredicate __comp) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_InputIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); for ( ; __first1 != __last1; ++__first1) for (_ForwardIter __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 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, forward_iterator_tag, forward_iterator_tag) { if (__first2 == __last2) return __last1; else { _ForwardIter1 __result = __last1; while (1) { _ForwardIter1 __new_result = search(__first1, __last1, __first2, __last2); if (__new_result == __last1) return __result; else { __result = __new_result; __first1 = __new_result; ++__first1; } } } } template _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, forward_iterator_tag, forward_iterator_tag, _BinaryPredicate __comp) { if (__first2 == __last2) return __last1; else { _ForwardIter1 __result = __last1; while (1) { _ForwardIter1 __new_result = 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. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template _BidirectionalIter1 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag) { __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator); __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator); typedef reverse_iterator<_BidirectionalIter1> _RevIter1; typedef reverse_iterator<_BidirectionalIter2> _RevIter2; _RevIter1 __rlast1(__first1); _RevIter2 __rlast2(__first2); _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, _RevIter2(__last2), __rlast2); if (__rresult == __rlast1) return __last1; else { _BidirectionalIter1 __result = __rresult.base(); advance(__result, -distance(__first2, __last2)); return __result; } } template _BidirectionalIter1 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag, _BinaryPredicate __comp) { __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator); __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator); typedef reverse_iterator<_BidirectionalIter1> _RevIter1; typedef reverse_iterator<_BidirectionalIter2> _RevIter2; _RevIter1 __rlast1(__first1); _RevIter2 __rlast2(__first2); _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, _RevIter2(__last2), __rlast2, __comp); if (__rresult == __rlast1) return __last1; else { _BidirectionalIter1 __result = __rresult.base(); advance(__result, -distance(__first2, __last2)); return __result; } } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // Dispatching functions for find_end. template inline _ForwardIter1 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); return __find_end(__first1, __last1, __first2, __last2, __ITERATOR_CATEGORY(__first1), __ITERATOR_CATEGORY(__first2)); } template inline _ForwardIter1 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2, _BinaryPredicate __comp) { __STL_REQUIRES(_ForwardIter1, _ForwardIterator); __STL_REQUIRES(_ForwardIter2, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); return __find_end(__first1, __last1, __first2, __last2, __ITERATOR_CATEGORY(__first1), __ITERATOR_CATEGORY(__first2), __comp); } // 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 bool __is_heap(_RandomAccessIter __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 bool __is_heap(_RandomAccessIter __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 inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last) { __STL_REQUIRES(_RandomAccessIter, _RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type, _LessThanComparable); return __is_heap(__first, __last - __first); } template inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last, _StrictWeakOrdering __comp) { __STL_REQUIRES(_RandomAccessIter, _RandomAccessIterator); __STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool, typename iterator_traits<_RandomAccessIter>::value_type, typename iterator_traits<_RandomAccessIter>::value_type); return __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. template bool is_sorted(_ForwardIter __first, _ForwardIter __last) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type, _LessThanComparable); if (__first == __last) return true; _ForwardIter __next = __first; for (++__next; __next != __last; __first = __next, ++__next) { if (*__next < *__first) return false; } return true; } template bool is_sorted(_ForwardIter __first, _ForwardIter __last, _StrictWeakOrdering __comp) { __STL_REQUIRES(_ForwardIter, _ForwardIterator); __STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool, typename iterator_traits<_ForwardIter>::value_type, typename iterator_traits<_ForwardIter>::value_type); if (__first == __last) return true; _ForwardIter __next = __first; for (++__next; __next != __last; __first = __next, ++__next) { if (__comp(*__next, *__first)) return false; } return true; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1209 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ALGO_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_algobase.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ALGOBASE_H #define __SGI_STL_INTERNAL_ALGOBASE_H #ifndef __STL_CONFIG_H #include #endif #ifndef __SGI_STL_INTERNAL_RELOPS #include #endif #ifndef __SGI_STL_INTERNAL_PAIR_H #include #endif #ifndef __TYPE_TRAITS_H #include #endif #include #include #include #include #include #ifdef __STL_USE_NEW_IOSTREAMS #include #else /* __STL_USE_NEW_IOSTREAMS */ #include #endif /* __STL_USE_NEW_IOSTREAMS */ #ifndef __SGI_STL_INTERNAL_ITERATOR_H #include #include #endif // We pick up concept_checks.h from stl_iterator_base.h. __STL_BEGIN_NAMESPACE // swap and iter_swap template inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) { _Tp __tmp = *__a; *__a = *__b; *__b = __tmp; } template inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) { __STL_REQUIRES(_ForwardIter1, _Mutable_ForwardIterator); __STL_REQUIRES(_ForwardIter2, _Mutable_ForwardIterator); __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter1>::value_type, typename iterator_traits<_ForwardIter2>::value_type); __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter2>::value_type, typename iterator_traits<_ForwardIter1>::value_type); __iter_swap(__a, __b, __VALUE_TYPE(__a)); } template inline void swap(_Tp& __a, _Tp& __b) { __STL_REQUIRES(_Tp, _Assignable); _Tp __tmp = __a; __a = __b; __b = __tmp; } //-------------------------------------------------- // min and max #if !defined(__BORLANDC__) || __BORLANDC__ >= 0x540 /* C++ Builder 4.0 */ #undef min #undef max template inline const _Tp& min(const _Tp& __a, const _Tp& __b) { __STL_REQUIRES(_Tp, _LessThanComparable); return __b < __a ? __b : __a; } template inline const _Tp& max(const _Tp& __a, const _Tp& __b) { __STL_REQUIRES(_Tp, _LessThanComparable); return __a < __b ? __b : __a; } #endif /* __BORLANDC__ */ template inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? __b : __a; } template inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__a, __b) ? __b : __a; } //-------------------------------------------------- // copy // All of these auxiliary functions 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 inline _OutputIter __copy(_InputIter __first, _InputIter __last, _OutputIter __result, input_iterator_tag, _Distance*) { for ( ; __first != __last; ++__result, ++__first) *__result = *__first; return __result; } template inline _OutputIter __copy(_RandomAccessIter __first, _RandomAccessIter __last, _OutputIter __result, random_access_iterator_tag, _Distance*) { for (_Distance __n = __last - __first; __n > 0; --__n) { *__result = *__first; ++__first; ++__result; } return __result; } template inline _Tp* __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) { memmove(__result, __first, sizeof(_Tp) * (__last - __first)); return __result + (__last - __first); } #if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) template inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last, _OutputIter __result, __false_type) { return __copy(__first, __last, __result, __ITERATOR_CATEGORY(__first), __DISTANCE_TYPE(__first)); } template inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last, _OutputIter __result, __true_type) { return __copy(__first, __last, __result, __ITERATOR_CATEGORY(__first), __DISTANCE_TYPE(__first)); } #ifndef __USLC__ template inline _Tp* __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result, __true_type) { return __copy_trivial(__first, __last, __result); } #endif /* __USLC__ */ template inline _Tp* __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result, __true_type) { return __copy_trivial(__first, __last, __result); } template inline _OutputIter __copy_aux(_InputIter __first, _InputIter __last, _OutputIter __result, _Tp*) { typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _Trivial; return __copy_aux2(__first, __last, __result, _Trivial()); } template inline _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); return __copy_aux(__first, __last, __result, __VALUE_TYPE(__first)); } // Hack for compilers that don't have partial ordering of function templates // but do have partial specialization of class templates. #elif defined(__STL_CLASS_PARTIAL_SPECIALIZATION) template struct __copy_dispatch { static _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) { typedef typename iterator_traits<_InputIter>::iterator_category _Category; typedef typename iterator_traits<_InputIter>::difference_type _Distance; return __copy(__first, __last, __result, _Category(), (_Distance*) 0); } }; template struct __copy_dispatch<_Tp*, _Tp*, __true_type> { static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { return __copy_trivial(__first, __last, __result); } }; template struct __copy_dispatch { static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { return __copy_trivial(__first, __last, __result); } }; template inline _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); typedef typename iterator_traits<_InputIter>::value_type _Tp; typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _Trivial; return __copy_dispatch<_InputIter, _OutputIter, _Trivial> ::copy(__first, __last, __result); } // Fallback for compilers with neither partial ordering nor partial // specialization. Define the faster version for the basic builtin // types. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) { return __copy(__first, __last, __result, __ITERATOR_CATEGORY(__first), __DISTANCE_TYPE(__first)); } #define __SGI_STL_DECLARE_COPY_TRIVIAL(_Tp) \ inline _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { \ memmove(__result, __first, sizeof(_Tp) * (__last - __first)); \ return __result + (__last - __first); \ } __SGI_STL_DECLARE_COPY_TRIVIAL(char) __SGI_STL_DECLARE_COPY_TRIVIAL(signed char) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned char) __SGI_STL_DECLARE_COPY_TRIVIAL(short) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned short) __SGI_STL_DECLARE_COPY_TRIVIAL(int) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned int) __SGI_STL_DECLARE_COPY_TRIVIAL(long) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long) #ifdef __STL_HAS_WCHAR_T __SGI_STL_DECLARE_COPY_TRIVIAL(wchar_t) #endif #ifdef _STL_LONG_LONG __SGI_STL_DECLARE_COPY_TRIVIAL(long long) __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long long) #endif __SGI_STL_DECLARE_COPY_TRIVIAL(float) __SGI_STL_DECLARE_COPY_TRIVIAL(double) __SGI_STL_DECLARE_COPY_TRIVIAL(long double) #undef __SGI_STL_DECLARE_COPY_TRIVIAL #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ //-------------------------------------------------- // copy_backward template inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first, _BidirectionalIter1 __last, _BidirectionalIter2 __result, bidirectional_iterator_tag, _Distance*) { while (__first != __last) *--__result = *--__last; return __result; } template inline _BidirectionalIter __copy_backward(_RandomAccessIter __first, _RandomAccessIter __last, _BidirectionalIter __result, random_access_iterator_tag, _Distance*) { for (_Distance __n = __last - __first; __n > 0; --__n) *--__result = *--__last; return __result; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION // This dispatch class is a workaround for compilers that do not // have partial ordering of function templates. All we're doing is // creating a specialization so that we can turn a call to copy_backward // into a memmove whenever possible. template struct __copy_backward_dispatch { typedef typename iterator_traits<_BidirectionalIter1>::iterator_category _Cat; typedef typename iterator_traits<_BidirectionalIter1>::difference_type _Distance; static _BidirectionalIter2 copy(_BidirectionalIter1 __first, _BidirectionalIter1 __last, _BidirectionalIter2 __result) { return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0); } }; template struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type> { static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { const ptrdiff_t _Num = __last - __first; memmove(__result - _Num, __first, sizeof(_Tp) * _Num); return __result - _Num; } }; template struct __copy_backward_dispatch { static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { return __copy_backward_dispatch<_Tp*, _Tp*, __true_type> ::copy(__first, __last, __result); } }; template inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { __STL_REQUIRES(_BI1, _BidirectionalIterator); __STL_REQUIRES(_BI2, _Mutable_BidirectionalIterator); __STL_CONVERTIBLE(typename iterator_traits<_BI1>::value_type, typename iterator_traits<_BI2>::value_type); typedef typename __type_traits::value_type> ::has_trivial_assignment_operator _Trivial; return __copy_backward_dispatch<_BI1, _BI2, _Trivial> ::copy(__first, __last, __result); } #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { return __copy_backward(__first, __last, __result, __ITERATOR_CATEGORY(__first), __DISTANCE_TYPE(__first)); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ //-------------------------------------------------- // copy_n (not part of the C++ standard) template pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count, _OutputIter __result, input_iterator_tag) { for ( ; __count > 0; --__count) { *__result = *__first; ++__first; ++__result; } return pair<_InputIter, _OutputIter>(__first, __result); } template inline pair<_RAIter, _OutputIter> __copy_n(_RAIter __first, _Size __count, _OutputIter __result, random_access_iterator_tag) { _RAIter __last = __first + __count; return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result)); } template inline pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count, _OutputIter __result) { return __copy_n(__first, __count, __result, __ITERATOR_CATEGORY(__first)); } template inline pair<_InputIter, _OutputIter> copy_n(_InputIter __first, _Size __count, _OutputIter __result) { __STL_REQUIRES(_InputIter, _InputIterator); __STL_REQUIRES(_OutputIter, _OutputIterator); return __copy_n(__first, __count, __result); } //-------------------------------------------------- // fill and fill_n template void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); for ( ; __first != __last; ++__first) *__first = __value; } template _OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) { __STL_REQUIRES(_OutputIter, _OutputIterator); for ( ; __n > 0; --__n, ++__first) *__first = __value; return __first; } // Specialization: for one-byte types we can use memset. inline void fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c) { unsigned char __tmp = __c; memset(__first, __tmp, __last - __first); } inline void fill(signed char* __first, signed char* __last, const signed char& __c) { signed char __tmp = __c; memset(__first, static_cast(__tmp), __last - __first); } inline void fill(char* __first, char* __last, const char& __c) { char __tmp = __c; memset(__first, static_cast(__tmp), __last - __first); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline unsigned char* fill_n(unsigned char* __first, _Size __n, const unsigned char& __c) { fill(__first, __first + __n, __c); return __first + __n; } template inline signed char* fill_n(char* __first, _Size __n, const signed char& __c) { fill(__first, __first + __n, __c); return __first + __n; } template inline char* fill_n(char* __first, _Size __n, const char& __c) { fill(__first, __first + __n, __c); return __first + __n; } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ //-------------------------------------------------- // equal and mismatch template pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _EqualityComparable); __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, _EqualityComparable); while (__first1 != __last1 && *__first1 == *__first2) { ++__first1; ++__first2; } return pair<_InputIter1, _InputIter2>(__first1, __first2); } template pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) { ++__first1; ++__first2; } return pair<_InputIter1, _InputIter2>(__first1, __first2); } template inline bool equal(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _EqualityComparable); __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, _EqualityComparable); for ( ; __first1 != __last1; ++__first1, ++__first2) if (*__first1 != *__first2) return false; return true; } template inline bool equal(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _BinaryPredicate __binary_pred) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); for ( ; __first1 != __last1; ++__first1, ++__first2) if (!__binary_pred(*__first1, *__first2)) return false; return true; } //-------------------------------------------------- // lexicographical_compare and lexicographical_compare_3way. // (the latter is not part of the C++ standard.) template bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, _LessThanComparable); for ( ; __first1 != __last1 && __first2 != __last2 ; ++__first1, ++__first2) { if (*__first1 < *__first2) return true; if (*__first2 < *__first1) return false; } return __first1 == __last1 && __first2 != __last2; } template bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); 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) { const size_t __len1 = __last1 - __first1; const size_t __len2 = __last2 - __first2; const int __result = memcmp(__first1, __first2, 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) { #if CHAR_MAX == SCHAR_MAX return lexicographical_compare((const signed char*) __first1, (const signed char*) __last1, (const signed char*) __first2, (const signed char*) __last2); #else /* CHAR_MAX == SCHAR_MAX */ return lexicographical_compare((const unsigned char*) __first1, (const unsigned char*) __last1, (const unsigned char*) __first2, (const unsigned char*) __last2); #endif /* CHAR_MAX == SCHAR_MAX */ } template int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __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 = 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 } template int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2) { __STL_REQUIRES(_InputIter1, _InputIterator); __STL_REQUIRES(_InputIter2, _InputIterator); __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type, _LessThanComparable); __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type, _LessThanComparable); return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ALGOBASE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_alloc.h ================================================ /* * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ALLOC_H #define __SGI_STL_INTERNAL_ALLOC_H #ifdef __SUNPRO_CC # define __PRIVATE public // Extra access restrictions prevent us from really making some things // private. #else # define __PRIVATE private #endif #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG # define __USE_MALLOC #endif // This implements some standard node allocators. These are // NOT the same as the allocators in the C++ draft standard or in // in the original STL. They do not encapsulate different pointer // types; indeed we assume that there is only one pointer type. // The allocation primitives are intended to allocate individual objects, // not larger arenas as with the original STL allocators. #ifndef __THROW_BAD_ALLOC # if defined(__STL_NO_BAD_ALLOC) || !defined(__STL_USE_EXCEPTIONS) # include # include # define __THROW_BAD_ALLOC fprintf(stderr, "out of memory\n"); exit(1) # else /* Standard conforming out-of-memory handling */ # include # define __THROW_BAD_ALLOC throw std::bad_alloc() # endif #endif #include #include #include #include #ifndef __RESTRICT # define __RESTRICT #endif #ifdef __STL_THREADS # include # define __NODE_ALLOCATOR_THREADS true # ifdef __STL_SGI_THREADS // We test whether threads are in use before locking. // Perhaps this should be moved into stl_threads.h, but that // probably makes it harder to avoid the procedure call when // it isn't needed. extern "C" { extern int __us_rsthread_malloc; } // The above is copied from malloc.h. Including // would be cleaner but fails with certain levels of standard // conformance. # define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \ { _S_node_allocator_lock._M_acquire_lock(); } # define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \ { _S_node_allocator_lock._M_release_lock(); } # else /* !__STL_SGI_THREADS */ # define __NODE_ALLOCATOR_LOCK \ { if (threads) _S_node_allocator_lock._M_acquire_lock(); } # define __NODE_ALLOCATOR_UNLOCK \ { if (threads) _S_node_allocator_lock._M_release_lock(); } # endif #else // Thread-unsafe # define __NODE_ALLOCATOR_LOCK # define __NODE_ALLOCATOR_UNLOCK # define __NODE_ALLOCATOR_THREADS false #endif __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif // Malloc-based allocator. Typically slower than default alloc below. // Typically thread-safe and more storage efficient. #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG # ifdef __DECLARE_GLOBALS_HERE void (* __malloc_alloc_oom_handler)() = 0; // g++ 2.7.2 does not handle static template data members. # else extern void (* __malloc_alloc_oom_handler)(); # endif #endif template class __malloc_alloc_template { private: static void* _S_oom_malloc(size_t); static void* _S_oom_realloc(void*, size_t); #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG static void (* __malloc_alloc_oom_handler)(); #endif public: static void* allocate(size_t __n) { void* __result = malloc(__n); if (0 == __result) __result = _S_oom_malloc(__n); return __result; } static void deallocate(void* __p, size_t /* __n */) { free(__p); } static void* reallocate(void* __p, size_t /* old_sz */, size_t __new_sz) { void* __result = realloc(__p, __new_sz); if (0 == __result) __result = _S_oom_realloc(__p, __new_sz); return __result; } static void (* __set_malloc_handler(void (*__f)()))() { void (* __old)() = __malloc_alloc_oom_handler; __malloc_alloc_oom_handler = __f; return(__old); } }; // malloc_alloc out-of-memory handling #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG template void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0; #endif template void* __malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n) { void (* __my_malloc_handler)(); void* __result; for (;;) { __my_malloc_handler = __malloc_alloc_oom_handler; if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; } (*__my_malloc_handler)(); __result = malloc(__n); if (__result) return(__result); } } template void* __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n) { void (* __my_malloc_handler)(); void* __result; for (;;) { __my_malloc_handler = __malloc_alloc_oom_handler; if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; } (*__my_malloc_handler)(); __result = realloc(__p, __n); if (__result) return(__result); } } typedef __malloc_alloc_template<0> malloc_alloc; template class simple_alloc { public: static _Tp* allocate(size_t __n) { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); } static _Tp* allocate(void) { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); } static void deallocate(_Tp* __p, size_t __n) { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); } static void deallocate(_Tp* __p) { _Alloc::deallocate(__p, sizeof (_Tp)); } }; // Allocator adaptor to check size arguments for debugging. // Reports errors using assert. Checking can be disabled with // NDEBUG, but it's far better to just use the underlying allocator // instead when no checking is desired. // There is some evidence that this can confuse Purify. template class debug_alloc { private: enum {_S_extra = 8}; // Size of space used to store size. Note // that this must be large enough to preserve // alignment. public: static void* allocate(size_t __n) { char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra); *(size_t*)__result = __n; return __result + (int) _S_extra; } static void deallocate(void* __p, size_t __n) { char* __real_p = (char*)__p - (int) _S_extra; assert(*(size_t*)__real_p == __n); _Alloc::deallocate(__real_p, __n + (int) _S_extra); } static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz) { char* __real_p = (char*)__p - (int) _S_extra; assert(*(size_t*)__real_p == __old_sz); char* __result = (char*) _Alloc::reallocate(__real_p, __old_sz + (int) _S_extra, __new_sz + (int) _S_extra); *(size_t*)__result = __new_sz; return __result + (int) _S_extra; } }; # ifdef __USE_MALLOC typedef malloc_alloc alloc; typedef malloc_alloc single_client_alloc; # else // Default node allocator. // With a reasonable compiler, this should be roughly as fast as the // original STL class-specific allocators, but with less fragmentation. // Default_alloc_template parameters are experimental and MAY // DISAPPEAR in the future. Clients should just use alloc for now. // // Important implementation properties: // 1. If the client request an object of size > _MAX_BYTES, the resulting // object will be obtained directly from malloc. // 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. // // The first template parameter specifies whether more than one thread // may use this allocator. It is safe to allocate an object from // one instance of a default_alloc and deallocate it with another // one. This effectively transfers its ownership to the second one. // This may have undesirable effects on reference locality. // The second parameter is unreferenced and serves only to allow the // creation of multiple default_alloc instances. // Node that containers built on different allocator instances have // different types, limiting the utility of this approach. #if defined(__SUNPRO_CC) || defined(__GNUC__) // breaks if we make these template class members: enum {_ALIGN = 8}; enum {_MAX_BYTES = 128}; enum {_NFREELISTS = 16}; // _MAX_BYTES/_ALIGN #endif template class __default_alloc_template { private: // Really we should use static const int x = N // instead of enum { x = N }, but few compilers accept the former. #if ! (defined(__SUNPRO_CC) || defined(__GNUC__)) enum {_ALIGN = 8}; enum {_MAX_BYTES = 128}; enum {_NFREELISTS = 16}; // _MAX_BYTES/_ALIGN # endif static size_t _S_round_up(size_t __bytes) { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); } __PRIVATE: union _Obj { union _Obj* _M_free_list_link; char _M_client_data[1]; /* The client sees this. */ }; private: # if defined(__SUNPRO_CC) || defined(__GNUC__) || defined(__HP_aCC) static _Obj* __STL_VOLATILE _S_free_list[]; // Specifying a size results in duplicate def for 4.1 # else static _Obj* __STL_VOLATILE _S_free_list[_NFREELISTS]; # endif static size_t _S_freelist_index(size_t __bytes) { return (((__bytes) + (size_t)_ALIGN-1)/(size_t)_ALIGN - 1); } // Returns an object of size __n, and optionally adds to size __n free list. static void* _S_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. static char* _S_chunk_alloc(size_t __size, int& __nobjs); // Chunk allocation state. static char* _S_start_free; static char* _S_end_free; static size_t _S_heap_size; # ifdef __STL_THREADS static _STL_mutex_lock _S_node_allocator_lock; # endif // It would be nice to use _STL_auto_lock here. But we // don't need the NULL check. And we do need a test whether // threads have actually been started. class _Lock; friend class _Lock; class _Lock { public: _Lock() { __NODE_ALLOCATOR_LOCK; } ~_Lock() { __NODE_ALLOCATOR_UNLOCK; } }; public: /* __n must be > 0 */ static void* allocate(size_t __n) { void* __ret = 0; if (__n > (size_t) _MAX_BYTES) { __ret = malloc_alloc::allocate(__n); } else { _Obj* __STL_VOLATILE* __my_free_list = _S_free_list + _S_freelist_index(__n); // Acquire the lock here with a constructor call. // This ensures that it is released in exit or during stack // unwinding. # ifndef _NOTHREADS /*REFERENCED*/ _Lock __lock_instance; # endif _Obj* __RESTRICT __result = *__my_free_list; if (__result == 0) __ret = _S_refill(_S_round_up(__n)); else { *__my_free_list = __result -> _M_free_list_link; __ret = __result; } } return __ret; }; /* __p may not be 0 */ static void deallocate(void* __p, size_t __n) { if (__n > (size_t) _MAX_BYTES) malloc_alloc::deallocate(__p, __n); else { _Obj* __STL_VOLATILE* __my_free_list = _S_free_list + _S_freelist_index(__n); _Obj* __q = (_Obj*)__p; // acquire lock # ifndef _NOTHREADS /*REFERENCED*/ _Lock __lock_instance; # endif /* _NOTHREADS */ __q -> _M_free_list_link = *__my_free_list; *__my_free_list = __q; // lock is released here } } static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz); } ; typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc; typedef __default_alloc_template single_client_alloc; template inline bool operator==(const __default_alloc_template<__threads, __inst>&, const __default_alloc_template<__threads, __inst>&) { return true; } # ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const __default_alloc_template<__threads, __inst>&, const __default_alloc_template<__threads, __inst>&) { return false; } # endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ /* We allocate memory in large chunks in order to avoid fragmenting */ /* the malloc heap too much. */ /* We assume that size is properly aligned. */ /* We hold the allocation lock. */ template char* __default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size, int& __nobjs) { char* __result; size_t __total_bytes = __size * __nobjs; size_t __bytes_left = _S_end_free - _S_start_free; if (__bytes_left >= __total_bytes) { __result = _S_start_free; _S_start_free += __total_bytes; return(__result); } else if (__bytes_left >= __size) { __nobjs = (int)(__bytes_left/__size); __total_bytes = __size * __nobjs; __result = _S_start_free; _S_start_free += __total_bytes; return(__result); } else { size_t __bytes_to_get = 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); // Try to make use of the left-over piece. if (__bytes_left > 0) { _Obj* __STL_VOLATILE* __my_free_list = _S_free_list + _S_freelist_index(__bytes_left); ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; *__my_free_list = (_Obj*)_S_start_free; } _S_start_free = (char*)malloc(__bytes_to_get); if (0 == _S_start_free) { size_t __i; _Obj* __STL_VOLATILE* __my_free_list; _Obj* __p; // Try to make do with what we have. That can't // hurt. We do not try smaller requests, since that tends // to result in disaster on multi-process machines. for (__i = __size; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN) { __my_free_list = _S_free_list + _S_freelist_index(__i); __p = *__my_free_list; if (0 != __p) { *__my_free_list = __p -> _M_free_list_link; _S_start_free = (char*)__p; _S_end_free = _S_start_free + __i; return(_S_chunk_alloc(__size, __nobjs)); // Any leftover piece will eventually make it to the // right free list. } } _S_end_free = 0; // In case of exception. _S_start_free = (char*)malloc_alloc::allocate(__bytes_to_get); // This should either throw an // exception or remedy the situation. Thus we assume it // succeeded. } _S_heap_size += __bytes_to_get; _S_end_free = _S_start_free + __bytes_to_get; return(_S_chunk_alloc(__size, __nobjs)); } } /* Returns an object of size __n, and optionally adds to size __n free list.*/ /* We assume that __n is properly aligned. */ /* We hold the allocation lock. */ template void* __default_alloc_template<__threads, __inst>::_S_refill(size_t __n) { int __nobjs = 20; char* __chunk = _S_chunk_alloc(__n, __nobjs); _Obj* __STL_VOLATILE* __my_free_list; _Obj* __result; _Obj* __current_obj; _Obj* __next_obj; int __i; if (1 == __nobjs) return(__chunk); __my_free_list = _S_free_list + _S_freelist_index(__n); /* Build free list in chunk */ __result = (_Obj*)__chunk; *__my_free_list = __next_obj = (_Obj*)(__chunk + __n); for (__i = 1; ; __i++) { __current_obj = __next_obj; __next_obj = (_Obj*)((char*)__next_obj + __n); if (__nobjs - 1 == __i) { __current_obj -> _M_free_list_link = 0; break; } else { __current_obj -> _M_free_list_link = __next_obj; } } return(__result); } template void* __default_alloc_template::reallocate(void* __p, size_t __old_sz, size_t __new_sz) { void* __result; size_t __copy_sz; if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) { return(realloc(__p, __new_sz)); } if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); __result = allocate(__new_sz); __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; memcpy(__result, __p, __copy_sz); deallocate(__p, __old_sz); return(__result); } #ifdef __STL_THREADS template _STL_mutex_lock __default_alloc_template<__threads, __inst>::_S_node_allocator_lock __STL_MUTEX_INITIALIZER; #endif template char* __default_alloc_template<__threads, __inst>::_S_start_free = 0; template char* __default_alloc_template<__threads, __inst>::_S_end_free = 0; template size_t __default_alloc_template<__threads, __inst>::_S_heap_size = 0; template typename __default_alloc_template<__threads, __inst>::_Obj* __STL_VOLATILE __default_alloc_template<__threads, __inst> ::_S_free_list[ # if defined(__SUNPRO_CC) || defined(__GNUC__) || defined(__HP_aCC) _NFREELISTS # else __default_alloc_template<__threads, __inst>::_NFREELISTS # endif ] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; // The 16 zeros are necessary to make version 4.1 of the SunPro // compiler happy. Otherwise it appears to allocate too little // space for the array. #endif /* ! __USE_MALLOC */ // This implements allocators as specified in the C++ standard. // // Note that standard-conforming allocators use many language features // that are not yet widely implemented. In particular, they rely on // member templates, partial specialization, partial ordering of function // templates, the typename keyword, and the use of the template keyword // to refer to a template member of a dependent type. #ifdef __STL_USE_STD_ALLOCATORS template class allocator { typedef alloc _Alloc; // The underlying 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 struct rebind { typedef allocator<_Tp1> other; }; allocator() __STL_NOTHROW {} allocator(const allocator&) __STL_NOTHROW {} template allocator(const allocator<_Tp1>&) __STL_NOTHROW {} ~allocator() __STL_NOTHROW {} pointer address(reference __x) const { return &__x; } const_pointer address(const_reference __x) const { return &__x; } // __n is permitted to be 0. The C++ standard says nothing about what // the return value is when __n == 0. _Tp* allocate(size_type __n, const void* = 0) { return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))) : 0; } // __p is not permitted to be a null pointer. void deallocate(pointer __p, size_type __n) { _Alloc::deallocate(__p, __n * sizeof(_Tp)); } size_type max_size() const __STL_NOTHROW { return size_t(-1) / sizeof(_Tp); } void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } void destroy(pointer __p) { __p->~_Tp(); } }; template<> class allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef allocator<_Tp1> other; }; }; template inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) { return true; } template inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&) { return false; } // Allocator adaptor to turn an SGI-style allocator (e.g. alloc, malloc_alloc) // into a standard-conforming allocator. Note that this adaptor does // *not* assume that all objects of the underlying alloc class are // identical, nor does it assume that all of the underlying alloc's // member functions are static member functions. Note, also, that // __allocator<_Tp, alloc> is essentially the same thing as allocator<_Tp>. template struct __allocator { _Alloc __underlying_alloc; 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 struct rebind { typedef __allocator<_Tp1, _Alloc> other; }; __allocator() __STL_NOTHROW {} __allocator(const __allocator& __a) __STL_NOTHROW : __underlying_alloc(__a.__underlying_alloc) {} template __allocator(const __allocator<_Tp1, _Alloc>& __a) __STL_NOTHROW : __underlying_alloc(__a.__underlying_alloc) {} ~__allocator() __STL_NOTHROW {} pointer address(reference __x) const { return &__x; } const_pointer address(const_reference __x) const { return &__x; } // __n is permitted to be 0. _Tp* allocate(size_type __n, const void* = 0) { return __n != 0 ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp))) : 0; } // __p is not permitted to be a null pointer. void deallocate(pointer __p, size_type __n) { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); } size_type max_size() const __STL_NOTHROW { return size_t(-1) / sizeof(_Tp); } void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } void destroy(pointer __p) { __p->~_Tp(); } }; template class __allocator { typedef size_t size_type; typedef ptrdiff_t difference_type; typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef __allocator<_Tp1, _Alloc> other; }; }; template inline bool operator==(const __allocator<_Tp, _Alloc>& __a1, const __allocator<_Tp, _Alloc>& __a2) { return __a1.__underlying_alloc == __a2.__underlying_alloc; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const __allocator<_Tp, _Alloc>& __a1, const __allocator<_Tp, _Alloc>& __a2) { return __a1.__underlying_alloc != __a2.__underlying_alloc; } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Comparison operators for all of the predifined SGI-style allocators. // This ensures that __allocator (for example) will // work correctly. template inline bool operator==(const __malloc_alloc_template&, const __malloc_alloc_template&) { return true; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const __malloc_alloc_template<__inst>&, const __malloc_alloc_template<__inst>&) { return false; } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template inline bool operator==(const debug_alloc<_Alloc>&, const debug_alloc<_Alloc>&) { return true; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const debug_alloc<_Alloc>&, const debug_alloc<_Alloc>&) { return false; } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Another allocator adaptor: _Alloc_traits. This serves two // purposes. First, make it possible to write containers that can use // either SGI-style allocators or standard-conforming allocator. // Second, provide a mechanism so that containers can query whether or // not the allocator has distinct instances. If not, the container // can avoid wasting a word of memory to store an empty object. // This adaptor uses partial specialization. The general case of // _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a // standard-conforming allocator, possibly with non-equal instances // and non-static members. (It still behaves correctly even if _Alloc // has static member and if all instances are equal. Refinements // affect performance, not correctness.) // There are always two members: allocator_type, which is a standard- // conforming allocator type for allocating objects of type _Tp, and // _S_instanceless, a static const member of type bool. If // _S_instanceless is true, this means that there is no difference // between any two instances of type allocator_type. Furthermore, if // _S_instanceless is true, then _Alloc_traits has one additional // member: _Alloc_type. This type encapsulates allocation and // deallocation of objects of type _Tp through a static interface; it // has two member functions, whose signatures are // static _Tp* allocate(size_t) // static void deallocate(_Tp*, size_t) // The fully general version. template struct _Alloc_traits { static const bool _S_instanceless = false; typedef typename _Allocator::__STL_TEMPLATE rebind<_Tp>::other allocator_type; }; template const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; // The version for the default allocator. template struct _Alloc_traits<_Tp, allocator<_Tp1> > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, alloc> _Alloc_type; typedef allocator<_Tp> allocator_type; }; // Versions for the predefined SGI-style allocators. template struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; }; template struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, __default_alloc_template<__threads, __inst> > _Alloc_type; typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> > allocator_type; }; template struct _Alloc_traits<_Tp, debug_alloc<_Alloc> > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; }; // Versions for the __allocator adaptor used with the predefined // SGI-style allocators. template struct _Alloc_traits<_Tp, __allocator<_Tp1, __malloc_alloc_template<__inst> > > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; }; template struct _Alloc_traits<_Tp, __allocator<_Tp1, __default_alloc_template<__thr, __inst> > > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, __default_alloc_template<__thr,__inst> > _Alloc_type; typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> > allocator_type; }; template struct _Alloc_traits<_Tp, __allocator<_Tp1, debug_alloc<_Alloc> > > { static const bool _S_instanceless = true; typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; }; #endif /* __STL_USE_STD_ALLOCATORS */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #undef __PRIVATE #endif /* __SGI_STL_INTERNAL_ALLOC_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_bvector.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_BVECTOR_H #define __SGI_STL_INTERNAL_BVECTOR_H __STL_BEGIN_NAMESPACE static const int __WORD_BIT = int(CHAR_BIT*sizeof(unsigned int)); #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif struct _Bit_reference { unsigned int* _M_p; unsigned int _M_mask; _Bit_reference(unsigned int* __x, unsigned int __y) : _M_p(__x), _M_mask(__y) {} public: _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; } }; inline void swap(_Bit_reference __x, _Bit_reference __y) { bool __tmp = __x; __x = __y; __y = __tmp; } struct _Bit_iterator_base : public random_access_iterator { unsigned int* _M_p; unsigned int _M_offset; _Bit_iterator_base(unsigned int* __x, unsigned int __y) : _M_p(__x), _M_offset(__y) {} void _M_bump_up() { if (_M_offset++ == __WORD_BIT - 1) { _M_offset = 0; ++_M_p; } } void _M_bump_down() { if (_M_offset-- == 0) { _M_offset = __WORD_BIT - 1; --_M_p; } } void _M_incr(ptrdiff_t __i) { difference_type __n = __i + _M_offset; _M_p += __n / __WORD_BIT; __n = __n % __WORD_BIT; if (__n < 0) { _M_offset = (unsigned int) __n + __WORD_BIT; --_M_p; } else _M_offset = (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 __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(unsigned int* __x, unsigned int __y) : _Bit_iterator_base(__x, __y) {} reference operator*() const { return reference(_M_p, 1U << _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) { 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(unsigned int* __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, 1U << _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) { return *(*this + __i); } }; inline _Bit_const_iterator operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) { return __x + __n; } // Bit-vector base class, which encapsulates the difference between // old SGI-style allocators and standard-conforming allocators. #ifdef __STL_USE_STD_ALLOCATORS // Base class for ordinary allocators. template class _Bvector_alloc_base { public: typedef typename _Alloc_traits::allocator_type allocator_type; allocator_type get_allocator() const { return _M_data_allocator; } _Bvector_alloc_base(const allocator_type& __a) : _M_data_allocator(__a), _M_start(), _M_finish(), _M_end_of_storage(0) {} protected: unsigned int* _M_bit_alloc(size_t __n) { return _M_data_allocator.allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } void _M_deallocate() { if (_M_start._M_p) _M_data_allocator.deallocate(_M_start._M_p, _M_end_of_storage - _M_start._M_p); } typename _Alloc_traits::allocator_type _M_data_allocator; _Bit_iterator _M_start; _Bit_iterator _M_finish; unsigned int* _M_end_of_storage; }; // Specialization for instanceless allocators. template class _Bvector_alloc_base<_Allocator, true> { public: typedef typename _Alloc_traits::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Bvector_alloc_base(const allocator_type&) : _M_start(), _M_finish(), _M_end_of_storage(0) {} protected: typedef typename _Alloc_traits::_Alloc_type _Alloc_type; unsigned int* _M_bit_alloc(size_t __n) { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } void _M_deallocate() { if (_M_start._M_p) _Alloc_type::deallocate(_M_start._M_p, _M_end_of_storage - _M_start._M_p); } _Bit_iterator _M_start; _Bit_iterator _M_finish; unsigned int* _M_end_of_storage; }; template class _Bvector_base : public _Bvector_alloc_base<_Alloc, _Alloc_traits::_S_instanceless> { typedef _Bvector_alloc_base<_Alloc, _Alloc_traits::_S_instanceless> _Base; public: typedef typename _Base::allocator_type allocator_type; _Bvector_base(const allocator_type& __a) : _Base(__a) {} ~_Bvector_base() { _Base::_M_deallocate(); } }; #else /* __STL_USE_STD_ALLOCATORS */ template class _Bvector_base { public: typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Bvector_base(const allocator_type&) : _M_start(), _M_finish(), _M_end_of_storage(0) {} ~_Bvector_base() { _M_deallocate(); } protected: typedef simple_alloc _Alloc_type; unsigned int* _M_bit_alloc(size_t __n) { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } void _M_deallocate() { if (_M_start._M_p) _Alloc_type::deallocate(_M_start._M_p, _M_end_of_storage - _M_start._M_p); } _Bit_iterator _M_start; _Bit_iterator _M_finish; unsigned int* _M_end_of_storage; }; #endif /* __STL_USE_STD_ALLOCATORS */ // The next few lines are confusing. What we're doing is declaring a // partial specialization of vector if we have the necessary // compiler support. Otherwise, we define a class bit_vector which uses // the default allocator. #if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NO_BOOL) # define __SGI_STL_VECBOOL_TEMPLATE # define __BVECTOR vector # define __VECTOR vector # define __BVECTOR_BASE _Bvector_base<_Alloc> # define __BVECTOR_TMPL_LIST template __STL_END_NAMESPACE # include __STL_BEGIN_NAMESPACE #else /* __STL_CLASS_PARTIAL_SPECIALIZATION && !__STL_NO_BOOL */ # undef __SGI_STL_VECBOOL_TEMPLATE # define __BVECTOR bit_vector # define __VECTOR bit_vector # define __BVECTOR_BASE _Bvector_base<__STL_DEFAULT_ALLOCATOR(bool) > # define __BVECTOR_TMPL_LIST #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION && !__STL_NO_BOOL */ __BVECTOR_TMPL_LIST class __BVECTOR : public __BVECTOR_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; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef typename __BVECTOR_BASE::allocator_type allocator_type; allocator_type get_allocator() const { return __BVECTOR_BASE::get_allocator(); } protected: #ifdef __STL_USE_NAMESPACES using __BVECTOR_BASE::_M_bit_alloc; using __BVECTOR_BASE::_M_deallocate; using __BVECTOR_BASE::_M_start; using __BVECTOR_BASE::_M_finish; using __BVECTOR_BASE::_M_end_of_storage; #endif /* __STL_USE_NAMESPACES */ protected: void _M_initialize(size_type __n) { unsigned int* __q = _M_bit_alloc(__n); _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT; _M_start = iterator(__q, 0); _M_finish = _M_start + difference_type(__n); } void _M_insert_aux(iterator __position, bool __x) { if (_M_finish._M_p != _M_end_of_storage) { copy_backward(__position, _M_finish, _M_finish + 1); *__position = __x; ++_M_finish; } else { size_type __len = size() ? 2 * size() : __WORD_BIT; unsigned int* __q = _M_bit_alloc(__len); iterator __i = copy(begin(), __position, iterator(__q, 0)); *__i++ = __x; _M_finish = copy(__position, end(), __i); _M_deallocate(); _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; _M_start = iterator(__q, 0); } } #ifdef __STL_MEMBER_TEMPLATES template void _M_initialize_range(_InputIterator __first, _InputIterator __last, input_iterator_tag) { _M_start = iterator(); _M_finish = iterator(); _M_end_of_storage = 0; for ( ; __first != __last; ++__first) push_back(*__first); } template void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { size_type __n = 0; distance(__first, __last, __n); _M_initialize(__n); copy(__first, __last, _M_start); } template void _M_insert_range(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag) { for ( ; __first != __last; ++__first) { __pos = insert(__pos, *__first); ++__pos; } } template void _M_insert_range(iterator __position, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { if (__first != __last) { size_type __n = 0; distance(__first, __last, __n); if (capacity() - size() >= __n) { copy_backward(__position, end(), _M_finish + difference_type(__n)); copy(__first, __last, __position); _M_finish += difference_type(__n); } else { size_type __len = size() + max(size(), __n); unsigned int* __q = _M_bit_alloc(__len); iterator __i = copy(begin(), __position, iterator(__q, 0)); __i = copy(__first, __last, __i); _M_finish = copy(__position, end(), __i); _M_deallocate(); _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; _M_start = iterator(__q, 0); } } } #endif /* __STL_MEMBER_TEMPLATES */ public: iterator begin() { return _M_start; } const_iterator begin() const { return _M_start; } iterator end() { return _M_finish; } const_iterator end() const { return _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 { return size_type(-1); } size_type capacity() const { return size_type(const_iterator(_M_end_of_storage, 0) - begin()); } bool empty() const { return begin() == end(); } reference operator[](size_type __n) { return *(begin() + difference_type(__n)); } const_reference operator[](size_type __n) const { return *(begin() + difference_type(__n)); } #ifdef __STL_THROW_RANGE_ERRORS void _M_range_check(size_type __n) const { if (__n >= this->size()) __stl_throw_range_error("vector"); } 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]; } #endif /* __STL_THROW_RANGE_ERRORS */ explicit __VECTOR(const allocator_type& __a = allocator_type()) : __BVECTOR_BASE(__a) {} __VECTOR(size_type __n, bool __value, const allocator_type& __a = allocator_type()) : __BVECTOR_BASE(__a) { _M_initialize(__n); fill(_M_start._M_p, _M_end_of_storage, __value ? ~0 : 0); } explicit __VECTOR(size_type __n) : __BVECTOR_BASE(allocator_type()) { _M_initialize(__n); fill(_M_start._M_p, _M_end_of_storage, 0); } __VECTOR(const __VECTOR& __x) : __BVECTOR_BASE(__x.get_allocator()) { _M_initialize(__x.size()); copy(__x.begin(), __x.end(), _M_start); } #ifdef __STL_MEMBER_TEMPLATES // Check whether it's an integral type. If so, it's not an iterator. template void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { _M_initialize(__n); fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); } template void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _M_initialize_range(__first, __last, __ITERATOR_CATEGORY(__first)); } template __VECTOR(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : __BVECTOR_BASE(__a) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } #else /* __STL_MEMBER_TEMPLATES */ __VECTOR(const_iterator __first, const_iterator __last, const allocator_type& __a = allocator_type()) : __BVECTOR_BASE(__a) { size_type __n = 0; distance(__first, __last, __n); _M_initialize(__n); copy(__first, __last, _M_start); } __VECTOR(const bool* __first, const bool* __last, const allocator_type& __a = allocator_type()) : __BVECTOR_BASE(__a) { size_type __n = 0; distance(__first, __last, __n); _M_initialize(__n); copy(__first, __last, _M_start); } #endif /* __STL_MEMBER_TEMPLATES */ ~__VECTOR() { } __VECTOR& operator=(const __VECTOR& __x) { if (&__x == this) return *this; if (__x.size() > capacity()) { _M_deallocate(); _M_initialize(__x.size()); } copy(__x.begin(), __x.end(), begin()); _M_finish = begin() + difference_type(__x.size()); 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 _M_fill_assign(size_t __n, bool __x) { if (__n > size()) { fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); insert(end(), __n - size(), __x); } else { erase(begin() + __n, end()); fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); } } void assign(size_t __n, bool __x) { _M_fill_assign(__n, __x); } #ifdef __STL_MEMBER_TEMPLATES template void assign(_InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_assign_dispatch(__first, __last, _Integral()); } template void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign((size_t) __n, (bool) __val); } template void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } template void _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag) { iterator __cur = begin(); for ( ; __first != __last && __cur != end(); ++__cur, ++__first) *__cur = *__first; if (__first == __last) erase(__cur, end()); else insert(end(), __first, __last); } template void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { size_type __len = 0; distance(__first, __last, __len); if (__len < size()) erase(copy(__first, __last, begin()), end()); else { _ForwardIterator __mid = __first; advance(__mid, size()); copy(__first, __mid, begin()); insert(end(), __mid, __last); } } #endif /* __STL_MEMBER_TEMPLATES */ void reserve(size_type __n) { if (capacity() < __n) { unsigned int* __q = _M_bit_alloc(__n); _M_finish = copy(begin(), end(), iterator(__q, 0)); _M_deallocate(); _M_start = iterator(__q, 0); _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT; } } reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(end() - 1); } const_reference back() const { return *(end() - 1); } void push_back(bool __x) { if (_M_finish._M_p != _M_end_of_storage) *_M_finish++ = __x; else _M_insert_aux(end(), __x); } void swap(__BVECTOR& __x) { __STD::swap(_M_start, __x._M_start); __STD::swap(_M_finish, __x._M_finish); __STD::swap(_M_end_of_storage, __x._M_end_of_storage); } iterator insert(iterator __position, bool __x = bool()) { difference_type __n = __position - begin(); if (_M_finish._M_p != _M_end_of_storage && __position == end()) *_M_finish++ = __x; else _M_insert_aux(__position, __x); return begin() + __n; } #ifdef __STL_MEMBER_TEMPLATES // Check whether it's an integral type. If so, it's not an iterator. template void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type) { _M_fill_insert(__pos, __n, __x); } template void _M_insert_dispatch(iterator __pos, _InputIterator __first, _InputIterator __last, __false_type) { _M_insert_range(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); } template void insert(iterator __position, _InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator __position, const_iterator __first, const_iterator __last) { if (__first == __last) return; size_type __n = 0; distance(__first, __last, __n); if (capacity() - size() >= __n) { copy_backward(__position, end(), _M_finish + __n); copy(__first, __last, __position); _M_finish += __n; } else { size_type __len = size() + max(size(), __n); unsigned int* __q = _M_bit_alloc(__len); iterator __i = copy(begin(), __position, iterator(__q, 0)); __i = copy(__first, __last, __i); _M_finish = copy(__position, end(), __i); _M_deallocate(); _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; _M_start = iterator(__q, 0); } } void insert(iterator __position, const bool* __first, const bool* __last) { if (__first == __last) return; size_type __n = 0; distance(__first, __last, __n); if (capacity() - size() >= __n) { copy_backward(__position, end(), _M_finish + __n); copy(__first, __last, __position); _M_finish += __n; } else { size_type __len = size() + max(size(), __n); unsigned int* __q = _M_bit_alloc(__len); iterator __i = copy(begin(), __position, iterator(__q, 0)); __i = copy(__first, __last, __i); _M_finish = copy(__position, end(), __i); _M_deallocate(); _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; _M_start = iterator(__q, 0); } } #endif /* __STL_MEMBER_TEMPLATES */ void _M_fill_insert(iterator __position, size_type __n, bool __x) { if (__n == 0) return; if (capacity() - size() >= __n) { copy_backward(__position, end(), _M_finish + difference_type(__n)); fill(__position, __position + difference_type(__n), __x); _M_finish += difference_type(__n); } else { size_type __len = size() + max(size(), __n); unsigned int* __q = _M_bit_alloc(__len); iterator __i = copy(begin(), __position, iterator(__q, 0)); fill_n(__i, __n, __x); _M_finish = copy(__position, end(), __i + difference_type(__n)); _M_deallocate(); _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; _M_start = iterator(__q, 0); } } void insert(iterator __position, size_type __n, bool __x) { _M_fill_insert(__position, __n, __x); } void pop_back() { --_M_finish; } iterator erase(iterator __position) { if (__position + 1 != end()) copy(__position + 1, end(), __position); --_M_finish; return __position; } iterator erase(iterator __first, iterator __last) { _M_finish = copy(__last, end(), __first); return __first; } void resize(size_type __new_size, bool __x = bool()) { if (__new_size < size()) erase(begin() + difference_type(__new_size), end()); else insert(end(), __new_size - size(), __x); } void flip() { for (unsigned int* __p = _M_start._M_p; __p != _M_end_of_storage; ++__p) *__p = ~*__p; } void clear() { erase(begin(), end()); } }; #ifdef __SGI_STL_VECBOOL_TEMPLATE // This typedef is non-standard. It is provided for backward compatibility. typedef vector bit_vector; #else /* __SGI_STL_VECBOOL_TEMPLATE */ inline void swap(bit_vector& __x, bit_vector& __y) { __x.swap(__y); } inline bool operator==(const bit_vector& __x, const bit_vector& __y) { return (__x.size() == __y.size() && equal(__x.begin(), __x.end(), __y.begin())); } inline bool operator!=(const bit_vector& __x, const bit_vector& __y) { return !(__x == __y); } inline bool operator<(const bit_vector& __x, const bit_vector& __y) { return lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } inline bool operator>(const bit_vector& __x, const bit_vector& __y) { return __y < __x; } inline bool operator<=(const bit_vector& __x, const bit_vector& __y) { return !(__y < __x); } inline bool operator>=(const bit_vector& __x, const bit_vector& __y) { return !(__x < __y); } #endif /* __SGI_STL_VECBOOL_TEMPLATE */ #undef __SGI_STL_VECBOOL_TEMPLATE #undef __BVECTOR #undef __VECTOR #undef __BVECTOR_BASE #undef __BVECTOR_TMPL_LIST #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_BVECTOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_config.h ================================================ /* * * 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 * * 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 __STL_CONFIG_H # define __STL_CONFIG_H // Flags: // * __STL_NO_BOOL: defined if the compiler doesn't have bool as a builtin // type. // * __STL_HAS_WCHAR_T: defined if the compier has wchar_t as a builtin type. // * __STL_NO_DRAND48: defined if the compiler doesn't have the drand48 // function. // * __STL_STATIC_TEMPLATE_MEMBER_BUG: defined if the compiler can't handle // static members of template classes. // * __STL_STATIC_CONST_INIT_BUG: defined if the compiler can't handle a // constant-initializer in the declaration of a static const data member // of integer type. (See section 9.4.2, paragraph 4, of the C++ standard.) // * __STL_CLASS_PARTIAL_SPECIALIZATION: defined if the compiler supports // partial specialization of template classes. // * __STL_PARTIAL_SPECIALIZATION_SYNTAX: defined if the compiler // supports partial specialization syntax for full specialization of // class templates. (Even if it doesn't actually support partial // specialization itself.) // * __STL_FUNCTION_TMPL_PARTIAL_ORDER: defined if the compiler supports // partial ordering of function templates. (a.k.a partial specialization // of function templates.) // * __STL_MEMBER_TEMPLATES: defined if the compiler supports template // member functions of classes. // * __STL_MEMBER_TEMPLATE_CLASSES: defined if the compiler supports // nested classes that are member templates of other classes. // * __STL_TEMPLATE_FRIENDS: defined if the compiler supports templatized // friend declarations. // * __STL_EXPLICIT_FUNCTION_TMPL_ARGS: defined if the compiler // supports calling a function template by providing its template // arguments explicitly. // * __STL_LIMITED_DEFAULT_TEMPLATES: defined if the compiler is unable // to handle default template parameters that depend on previous template // parameters. // * __STL_NON_TYPE_TMPL_PARAM_BUG: defined if the compiler has trouble with // function template argument deduction for non-type template parameters. // * __SGI_STL_NO_ARROW_OPERATOR: defined if the compiler is unable // to support the -> operator for iterators. // * __STL_DEFAULT_CONSTRUCTOR_BUG: defined if T() does not work properly // when T is a builtin type. // * __STL_USE_EXCEPTIONS: defined if the compiler (in the current compilation // mode) supports exceptions. // * __STL_USE_NAMESPACES: defined if the compiler has the necessary // support for namespaces. // * __STL_NO_EXCEPTION_HEADER: defined if the compiler does not have a // standard-conforming header . // * __STL_NO_BAD_ALLOC: defined if the compiler does not have a // header, or if does not contain a bad_alloc class. If a bad_alloc // class exists, it is assumed to be in namespace std. // * __STL_SGI_THREADS: defined if this is being compiled for an SGI IRIX // system in multithreaded mode, using native SGI threads instead of // pthreads. // * __STL_WIN32THREADS: defined if this is being compiled on a WIN32 // compiler in multithreaded mode. // * __STL_PTHREADS: defined if we should use portable pthreads // synchronization. // * __STL_UITHREADS: defined if we should use UI / solaris / UnixWare threads // synchronization. UIthreads are similar to pthreads, but are based // on an earlier version of the Posix threads standard. // * __STL_LONG_LONG if the compiler has long long and unsigned long long // types. (They're not in the C++ standard, but they are expected to be // included in the forthcoming C9X standard.) // * __STL_THREADS is defined if thread safety is needed. // * __STL_VOLATILE is defined to be "volatile" if threads are being // used, and the empty string otherwise. // * __STL_USE_CONCEPT_CHECKS enables some extra compile-time error // checking to make sure that user-defined template arguments satisfy // all of the appropriate requirements. This may result in more // comprehensible error messages. It incurs no runtime overhead. This // feature requires member templates and partial specialization. // * __STL_NO_USING_CLAUSE_IN_CLASS: The compiler does not handle "using" // clauses inside of class definitions. // * __STL_NO_FRIEND_TEMPLATE_CLASS: The compiler does not handle friend // declaractions where the friend is a template class. // * __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE: The compiler does not // support the use of a function pointer type as the argument // for a template. // * __STL_MEMBER_TEMPLATE_KEYWORD: standard C++ requires the template // keyword in a few new places (14.2.4). This flag is set for // compilers that support (and require) this usage. // User-settable macros that control compilation: // * __STL_USE_SGI_ALLOCATORS: if defined, then the STL will use older // SGI-style allocators, instead of standard-conforming allocators, // even if the compiler supports all of the language features needed // for standard-conforming allocators. // * __STL_NO_NAMESPACES: if defined, don't put the library in namespace // std, even if the compiler supports namespaces. // * __STL_NO_RELOPS_NAMESPACE: if defined, don't put the relational // operator templates (>, <=. >=, !=) in namespace std::rel_ops, even // if the compiler supports namespaces and partial ordering of // function templates. // * __STL_ASSERTIONS: if defined, then enable runtime checking through the // __stl_assert macro. // * _PTHREADS: if defined, use Posix threads for multithreading support. // * _UITHREADS:if defined, use SCO/Solaris/UI threads for multithreading // support // * _NOTHREADS: if defined, don't use any multithreading support. // * _STL_NO_CONCEPT_CHECKS: if defined, disables the error checking that // we get from __STL_USE_CONCEPT_CHECKS. // * __STL_USE_NEW_IOSTREAMS: if defined, then the STL will use new, // standard-conforming iostreams (e.g. the header). If not // defined, the STL will use old cfront-style iostreams (e.g. the // header). // Other macros defined by this file: // * bool, true, and false, if __STL_NO_BOOL is defined. // * typename, as a null macro if it's not already a keyword. // * explicit, as a null macro if it's not already a keyword. // * namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) // * exception-related macros (__STL_TRY, __STL_UNWIND, etc.) // * __stl_assert, either as a test or as a null macro, depending on // whether or not __STL_ASSERTIONS is defined. # if defined(_PTHREADS) && !defined(_NOTHREADS) # define __STL_PTHREADS # endif # if defined(_UITHREADS) && !defined(_PTHREADS) && !defined(_NOTHREADS) # define __STL_UITHREADS # endif # if defined(__sgi) && !defined(__GNUC__) # include # if !defined(_BOOL) # define __STL_NO_BOOL # endif # if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32 # define __STL_STATIC_CONST_INIT_BUG # endif # if defined(_WCHAR_T_IS_KEYWORD) # define __STL_HAS_WCHAR_T # endif # if !defined(_TYPENAME_IS_KEYWORD) # define __STL_NEED_TYPENAME # endif # ifdef _PARTIAL_SPECIALIZATION_OF_CLASS_TEMPLATES # define __STL_CLASS_PARTIAL_SPECIALIZATION # endif # if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # endif # ifdef _MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATES # define __STL_TEMPLATE_FRIENDS # define __STL_MEMBER_TEMPLATE_CLASSES # endif # if defined(_MEMBER_TEMPLATE_KEYWORD) # define __STL_MEMBER_TEMPLATE_KEYWORD # endif # if defined(_STANDARD_C_PLUS_PLUS) # define __STL_EXPLICIT_FUNCTION_TMPL_ARGS # endif # if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 # define __STL_MEMBER_TEMPLATE_KEYWORD # endif # if COMPILER_VERSION < 720 || (defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32) # define __STL_DEFAULT_CONSTRUCTOR_BUG # endif # if !defined(_EXPLICIT_IS_KEYWORD) # define __STL_NEED_EXPLICIT # endif # ifdef __EXCEPTIONS # define __STL_USE_EXCEPTIONS # endif # if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES) # define __STL_HAS_NAMESPACES # endif # if (_COMPILER_VERSION < 721) || \ !defined(__STL_HAS_NAMESPACES) || defined(__STL_NO_NAMESPACES) # define __STL_NO_EXCEPTION_HEADER # endif # if _COMPILER_VERSION < 730 || !defined(_STANDARD_C_PLUS_PLUS) || \ !defined(_NAMESPACES) # define __STL_NO_BAD_ALLOC # endif # if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) # define __STL_SGI_THREADS # endif # if defined(_LONGLONG) && defined(_SGIAPI) && _SGIAPI # define __STL_LONG_LONG # endif # if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) # define __STL_USE_NEW_IOSTREAMS # endif # if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) # define __STL_CAN_THROW_RANGE_ERRORS # endif # if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) # define __SGI_STL_USE_AUTO_PTR_CONVERSIONS # endif # endif /* * Jochen Schlick '1999 - added new #defines (__STL)_UITHREADS (for * providing SCO / Solaris / UI thread support) * - added the necessary defines for the SCO UDK 7 * compiler (and its template friend behavior) * - all UDK7 specific STL changes are based on the * macro __USLC__ being defined */ // SCO UDK 7 compiler (UnixWare 7x, OSR 5, UnixWare 2x) # if defined(__USLC__) # define __STL_HAS_WCHAR_T # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_PARTIAL_SPECIALIZATION_SYNTAX # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_USE_EXCEPTIONS # define __STL_HAS_NAMESPACES # define __STL_USE_NAMESPACES # define __STL_LONG_LONG # if defined(_REENTRANT) # define _UITHREADS /* if UnixWare < 7.0.1 */ # define __STL_UITHREADS // use the following defines instead of the UI threads defines when // you want to use POSIX threads //# define _PTHREADS /* only if UnixWare >=7.0.1 */ //# define __STL_PTHREADS # endif # endif # ifdef __GNUC__ # if __GNUC__ == 2 && __GNUC_MINOR__ <= 7 # define __STL_STATIC_TEMPLATE_MEMBER_BUG # endif # if __GNUC__ < 2 # define __STL_NEED_TYPENAME # define __STL_NEED_EXPLICIT # endif # if __GNUC__ == 2 && __GNUC_MINOR__ <= 8 # define __STL_NO_EXCEPTION_HEADER # define __STL_NO_BAD_ALLOC # endif # if __GNUC__ == 2 && __GNUC_MINOR__ >= 8 # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_MEMBER_TEMPLATES # define __STL_CAN_THROW_RANGE_ERRORS // g++ 2.8.1 supports member template functions, but not member // template nested classes. # if __GNUC_MINOR__ >= 9 # define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_TEMPLATE_FRIENDS # define __SGI_STL_USE_AUTO_PTR_CONVERSIONS # define __STL_HAS_NAMESPACES //# define __STL_USE_NEW_IOSTREAMS # endif # endif # define __STL_DEFAULT_CONSTRUCTOR_BUG # ifdef __EXCEPTIONS # define __STL_USE_EXCEPTIONS # endif # ifdef _REENTRANT # define __STL_PTHREADS # endif # if (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 95) # define __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE # endif # endif # if defined(__SUNPRO_CC) # define __STL_NO_BOOL # define __STL_NEED_TYPENAME # define __STL_NEED_EXPLICIT # define __STL_USE_EXCEPTIONS # ifdef _REENTRANT # define __STL_PTHREADS # endif # define __SGI_STL_NO_ARROW_OPERATOR # define __STL_PARTIAL_SPECIALIZATION_SYNTAX # define __STL_NO_EXCEPTION_HEADER # define __STL_NO_BAD_ALLOC # endif # if defined(__COMO__) # define __STL_MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_TEMPLATE_FRIENDS # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_USE_EXCEPTIONS # define __STL_HAS_NAMESPACES # endif // Intel compiler, which uses the EDG front end. # if defined(__ICL) # define __STL_LONG_LONG # define __STL_MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_TEMPLATE_FRIENDS # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_NO_DRAND48 # define __STL_HAS_NAMESPACES # define __STL_USE_EXCEPTIONS # define __STL_MEMBER_TEMPLATE_KEYWORD # ifdef _CPPUNWIND # define __STL_USE_EXCEPTIONS # endif # ifdef _MT # define __STL_WIN32THREADS # endif # endif // Mingw32, egcs compiler using the Microsoft C runtime # if defined(__MINGW32__) # define __STL_NO_DRAND48 # ifdef _MT # define __STL_WIN32THREADS # endif # endif // Cygwin32, egcs compiler on MS Windows # if defined(__CYGWIN__) # define __STL_NO_DRAND48 # endif // Microsoft compiler. # if defined(_MSC_VER) && !defined(__ICL) && !defined(__MWERKS__) # define __STL_NO_DRAND48 # define __STL_STATIC_CONST_INIT_BUG # define __STL_NEED_TYPENAME # define __STL_NO_USING_CLAUSE_IN_CLASS # define __STL_NO_FRIEND_TEMPLATE_CLASS # if _MSC_VER < 1100 /* 1000 is version 4.0, 1100 is 5.0, 1200 is 6.0. */ # define __STL_NEED_EXPLICIT # define __STL_NO_BOOL # define __STL_NO_BAD_ALLOC # endif # if _MSC_VER > 1000 # include # define __STL_DONT_USE_BOOL_TYPEDEF # endif # define __STL_NON_TYPE_TMPL_PARAM_BUG # define __SGI_STL_NO_ARROW_OPERATOR # define __STL_DEFAULT_CONSTRUCTOR_BUG # ifdef _CPPUNWIND # define __STL_USE_EXCEPTIONS # endif # ifdef _MT # define __STL_WIN32THREADS # endif # if _MSC_VER >= 1200 # define __STL_PARTIAL_SPECIALIZATION_SYNTAX # define __STL_HAS_NAMESPACES # define __STL_CAN_THROW_RANGE_ERRORS # define NOMINMAX # undef min # undef max // disable warning 'initializers put in unrecognized initialization area' # pragma warning ( disable : 4075 ) // disable warning 'empty controlled statement found' # pragma warning ( disable : 4390 ) // disable warning 'debug symbol greater than 255 chars' # pragma warning ( disable : 4786 ) # endif # if _MSC_VER < 1100 # define __STL_NO_EXCEPTION_HEADER # define __STL_NO_BAD_ALLOC # endif // Because of a Microsoft front end bug, we must not provide a // namespace qualifier when declaring a friend function. # define __STD_QUALIFIER # endif # if defined(__BORLANDC__) # define __STL_NO_BAD_ALLOC # define __STL_NO_DRAND48 # define __STL_DEFAULT_CONSTRUCTOR_BUG # if __BORLANDC__ >= 0x540 /* C++ Builder 4.0 */ # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_MEMBER_TEMPLATES # define __STL_TEMPLATE_FRIENDS # else # define __STL_NEED_TYPENAME # define __STL_LIMITED_DEFAULT_TEMPLATES # define __SGI_STL_NO_ARROW_OPERATOR # define __STL_NON_TYPE_TMPL_PARAM_BUG # endif # ifdef _CPPUNWIND # define __STL_USE_EXCEPTIONS # endif # ifdef __MT__ # define __STL_WIN32THREADS # endif # endif # if defined(__STL_NO_BOOL) && !defined(__STL_DONT_USE_BOOL_TYPEDEF) typedef int bool; # define true 1 # define false 0 # endif # ifdef __STL_NEED_TYPENAME # define typename # endif # ifdef __STL_LIMITED_DEFAULT_TEMPLATES # define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) # else # define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) = _Tp # endif # ifdef __STL_MEMBER_TEMPLATE_KEYWORD # define __STL_TEMPLATE template # else # define __STL_TEMPLATE # endif # ifdef __STL_NEED_EXPLICIT # define explicit # endif # ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_NULL_TMPL_ARGS <> # else # define __STL_NULL_TMPL_ARGS # endif # if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ || defined (__STL_PARTIAL_SPECIALIZATION_SYNTAX) # define __STL_TEMPLATE_NULL template<> # else # define __STL_TEMPLATE_NULL # endif // Use standard-conforming allocators if we have the necessary language // features. __STL_USE_SGI_ALLOCATORS is a hook so that users can // disable new-style allocators, and continue to use the same kind of // allocators as before, without having to edit library headers. # if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && \ defined(__STL_MEMBER_TEMPLATES) && \ defined(__STL_MEMBER_TEMPLATE_CLASSES) && \ !defined(__STL_NO_BOOL) && \ !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) && \ !defined(__STL_LIMITED_DEFAULT_TEMPLATES) && \ !defined(__STL_USE_SGI_ALLOCATORS) # define __STL_USE_STD_ALLOCATORS # endif # ifndef __STL_DEFAULT_ALLOCATOR # ifdef __STL_USE_STD_ALLOCATORS # define __STL_DEFAULT_ALLOCATOR(T) allocator< T > # else # define __STL_DEFAULT_ALLOCATOR(T) alloc # endif # endif // __STL_NO_NAMESPACES is a hook so that users can disable namespaces // without having to edit library headers. __STL_NO_RELOPS_NAMESPACE is // a hook so that users can disable the std::rel_ops namespace, keeping // the relational operator template in namespace std, without having to // edit library headers. # if defined(__STL_HAS_NAMESPACES) && !defined(__STL_NO_NAMESPACES) # define __STL_USE_NAMESPACES # define __STD std # define __STL_BEGIN_NAMESPACE namespace std { # define __STL_END_NAMESPACE } # if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \ !defined(__STL_NO_RELOPS_NAMESPACE) # define __STL_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE namespace std { namespace rel_ops { # define __STL_END_RELOPS_NAMESPACE } } # define __STD_RELOPS std::rel_ops # else /* Use std::rel_ops namespace */ # define __STL_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE namespace std { # define __STL_END_RELOPS_NAMESPACE } # define __STD_RELOPS std # endif /* Use std::rel_ops namespace */ # else # define __STD # define __STL_BEGIN_NAMESPACE # define __STL_END_NAMESPACE # undef __STL_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE # define __STL_END_RELOPS_NAMESPACE # define __STD_RELOPS # undef __STL_USE_NAMESPACES # endif // Some versions of the EDG front end sometimes require an explicit // namespace spec where they shouldn't. This macro facilitates that. // If the bug becomes irrelevant, then all uses of __STD_QUALIFIER // should be removed. The 7.3 beta SGI compiler has this bug, but the // MR version is not expected to have it. # if defined(__STL_USE_NAMESPACES) && !defined(__STD_QUALIFIER) # define __STD_QUALIFIER std:: # else # define __STD_QUALIFIER # endif # ifdef __STL_USE_EXCEPTIONS # define __STL_TRY try # define __STL_CATCH_ALL catch(...) # define __STL_THROW(x) throw x # define __STL_RETHROW throw # define __STL_NOTHROW throw() # define __STL_UNWIND(action) catch(...) { action; throw; } # else # define __STL_TRY # define __STL_CATCH_ALL if (false) # define __STL_THROW(x) # define __STL_RETHROW # define __STL_NOTHROW # define __STL_UNWIND(action) # endif #ifdef __STL_ASSERTIONS # include # define __stl_assert(expr) \ if (!(expr)) { fprintf(stderr, "%s:%d STL assertion failure: %s\n", \ __FILE__, __LINE__, # expr); abort(); } #else # define __stl_assert(expr) #endif #if defined(__STL_WIN32THREADS) || defined(__STL_SGI_THREADS) \ || defined(__STL_PTHREADS) || defined(__STL_UITHREADS) # define __STL_THREADS # define __STL_VOLATILE volatile #else # define __STL_VOLATILE #endif #if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ && defined(__STL_MEMBER_TEMPLATES) \ && !defined(_STL_NO_CONCEPT_CHECKS) # define __STL_USE_CONCEPT_CHECKS #endif #endif /* __STL_CONFIG_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_construct.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_CONSTRUCT_H #define __SGI_STL_INTERNAL_CONSTRUCT_H #include __STL_BEGIN_NAMESPACE // construct and destroy. These functions are not part of the C++ standard, // and are provided for backward compatibility with the HP STL. We also // provide internal names _Construct and _Destroy that can be used within // the library, so that standard-conforming pieces don't have to rely on // non-standard extensions. // Internal names template inline void _Construct(_T1* __p, const _T2& __value) { new ((void*) __p) _T1(__value); } template inline void _Construct(_T1* __p) { new ((void*) __p) _T1(); } template inline void _Destroy(_Tp* __pointer) { __pointer->~_Tp(); } template void __destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type) { for ( ; __first != __last; ++__first) destroy(&*__first); } template inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {} template inline void __destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*) { typedef typename __type_traits<_Tp>::has_trivial_destructor _Trivial_destructor; __destroy_aux(__first, __last, _Trivial_destructor()); } template inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) { __destroy(__first, __last, __VALUE_TYPE(__first)); } inline void _Destroy(char*, char*) {} inline void _Destroy(int*, int*) {} inline void _Destroy(long*, long*) {} inline void _Destroy(float*, float*) {} inline void _Destroy(double*, double*) {} #ifdef __STL_HAS_WCHAR_T inline void _Destroy(wchar_t*, wchar_t*) {} #endif /* __STL_HAS_WCHAR_T */ // -------------------------------------------------- // Old names from the HP STL. template inline void construct(_T1* __p, const _T2& __value) { _Construct(__p, __value); } template inline void construct(_T1* __p) { _Construct(__p); } template inline void destroy(_Tp* __pointer) { _Destroy(__pointer); } template inline void destroy(_ForwardIterator __first, _ForwardIterator __last) { _Destroy(__first, __last); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_CONSTRUCT_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_ctraits_fns.h ================================================ /* * Copyright (c) 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. */ // WARNING: This is an internal header file, included by other C++ // standard library headers. You should not attempt to use this header // file directly. #ifndef __SGI_STL_INTERNAL_CTRAITS_FUNCTIONS_H #define __SGI_STL_INTERNAL_CTRAITS_FUNCTIONS_H // This file contains a few small adapters that allow a character // traits class to be used as a function object. __STL_BEGIN_NAMESPACE template struct _Eq_traits : public binary_function { bool operator()(const typename _Traits::char_type& __x, const typename _Traits::char_type& __y) const { return _Traits::eq(__x, __y); } }; template struct _Eq_int_traits : public binary_function { bool operator()(const typename _Traits::char_type& __x, const typename _Traits::int_type& __y) const { return _Traits::eq_int_type(_Traits::to_int_type(__x), __y); } }; template struct _Lt_traits : public binary_function { bool operator()(const typename _Traits::char_type& __x, const typename _Traits::char_type& __y) const { return _Traits::lt(__x, __y); } }; __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_CTRAITS_FUNCTIONS_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_deque.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #include #ifndef __SGI_STL_INTERNAL_DEQUE_H #define __SGI_STL_INTERNAL_DEQUE_H /* Class invariants: * For any nonsingular iterator i: * i.node is the address of an element in the map array. The * contents of i.node is a pointer to the beginning of a node. * i.first == *(i.node) * 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, and that a deque * with N elements, where N is the buffer size, must have two nodes. * 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]. */ /* * In previous versions of deque, there was an extra template * parameter so users could control the node size. This extension * turns out to violate the C++ standard (it can be detected using * template template parameters), and it has been removed. */ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // Note: this function is simply a kludge to work around several compilers' // bugs in handling constant expressions. inline size_t __deque_buf_size(size_t __size) { return __size < 512 ? size_t(512 / __size) : size_t(1); } template 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 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; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return _M_cur; } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ difference_type operator-(const _Self& __x) const { return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) + (_M_cur - _M_first) + (__x._M_last - __x._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) { difference_type __offset = __n + (_M_cur - _M_first); if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) _M_cur += __n; else { 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); } bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; } bool operator!=(const _Self& __x) const { return !(*this == __x); } bool operator<(const _Self& __x) const { return (_M_node == __x._M_node) ? (_M_cur < __x._M_cur) : (_M_node < __x._M_node); } bool operator>(const _Self& __x) const { return __x < *this; } bool operator<=(const _Self& __x) const { return !(__x < *this); } bool operator>=(const _Self& __x) const { return !(*this < __x); } 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()); } }; template inline _Deque_iterator<_Tp, _Ref, _Ptr> operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) { return __x + __n; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline random_access_iterator_tag iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return random_access_iterator_tag(); } template inline _Tp* value_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; } template inline ptrdiff_t* distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // Deque base class. It has two purposes. First, its constructor // and destructor allocate (but don't initialize) storage. This makes // exception safety easier. Second, the base class encapsulates all of // the differences between SGI-style allocators and standard-conforming // allocators. #ifdef __STL_USE_STD_ALLOCATORS // Base class for ordinary allocators. template class _Deque_alloc_base { public: typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_node_allocator; } _Deque_alloc_base(const allocator_type& __a) : _M_node_allocator(__a), _M_map_allocator(__a), _M_map(0), _M_map_size(0) {} protected: typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type _Map_allocator_type; allocator_type _M_node_allocator; _Map_allocator_type _M_map_allocator; _Tp* _M_allocate_node() { return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp))); } void _M_deallocate_node(_Tp* __p) { _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp))); } _Tp** _M_allocate_map(size_t __n) { return _M_map_allocator.allocate(__n); } void _M_deallocate_map(_Tp** __p, size_t __n) { _M_map_allocator.deallocate(__p, __n); } _Tp** _M_map; size_t _M_map_size; }; // Specialization for instanceless allocators. template class _Deque_alloc_base<_Tp, _Alloc, true> { public: typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {} protected: typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type; typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type; _Tp* _M_allocate_node() { return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); } void _M_deallocate_node(_Tp* __p) { _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } _Tp** _M_allocate_map(size_t __n) { return _Map_alloc_type::allocate(__n); } void _M_deallocate_map(_Tp** __p, size_t __n) { _Map_alloc_type::deallocate(__p, __n); } _Tp** _M_map; size_t _M_map_size; }; template class _Deque_base : public _Deque_alloc_base<_Tp,_Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { public: typedef _Deque_alloc_base<_Tp,_Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base; typedef typename _Base::allocator_type allocator_type; 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) : _Base(__a), _M_start(), _M_finish() { _M_initialize_map(__num_elements); } _Deque_base(const allocator_type& __a) : _Base(__a), _M_start(), _M_finish() {} ~_Deque_base(); 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 }; protected: iterator _M_start; iterator _M_finish; }; #else /* __STL_USE_STD_ALLOCATORS */ template class _Deque_base { public: typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Deque_base(const allocator_type&, size_t __num_elements) : _M_map(0), _M_map_size(0), _M_start(), _M_finish() { _M_initialize_map(__num_elements); } _Deque_base(const allocator_type&) : _M_map(0), _M_map_size(0), _M_start(), _M_finish() {} ~_Deque_base(); 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 }; protected: _Tp** _M_map; size_t _M_map_size; iterator _M_start; iterator _M_finish; typedef simple_alloc<_Tp, _Alloc> _Node_alloc_type; typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type; _Tp* _M_allocate_node() { return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); } void _M_deallocate_node(_Tp* __p) { _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } _Tp** _M_allocate_map(size_t __n) { return _Map_alloc_type::allocate(__n); } void _M_deallocate_map(_Tp** __p, size_t __n) { _Map_alloc_type::deallocate(__p, __n); } }; #endif /* __STL_USE_STD_ALLOCATORS */ // Non-inline member functions from _Deque_base. template _Deque_base<_Tp,_Alloc>::~_Deque_base() { if (_M_map) { _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1); _M_deallocate_map(_M_map, _M_map_size); } } template void _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) { size_t __num_nodes = __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2); _M_map = _M_allocate_map(_M_map_size); _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2; _Tp** __nfinish = __nstart + __num_nodes; __STL_TRY { _M_create_nodes(__nstart, __nfinish); } __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size), _M_map = 0, _M_map_size = 0)); _M_start._M_set_node(__nstart); _M_finish._M_set_node(__nfinish - 1); _M_start._M_cur = _M_start._M_first; _M_finish._M_cur = _M_finish._M_first + __num_elements % __deque_buf_size(sizeof(_Tp)); } template void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish) { _Tp** __cur; __STL_TRY { for (__cur = __nstart; __cur < __nfinish; ++__cur) *__cur = _M_allocate_node(); } __STL_UNWIND(_M_destroy_nodes(__nstart, __cur)); } template void _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) { for (_Tp** __n = __nstart; __n < __nfinish; ++__n) _M_deallocate_node(*__n); } template class deque : protected _Deque_base<_Tp, _Alloc> { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); typedef _Deque_base<_Tp, _Alloc> _Base; public: // Basic types 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 typename _Base::allocator_type allocator_type; allocator_type get_allocator() const { return _Base::get_allocator(); } public: // Iterators typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: // Internal typedefs typedef pointer* _Map_pointer; static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); } protected: #ifdef __STL_USE_NAMESPACES 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_map; using _Base::_M_map_size; using _Base::_M_start; using _Base::_M_finish; #endif /* __STL_USE_NAMESPACES */ public: // Basic accessors iterator begin() { return _M_start; } iterator end() { return _M_finish; } const_iterator begin() const { return _M_start; } const_iterator end() const { return _M_finish; } reverse_iterator rbegin() { return reverse_iterator(_M_finish); } reverse_iterator rend() { return reverse_iterator(_M_start); } const_reverse_iterator rbegin() const { return const_reverse_iterator(_M_finish); } const_reverse_iterator rend() const { return const_reverse_iterator(_M_start); } reference operator[](size_type __n) { return _M_start[difference_type(__n)]; } const_reference operator[](size_type __n) const { return _M_start[difference_type(__n)]; } #ifdef __STL_THROW_RANGE_ERRORS void _M_range_check(size_type __n) const { if (__n >= this->size()) __stl_throw_range_error("deque"); } 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]; } #endif /* __STL_THROW_RANGE_ERRORS */ reference front() { return *_M_start; } reference back() { iterator __tmp = _M_finish; --__tmp; return *__tmp; } const_reference front() const { return *_M_start; } const_reference back() const { const_iterator __tmp = _M_finish; --__tmp; return *__tmp; } size_type size() const { return _M_finish - _M_start; } size_type max_size() const { return size_type(-1); } bool empty() const { return _M_finish == _M_start; } public: // Constructor, destructor. explicit deque(const allocator_type& __a = allocator_type()) : _Base(__a, 0) {} deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) { uninitialized_copy(__x.begin(), __x.end(), _M_start); } deque(size_type __n, const value_type& __value, const allocator_type& __a = allocator_type()) : _Base(__a, __n) { _M_fill_initialize(__value); } explicit deque(size_type __n) : _Base(allocator_type(), __n) { _M_fill_initialize(value_type()); } #ifdef __STL_MEMBER_TEMPLATES // Check whether it's an integral type. If so, it's not an iterator. template deque(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } template void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { _M_initialize_map(__n); _M_fill_initialize(__x); } template void _M_initialize_dispatch(_InputIter __first, _InputIter __last, __false_type) { _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ deque(const value_type* __first, const value_type* __last, const allocator_type& __a = allocator_type()) : _Base(__a, __last - __first) { uninitialized_copy(__first, __last, _M_start); } deque(const_iterator __first, const_iterator __last, const allocator_type& __a = allocator_type()) : _Base(__a, __last - __first) { uninitialized_copy(__first, __last, _M_start); } #endif /* __STL_MEMBER_TEMPLATES */ ~deque() { destroy(_M_start, _M_finish); } deque& operator= (const deque& __x) { const size_type __len = size(); if (&__x != this) { if (__len >= __x.size()) erase(copy(__x.begin(), __x.end(), _M_start), _M_finish); else { const_iterator __mid = __x.begin() + difference_type(__len); copy(__x.begin(), __mid, _M_start); insert(_M_finish, __mid, __x.end()); } } return *this; } void swap(deque& __x) { __STD::swap(_M_start, __x._M_start); __STD::swap(_M_finish, __x._M_finish); __STD::swap(_M_map, __x._M_map); __STD::swap(_M_map_size, __x._M_map_size); } 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 _M_fill_assign(size_type __n, const _Tp& __val) { if (__n > size()) { fill(begin(), end(), __val); insert(end(), __n - size(), __val); } else { erase(begin() + __n, end()); fill(begin(), end(), __val); } } void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); } #ifdef __STL_MEMBER_TEMPLATES template void assign(_InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_assign_dispatch(__first, __last, _Integral()); } private: // helper functions for assign() template void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign((size_type) __n, (_Tp) __val); } template void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } template void _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag); template void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { size_type __len = 0; distance(__first, __last, __len); if (__len > size()) { _ForwardIterator __mid = __first; advance(__mid, size()); copy(__first, __mid, begin()); insert(end(), __mid, __last); } else erase(copy(__first, __last, begin()), end()); } #endif /* __STL_MEMBER_TEMPLATES */ public: // push_* and pop_* void push_back(const value_type& __t) { if (_M_finish._M_cur != _M_finish._M_last - 1) { construct(_M_finish._M_cur, __t); ++_M_finish._M_cur; } else _M_push_back_aux(__t); } void push_back() { if (_M_finish._M_cur != _M_finish._M_last - 1) { construct(_M_finish._M_cur); ++_M_finish._M_cur; } else _M_push_back_aux(); } void push_front(const value_type& __t) { if (_M_start._M_cur != _M_start._M_first) { construct(_M_start._M_cur - 1, __t); --_M_start._M_cur; } else _M_push_front_aux(__t); } void push_front() { if (_M_start._M_cur != _M_start._M_first) { construct(_M_start._M_cur - 1); --_M_start._M_cur; } else _M_push_front_aux(); } void pop_back() { if (_M_finish._M_cur != _M_finish._M_first) { --_M_finish._M_cur; destroy(_M_finish._M_cur); } else _M_pop_back_aux(); } void pop_front() { if (_M_start._M_cur != _M_start._M_last - 1) { destroy(_M_start._M_cur); ++_M_start._M_cur; } else _M_pop_front_aux(); } public: // Insert iterator insert(iterator position, const value_type& __x) { if (position._M_cur == _M_start._M_cur) { push_front(__x); return _M_start; } else if (position._M_cur == _M_finish._M_cur) { push_back(__x); iterator __tmp = _M_finish; --__tmp; return __tmp; } else { return _M_insert_aux(position, __x); } } iterator insert(iterator __position) { return insert(__position, value_type()); } void insert(iterator __pos, size_type __n, const value_type& __x) { _M_fill_insert(__pos, __n, __x); } void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); #ifdef __STL_MEMBER_TEMPLATES // Check whether it's an integral type. If so, it's not an iterator. template void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_insert_dispatch(__pos, __first, __last, _Integral()); } template void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type) { _M_fill_insert(__pos, (size_type) __n, (value_type) __x); } template void _M_insert_dispatch(iterator __pos, _InputIterator __first, _InputIterator __last, __false_type) { insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator __pos, const value_type* __first, const value_type* __last); void insert(iterator __pos, const_iterator __first, const_iterator __last); #endif /* __STL_MEMBER_TEMPLATES */ void resize(size_type __new_size, const value_type& __x) { const size_type __len = size(); if (__new_size < __len) erase(_M_start + __new_size, _M_finish); else insert(_M_finish, __new_size - __len, __x); } void resize(size_type new_size) { resize(new_size, value_type()); } public: // Erase iterator erase(iterator __pos) { iterator __next = __pos; ++__next; difference_type __index = __pos - _M_start; if (size_type(__index) < (this->size() >> 1)) { copy_backward(_M_start, __pos, __next); pop_front(); } else { copy(__next, _M_finish, __pos); pop_back(); } return _M_start + __index; } iterator erase(iterator __first, iterator __last); void clear(); protected: // Internal construction/destruction void _M_fill_initialize(const value_type& __value); #ifdef __STL_MEMBER_TEMPLATES template void _M_range_initialize(_InputIterator __first, _InputIterator __last, input_iterator_tag); template void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ protected: // Internal push_* and pop_* void _M_push_back_aux(const value_type&); void _M_push_back_aux(); void _M_push_front_aux(const value_type&); void _M_push_front_aux(); void _M_pop_back_aux(); void _M_pop_front_aux(); protected: // Internal insert functions #ifdef __STL_MEMBER_TEMPLATES template void insert(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag); template void insert(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ iterator _M_insert_aux(iterator __pos, const value_type& __x); iterator _M_insert_aux(iterator __pos); void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); #ifdef __STL_MEMBER_TEMPLATES template void _M_insert_aux(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, size_type __n); #else /* __STL_MEMBER_TEMPLATES */ void _M_insert_aux(iterator __pos, const value_type* __first, const value_type* __last, size_type __n); void _M_insert_aux(iterator __pos, const_iterator __first, const_iterator __last, size_type __n); #endif /* __STL_MEMBER_TEMPLATES */ iterator _M_reserve_elements_at_front(size_type __n) { size_type __vacancies = _M_start._M_cur - _M_start._M_first; if (__n > __vacancies) _M_new_elements_at_front(__n - __vacancies); return _M_start - difference_type(__n); } iterator _M_reserve_elements_at_back(size_type __n) { size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1; if (__n > __vacancies) _M_new_elements_at_back(__n - __vacancies); return _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); protected: // Allocation of _M_map and nodes // 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.) void _M_reserve_map_at_back (size_type __nodes_to_add = 1) { if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _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(_M_start._M_node - _M_map)) _M_reallocate_map(__nodes_to_add, true); } void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); }; // Non-inline member functions #ifdef __STL_MEMBER_TEMPLATES template template void deque<_Tp, _Alloc> ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag) { iterator __cur = begin(); for ( ; __first != __last && __cur != end(); ++__cur, ++__first) *__cur = *__first; if (__first == __last) erase(__cur, end()); else insert(end(), __first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ template void deque<_Tp, _Alloc>::_M_fill_insert(iterator __pos, size_type __n, const value_type& __x) { if (__pos._M_cur == _M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { uninitialized_fill(__new_start, _M_start, __x); _M_start = __new_start; } __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else if (__pos._M_cur == _M_finish._M_cur) { iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { uninitialized_fill(_M_finish, __new_finish, __x); _M_finish = __new_finish; } __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1)); } else _M_insert_aux(__pos, __n, __x); } #ifndef __STL_MEMBER_TEMPLATES template void deque<_Tp, _Alloc>::insert(iterator __pos, const value_type* __first, const value_type* __last) { size_type __n = __last - __first; if (__pos._M_cur == _M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { uninitialized_copy(__first, __last, __new_start); _M_start = __new_start; } __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else if (__pos._M_cur == _M_finish._M_cur) { iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { uninitialized_copy(__first, __last, _M_finish); _M_finish = __new_finish; } __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1)); } else _M_insert_aux(__pos, __first, __last, __n); } template void deque<_Tp,_Alloc>::insert(iterator __pos, const_iterator __first, const_iterator __last) { size_type __n = __last - __first; if (__pos._M_cur == _M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { uninitialized_copy(__first, __last, __new_start); _M_start = __new_start; } __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else if (__pos._M_cur == _M_finish._M_cur) { iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { uninitialized_copy(__first, __last, _M_finish); _M_finish = __new_finish; } __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1)); } else _M_insert_aux(__pos, __first, __last, __n); } #endif /* __STL_MEMBER_TEMPLATES */ template typename deque<_Tp,_Alloc>::iterator deque<_Tp,_Alloc>::erase(iterator __first, iterator __last) { if (__first == _M_start && __last == _M_finish) { clear(); return _M_finish; } else { difference_type __n = __last - __first; difference_type __elems_before = __first - _M_start; if (__elems_before < difference_type((this->size() - __n) / 2)) { copy_backward(_M_start, __first, __last); iterator __new_start = _M_start + __n; destroy(_M_start, __new_start); _M_destroy_nodes(__new_start._M_node, _M_start._M_node); _M_start = __new_start; } else { copy(__last, _M_finish, __first); iterator __new_finish = _M_finish - __n; destroy(__new_finish, _M_finish); _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1); _M_finish = __new_finish; } return _M_start + __elems_before; } } template void deque<_Tp,_Alloc>::clear() { for (_Map_pointer __node = _M_start._M_node + 1; __node < _M_finish._M_node; ++__node) { destroy(*__node, *__node + _S_buffer_size()); _M_deallocate_node(*__node); } if (_M_start._M_node != _M_finish._M_node) { destroy(_M_start._M_cur, _M_start._M_last); destroy(_M_finish._M_first, _M_finish._M_cur); _M_deallocate_node(_M_finish._M_first); } else destroy(_M_start._M_cur, _M_finish._M_cur); _M_finish = _M_start; } // Precondition: _M_start and _M_finish have already been initialized, // but none of the deque's elements have yet been constructed. template void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value) { _Map_pointer __cur; __STL_TRY { for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur) uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value); } __STL_UNWIND(destroy(_M_start, iterator(*__cur, __cur))); } #ifdef __STL_MEMBER_TEMPLATES template template void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first, _InputIterator __last, input_iterator_tag) { _M_initialize_map(0); __STL_TRY { for ( ; __first != __last; ++__first) push_back(*__first); } __STL_UNWIND(clear()); } template template void deque<_Tp,_Alloc>::_M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { size_type __n = 0; distance(__first, __last, __n); _M_initialize_map(__n); _Map_pointer __cur_node; __STL_TRY { for (__cur_node = _M_start._M_node; __cur_node < _M_finish._M_node; ++__cur_node) { _ForwardIterator __mid = __first; advance(__mid, _S_buffer_size()); uninitialized_copy(__first, __mid, *__cur_node); __first = __mid; } uninitialized_copy(__first, __last, _M_finish._M_first); } __STL_UNWIND(destroy(_M_start, iterator(*__cur_node, __cur_node))); } #endif /* __STL_MEMBER_TEMPLATES */ // Called only if _M_finish._M_cur == _M_finish._M_last - 1. template void deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t) { value_type __t_copy = __t; _M_reserve_map_at_back(); *(_M_finish._M_node + 1) = _M_allocate_node(); __STL_TRY { construct(_M_finish._M_cur, __t_copy); _M_finish._M_set_node(_M_finish._M_node + 1); _M_finish._M_cur = _M_finish._M_first; } __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); } // Called only if _M_finish._M_cur == _M_finish._M_last - 1. template void deque<_Tp,_Alloc>::_M_push_back_aux() { _M_reserve_map_at_back(); *(_M_finish._M_node + 1) = _M_allocate_node(); __STL_TRY { construct(_M_finish._M_cur); _M_finish._M_set_node(_M_finish._M_node + 1); _M_finish._M_cur = _M_finish._M_first; } __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); } // Called only if _M_start._M_cur == _M_start._M_first. template void deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t) { value_type __t_copy = __t; _M_reserve_map_at_front(); *(_M_start._M_node - 1) = _M_allocate_node(); __STL_TRY { _M_start._M_set_node(_M_start._M_node - 1); _M_start._M_cur = _M_start._M_last - 1; construct(_M_start._M_cur, __t_copy); } __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); } // Called only if _M_start._M_cur == _M_start._M_first. template void deque<_Tp,_Alloc>::_M_push_front_aux() { _M_reserve_map_at_front(); *(_M_start._M_node - 1) = _M_allocate_node(); __STL_TRY { _M_start._M_set_node(_M_start._M_node - 1); _M_start._M_cur = _M_start._M_last - 1; construct(_M_start._M_cur); } __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); } // Called only if _M_finish._M_cur == _M_finish._M_first. template void deque<_Tp,_Alloc>::_M_pop_back_aux() { _M_deallocate_node(_M_finish._M_first); _M_finish._M_set_node(_M_finish._M_node - 1); _M_finish._M_cur = _M_finish._M_last - 1; destroy(_M_finish._M_cur); } // Called only if _M_start._M_cur == _M_start._M_last - 1. Note that // if the deque has at least one element (a precondition for this member // function), and if _M_start._M_cur == _M_start._M_last, then the deque // must have at least two nodes. template void deque<_Tp,_Alloc>::_M_pop_front_aux() { destroy(_M_start._M_cur); _M_deallocate_node(_M_start._M_first); _M_start._M_set_node(_M_start._M_node + 1); _M_start._M_cur = _M_start._M_first; } #ifdef __STL_MEMBER_TEMPLATES template template void deque<_Tp,_Alloc>::insert(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag) { copy(__first, __last, inserter(*this, __pos)); } template template void deque<_Tp,_Alloc>::insert(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { size_type __n = 0; distance(__first, __last, __n); if (__pos._M_cur == _M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { uninitialized_copy(__first, __last, __new_start); _M_start = __new_start; } __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else if (__pos._M_cur == _M_finish._M_cur) { iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { uninitialized_copy(__first, __last, _M_finish); _M_finish = __new_finish; } __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1)); } else _M_insert_aux(__pos, __first, __last, __n); } #endif /* __STL_MEMBER_TEMPLATES */ template typename deque<_Tp, _Alloc>::iterator deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x) { difference_type __index = __pos - _M_start; value_type __x_copy = __x; if (size_type(__index) < this->size() / 2) { push_front(front()); iterator __front1 = _M_start; ++__front1; iterator __front2 = __front1; ++__front2; __pos = _M_start + __index; iterator __pos1 = __pos; ++__pos1; copy(__front2, __pos1, __front1); } else { push_back(back()); iterator __back1 = _M_finish; --__back1; iterator __back2 = __back1; --__back2; __pos = _M_start + __index; copy_backward(__pos, __back2, __back1); } *__pos = __x_copy; return __pos; } template typename deque<_Tp,_Alloc>::iterator deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos) { difference_type __index = __pos - _M_start; if (__index < size() / 2) { push_front(front()); iterator __front1 = _M_start; ++__front1; iterator __front2 = __front1; ++__front2; __pos = _M_start + __index; iterator __pos1 = __pos; ++__pos1; copy(__front2, __pos1, __front1); } else { push_back(back()); iterator __back1 = _M_finish; --__back1; iterator __back2 = __back1; --__back2; __pos = _M_start + __index; copy_backward(__pos, __back2, __back1); } *__pos = value_type(); return __pos; } template void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, size_type __n, const value_type& __x) { const difference_type __elems_before = __pos - _M_start; 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 = _M_start; __pos = _M_start + __elems_before; __STL_TRY { if (__elems_before >= difference_type(__n)) { iterator __start_n = _M_start + difference_type(__n); uninitialized_copy(_M_start, __start_n, __new_start); _M_start = __new_start; copy(__start_n, __pos, __old_start); fill(__pos - difference_type(__n), __pos, __x_copy); } else { __uninitialized_copy_fill(_M_start, __pos, __new_start, _M_start, __x_copy); _M_start = __new_start; fill(__old_start, __pos, __x_copy); } } __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { iterator __new_finish = _M_reserve_elements_at_back(__n); iterator __old_finish = _M_finish; const difference_type __elems_after = difference_type(__length) - __elems_before; __pos = _M_finish - __elems_after; __STL_TRY { if (__elems_after > difference_type(__n)) { iterator __finish_n = _M_finish - difference_type(__n); uninitialized_copy(__finish_n, _M_finish, _M_finish); _M_finish = __new_finish; copy_backward(__pos, __finish_n, __old_finish); fill(__pos, __pos + difference_type(__n), __x_copy); } else { __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n), __x_copy, __pos, _M_finish); _M_finish = __new_finish; fill(__pos, __old_finish, __x_copy); } } __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1)); } } #ifdef __STL_MEMBER_TEMPLATES template template void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, size_type __n) { const difference_type __elemsbefore = __pos - _M_start; size_type __length = size(); if (__elemsbefore < __length / 2) { iterator __new_start = _M_reserve_elements_at_front(__n); iterator __old_start = _M_start; __pos = _M_start + __elemsbefore; __STL_TRY { if (__elemsbefore >= difference_type(__n)) { iterator __start_n = _M_start + difference_type(__n); uninitialized_copy(_M_start, __start_n, __new_start); _M_start = __new_start; copy(__start_n, __pos, __old_start); copy(__first, __last, __pos - difference_type(__n)); } else { _ForwardIterator __mid = __first; advance(__mid, difference_type(__n) - __elemsbefore); __uninitialized_copy_copy(_M_start, __pos, __first, __mid, __new_start); _M_start = __new_start; copy(__mid, __last, __old_start); } } __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { iterator __new_finish = _M_reserve_elements_at_back(__n); iterator __old_finish = _M_finish; const difference_type __elemsafter = difference_type(__length) - __elemsbefore; __pos = _M_finish - __elemsafter; __STL_TRY { if (__elemsafter > difference_type(__n)) { iterator __finish_n = _M_finish - difference_type(__n); uninitialized_copy(__finish_n, _M_finish, _M_finish); _M_finish = __new_finish; copy_backward(__pos, __finish_n, __old_finish); copy(__first, __last, __pos); } else { _ForwardIterator __mid = __first; advance(__mid, __elemsafter); __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); _M_finish = __new_finish; copy(__first, __mid, __pos); } } __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1)); } } #else /* __STL_MEMBER_TEMPLATES */ template void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type* __first, const value_type* __last, size_type __n) { const difference_type __elemsbefore = __pos - _M_start; size_type __length = size(); if (__elemsbefore < __length / 2) { iterator __new_start = _M_reserve_elements_at_front(__n); iterator __old_start = _M_start; __pos = _M_start + __elemsbefore; __STL_TRY { if (__elemsbefore >= difference_type(__n)) { iterator __start_n = _M_start + difference_type(__n); uninitialized_copy(_M_start, __start_n, __new_start); _M_start = __new_start; copy(__start_n, __pos, __old_start); copy(__first, __last, __pos - difference_type(__n)); } else { const value_type* __mid = __first + (difference_type(__n) - __elemsbefore); __uninitialized_copy_copy(_M_start, __pos, __first, __mid, __new_start); _M_start = __new_start; copy(__mid, __last, __old_start); } } __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { iterator __new_finish = _M_reserve_elements_at_back(__n); iterator __old_finish = _M_finish; const difference_type __elemsafter = difference_type(__length) - __elemsbefore; __pos = _M_finish - __elemsafter; __STL_TRY { if (__elemsafter > difference_type(__n)) { iterator __finish_n = _M_finish - difference_type(__n); uninitialized_copy(__finish_n, _M_finish, _M_finish); _M_finish = __new_finish; copy_backward(__pos, __finish_n, __old_finish); copy(__first, __last, __pos); } else { const value_type* __mid = __first + __elemsafter; __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); _M_finish = __new_finish; copy(__first, __mid, __pos); } } __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1)); } } template void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const_iterator __first, const_iterator __last, size_type __n) { const difference_type __elemsbefore = __pos - _M_start; size_type __length = size(); if (__elemsbefore < __length / 2) { iterator __new_start = _M_reserve_elements_at_front(__n); iterator __old_start = _M_start; __pos = _M_start + __elemsbefore; __STL_TRY { if (__elemsbefore >= __n) { iterator __start_n = _M_start + __n; uninitialized_copy(_M_start, __start_n, __new_start); _M_start = __new_start; copy(__start_n, __pos, __old_start); copy(__first, __last, __pos - difference_type(__n)); } else { const_iterator __mid = __first + (__n - __elemsbefore); __uninitialized_copy_copy(_M_start, __pos, __first, __mid, __new_start); _M_start = __new_start; copy(__mid, __last, __old_start); } } __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { iterator __new_finish = _M_reserve_elements_at_back(__n); iterator __old_finish = _M_finish; const difference_type __elemsafter = __length - __elemsbefore; __pos = _M_finish - __elemsafter; __STL_TRY { if (__elemsafter > __n) { iterator __finish_n = _M_finish - difference_type(__n); uninitialized_copy(__finish_n, _M_finish, _M_finish); _M_finish = __new_finish; copy_backward(__pos, __finish_n, __old_finish); copy(__first, __last, __pos); } else { const_iterator __mid = __first + __elemsafter; __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); _M_finish = __new_finish; copy(__first, __mid, __pos); } } __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1)); } } #endif /* __STL_MEMBER_TEMPLATES */ template void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems) { size_type __new_nodes = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); _M_reserve_map_at_front(__new_nodes); size_type __i; __STL_TRY { for (__i = 1; __i <= __new_nodes; ++__i) *(_M_start._M_node - __i) = _M_allocate_node(); } # ifdef __STL_USE_EXCEPTIONS catch(...) { for (size_type __j = 1; __j < __i; ++__j) _M_deallocate_node(*(_M_start._M_node - __j)); throw; } # endif /* __STL_USE_EXCEPTIONS */ } template void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems) { size_type __new_nodes = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); _M_reserve_map_at_back(__new_nodes); size_type __i; __STL_TRY { for (__i = 1; __i <= __new_nodes; ++__i) *(_M_finish._M_node + __i) = _M_allocate_node(); } # ifdef __STL_USE_EXCEPTIONS catch(...) { for (size_type __j = 1; __j < __i; ++__j) _M_deallocate_node(*(_M_finish._M_node + __j)); throw; } # endif /* __STL_USE_EXCEPTIONS */ } template void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) { size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1; size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; _Map_pointer __new_nstart; if (_M_map_size > 2 * __new_num_nodes) { __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 + (__add_at_front ? __nodes_to_add : 0); if (__new_nstart < _M_start._M_node) copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); else copy_backward(_M_start._M_node, _M_finish._M_node + 1, __new_nstart + __old_num_nodes); } else { size_type __new_map_size = _M_map_size + max(_M_map_size, __nodes_to_add) + 2; _Map_pointer __new_map = _M_allocate_map(__new_map_size); __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + (__add_at_front ? __nodes_to_add : 0); copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); _M_deallocate_map(_M_map, _M_map_size); _M_map = __new_map; _M_map_size = __new_map_size; } _M_start._M_set_node(__new_nstart); _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } // Nonmember functions. template inline bool operator==(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return __x.size() == __y.size() && equal(__x.begin(), __x.end(), __y.begin()); } template inline bool operator<(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return !(__x == __y); } template inline bool operator>(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return __y < __x; } template inline bool operator<=(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return !(__y < __x); } template inline bool operator>=(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return !(__x < __y); } template inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_DEQUE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_exception.h ================================================ /* * 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. */ #ifndef __SGI_STL_EXCEPTION_H #define __SGI_STL_EXCEPTION_H // This header exists solely for portability. Normally it just includes // the header . // The header contains low-level functions that interact // with a compiler's exception-handling mechanism. It is assumed to // be supplied with the compiler, rather than with the library, because // it is inherently tied very closely to the compiler itself. // On platforms where does not exist, this header defines // an exception base class. This is *not* a substitute for everything // in , but it suffices to support a bare minimum of STL // functionality. #include #ifndef __STL_NO_EXCEPTION_HEADER #include #define __STL_EXCEPTION_BASE exception #else /* __STL_NO_EXCEPTION_HEADER */ __STL_BEGIN_NAMESPACE class _Exception { public: virtual ~_Exception() __STL_NOTHROW {} virtual const char* what() const __STL_NOTHROW { return ""; } }; #define __STL_EXCEPTION_BASE _Exception __STL_END_NAMESPACE #endif /* __STL_NO_EXCEPTION_HEADER */ #endif /* __SGI_STL_EXCEPTION_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_function.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_FUNCTION_H #define __SGI_STL_INTERNAL_FUNCTION_H __STL_BEGIN_NAMESPACE template struct unary_function { typedef _Arg argument_type; typedef _Result result_type; }; template struct binary_function { typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; }; template struct plus : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } }; template struct minus : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } }; template struct multiplies : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } }; template struct divides : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } }; // identity_element (not part of the C++ standard). template inline _Tp identity_element(plus<_Tp>) { return _Tp(0); } template inline _Tp identity_element(multiplies<_Tp>) { return _Tp(1); } template struct modulus : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } }; template struct negate : public unary_function<_Tp,_Tp> { _Tp operator()(const _Tp& __x) const { return -__x; } }; template struct equal_to : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } }; template struct not_equal_to : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } }; template struct greater : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; template struct less : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; template struct greater_equal : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } }; template struct less_equal : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } }; template struct logical_and : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } }; template struct logical_or : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } }; template struct logical_not : public unary_function<_Tp,bool> { bool operator()(const _Tp& __x) const { return !__x; } }; template class unary_negate : public unary_function { 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); } }; template inline unary_negate<_Predicate> not1(const _Predicate& __pred) { return unary_negate<_Predicate>(__pred); } template class binary_negate : public binary_function { 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); } }; template inline binary_negate<_Predicate> not2(const _Predicate& __pred) { return binary_negate<_Predicate>(__pred); } template class binder1st : public unary_function { 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); } }; template 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)); } template class binder2nd : public unary_function { 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); } }; template 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)); } // unary_compose and binary_compose (extensions, not part of the standard). template class unary_compose : public unary_function { 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)); } }; template inline unary_compose<_Operation1,_Operation2> compose1(const _Operation1& __fn1, const _Operation2& __fn2) { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); } template class binary_compose : public unary_function { 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)); } }; template 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); } template 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); } }; template inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) { return pointer_to_unary_function<_Arg, _Result>(__x); } template 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); } }; template inline pointer_to_binary_function<_Arg1,_Arg2,_Result> ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__x); } // identity is an extensions: it is not part of the standard. template struct _Identity : public unary_function<_Tp,_Tp> { const _Tp& operator()(const _Tp& __x) const { return __x; } }; template struct identity : public _Identity<_Tp> {}; // select1st and select2nd are extensions: they are not part of the standard. template struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { const typename _Pair::first_type& operator()(const _Pair& __x) const { return __x.first; } }; template struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> { const typename _Pair::second_type& operator()(const _Pair& __x) const { return __x.second; } }; template struct select1st : public _Select1st<_Pair> {}; template struct select2nd : public _Select2nd<_Pair> {}; // project1st and project2nd are extensions: they are not part of the standard template struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } }; template struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } }; template struct project1st : public _Project1st<_Arg1, _Arg2> {}; template struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; // constant_void_fun, constant_unary_fun, and constant_binary_fun are // extensions: they are not part of the standard. (The same, of course, // is true of the helper functions constant0, constant1, and constant2.) template 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 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 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; } }; template struct constant_void_fun : public _Constant_void_fun<_Result> { constant_void_fun(const _Result& __v) : _Constant_void_fun<_Result>(__v) {} }; template struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> { constant_unary_fun(const _Result& __v) : _Constant_unary_fun<_Result, _Argument>(__v) {} }; template struct constant_binary_fun : public _Constant_binary_fun<_Result, _Arg1, _Arg2> { constant_binary_fun(const _Result& __v) : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} }; template inline constant_void_fun<_Result> constant0(const _Result& __val) { return constant_void_fun<_Result>(__val); } template inline constant_unary_fun<_Result,_Result> constant1(const _Result& __val) { return constant_unary_fun<_Result,_Result>(__val); } template inline constant_binary_fun<_Result,_Result,_Result> constant2(const _Result& __val) { return constant_binary_fun<_Result,_Result,_Result>(__val); } // subtractive_rng is an extension: it is not part of the standard. // Note: this code assumes that int is 32 bits. class subtractive_rng : public unary_function { private: unsigned int _M_table[55]; size_t _M_index1; size_t _M_index2; public: 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; } subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } subtractive_rng() { _M_initialize(161803398u); } }; // Adaptor function objects: pointers to member functions. // There are a total of 16 = 2^4 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) Member function with void return type vs member function with // non-void return type. // (4) Const vs non-const member function. // Note that choice (3) is nothing more than a workaround: according // to the draft, compilers should handle void and non-void the same way. // This feature is not yet widely implemented, though. You can only use // member functions returning void if your compiler supports partial // specialization. // 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. // (mem_fun1 and mem_fun1_ref are no longer part of the C++ standard, // but they are provided for backward compatibility.) template 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)(); }; template class const_mem_fun_t : public unary_function { 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; }; template 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)(); }; template 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; }; template 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); }; template class const_mem_fun1_t : public binary_function { 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; }; template 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); }; template 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; }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template class mem_fun_t : public unary_function<_Tp*,void> { public: explicit mem_fun_t(void (_Tp::*__pf)()) : _M_f(__pf) {} void operator()(_Tp* __p) const { (__p->*_M_f)(); } private: void (_Tp::*_M_f)(); }; template class const_mem_fun_t : public unary_function { public: explicit const_mem_fun_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} void operator()(const _Tp* __p) const { (__p->*_M_f)(); } private: void (_Tp::*_M_f)() const; }; template class mem_fun_ref_t : public unary_function<_Tp,void> { public: explicit mem_fun_ref_t(void (_Tp::*__pf)()) : _M_f(__pf) {} void operator()(_Tp& __r) const { (__r.*_M_f)(); } private: void (_Tp::*_M_f)(); }; template class const_mem_fun_ref_t : public unary_function<_Tp,void> { public: explicit const_mem_fun_ref_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} void operator()(const _Tp& __r) const { (__r.*_M_f)(); } private: void (_Tp::*_M_f)() const; }; template class mem_fun1_t : public binary_function<_Tp*,_Arg,void> { public: explicit mem_fun1_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} void operator()(_Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } private: void (_Tp::*_M_f)(_Arg); }; template class const_mem_fun1_t : public binary_function { public: explicit const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} void operator()(const _Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } private: void (_Tp::*_M_f)(_Arg) const; }; template class mem_fun1_ref_t : public binary_function<_Tp,_Arg,void> { public: explicit mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} void operator()(_Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } private: void (_Tp::*_M_f)(_Arg); }; template class const_mem_fun1_ref_t : public binary_function<_Tp,_Arg,void> { public: explicit const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} void operator()(const _Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } private: void (_Tp::*_M_f)(_Arg) const; }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // Mem_fun adaptor helper functions. There are only two: // mem_fun and mem_fun_ref. (mem_fun1 and mem_fun1_ref // are provided for backward compatibility, but they are no longer // part of the C++ standard.) template inline mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)()) { return mem_fun_t<_Ret,_Tp>(__f); } template inline const_mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)() const) { return const_mem_fun_t<_Ret,_Tp>(__f); } template inline mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)()) { return mem_fun_ref_t<_Ret,_Tp>(__f); } template 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 inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } template 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 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 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); } template inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } template 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 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 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); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_FUNCTION_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_hash_fun.h ================================================ /* * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_HASH_FUN_H #define __SGI_STL_HASH_FUN_H #include __STL_BEGIN_NAMESPACE template 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); } __STL_TEMPLATE_NULL struct hash { size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(short __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned short __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(int __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned int __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(long __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned long __x) const { return __x; } }; __STL_END_NAMESPACE #endif /* __SGI_STL_HASH_FUN_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_hash_map.h ================================================ /* * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_HASH_MAP_H #define __SGI_STL_INTERNAL_HASH_MAP_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // Forward declaration of equality operator; needed for friend declaration. template ), class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Key>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > class hash_map; template inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&, const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&); template class hash_map { // requirements: __STL_CLASS_REQUIRES(_Key, _Assignable); __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Key); __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Key, _Key); private: typedef hashtable,_Key,_HashFcn, _Select1st >,_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) {} #ifdef __STL_MEMBER_TEMPLATES template hash_map(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_map(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template 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 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); } #else hash_map(const value_type* __f, const value_type* __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const value_type* __f, const value_type* __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const value_type* __f, const value_type* __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); } hash_map(const_iterator __f, const_iterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const_iterator __f, const_iterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_map(const_iterator __f, const_iterator __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); } #endif /*__STL_MEMBER_TEMPLATES */ 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); } #ifdef __STL_MEMBER_TEMPLATES template friend bool operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, const hash_map<_K1, _T1, _HF, _EqK, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); #endif /* __STL_MEMBER_TEMPLATES */ 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 insert(const value_type& __obj) { return _M_ht.insert_unique(__obj); } #ifdef __STL_MEMBER_TEMPLATES template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f,__l); } #else void insert(const value_type* __f, const value_type* __l) { _M_ht.insert_unique(__f,__l); } void insert(const_iterator __f, const_iterator __l) { _M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ pair 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 equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair 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 inline bool operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { return __hm1._M_ht == __hm2._M_ht; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { return !(__hm1 == __hm2); } template inline void swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { __hm1.swap(__hm2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Forward declaration of equality operator; needed for friend declaration. template ), class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Key>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > class hash_multimap; template inline bool operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2); template class hash_multimap { // requirements: __STL_CLASS_REQUIRES(_Key, _Assignable); __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Key); __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Key, _Key); private: typedef hashtable, _Key, _HashFcn, _Select1st >, _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) {} #ifdef __STL_MEMBER_TEMPLATES template hash_multimap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template 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 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); } #else hash_multimap(const value_type* __f, const value_type* __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const value_type* __f, const value_type* __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const value_type* __f, const value_type* __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); } hash_multimap(const_iterator __f, const_iterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const_iterator __f, const_iterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multimap(const_iterator __f, const_iterator __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); } #endif /*__STL_MEMBER_TEMPLATES */ 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); } #ifdef __STL_MEMBER_TEMPLATES template friend bool operator== (const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hash_multimap&,const hash_multimap&); #endif /* __STL_MEMBER_TEMPLATES */ 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); } #ifdef __STL_MEMBER_TEMPLATES template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } #else void insert(const value_type* __f, const value_type* __l) { _M_ht.insert_equal(__f,__l); } void insert(const_iterator __f, const_iterator __l) { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ 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 equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair 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 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; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template 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 inline void swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { __hm1.swap(__hm2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Specialization of insert_iterator so that it will work for hash_map // and hash_multimap. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template class insert_iterator > { protected: typedef 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 insert_iterator > { protected: typedef 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; } }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HASH_MAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_hash_set.h ================================================ /* * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_HASH_SET_H #define __SGI_STL_INTERNAL_HASH_SET_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // Forward declaration of equality operator; needed for friend declaration. template ), class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Value>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > class hash_set; template inline bool operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2); template class hash_set { // requirements: __STL_CLASS_REQUIRES(_Value, _Assignable); __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Value); __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Value, _Value); 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 _Ht::const_pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::const_reference reference; typedef typename _Ht::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) {} #ifdef __STL_MEMBER_TEMPLATES template hash_set(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template 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 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); } #else hash_set(const value_type* __f, const value_type* __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const value_type* __f, const value_type* __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const value_type* __f, const value_type* __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); } hash_set(const_iterator __f, const_iterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const_iterator __f, const_iterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } hash_set(const_iterator __f, const_iterator __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); } #endif /*__STL_MEMBER_TEMPLATES */ 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); } #ifdef __STL_MEMBER_TEMPLATES template friend bool operator== (const hash_set<_Val, _HF, _EqK, _Al>&, const hash_set<_Val, _HF, _EqK, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hash_set&, const hash_set&); #endif /* __STL_MEMBER_TEMPLATES */ iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } public: pair insert(const value_type& __obj) { pair __p = _M_ht.insert_unique(__obj); return pair(__p.first, __p.second); } #ifdef __STL_MEMBER_TEMPLATES template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f,__l); } #else void insert(const value_type* __f, const value_type* __l) { _M_ht.insert_unique(__f,__l); } void insert(const_iterator __f, const_iterator __l) {_M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ pair insert_noresize(const value_type& __obj) { pair __p = _M_ht.insert_unique_noresize(__obj); return pair(__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 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 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; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { __hs1.swap(__hs2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template ), class _EqualKey __STL_DEPENDENT_DEFAULT_TMPL(equal_to<_Value>), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > class hash_multiset; template inline bool operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2); template class hash_multiset { // requirements: __STL_CLASS_REQUIRES(_Value, _Assignable); __STL_CLASS_UNARY_FUNCTION_CHECK(_HashFcn, size_t, _Value); __STL_CLASS_BINARY_FUNCTION_CHECK(_EqualKey, bool, _Value, _Value); 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 _Ht::const_pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::const_reference reference; typedef typename _Ht::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) {} #ifdef __STL_MEMBER_TEMPLATES template hash_multiset(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template 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 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); } #else hash_multiset(const value_type* __f, const value_type* __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const value_type* __f, const value_type* __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const value_type* __f, const value_type* __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const value_type* __f, const value_type* __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); } hash_multiset(const_iterator __f, const_iterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const_iterator __f, const_iterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const_iterator __f, const_iterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } hash_multiset(const_iterator __f, const_iterator __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); } #endif /*__STL_MEMBER_TEMPLATES */ 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); } #ifdef __STL_MEMBER_TEMPLATES template friend bool operator== (const hash_multiset<_Val, _HF, _EqK, _Al>&, const hash_multiset<_Val, _HF, _EqK, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hash_multiset&,const hash_multiset&); #endif /* __STL_MEMBER_TEMPLATES */ 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); } #ifdef __STL_MEMBER_TEMPLATES template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } #else void insert(const value_type* __f, const value_type* __l) { _M_ht.insert_equal(__f,__l); } void insert(const_iterator __f, const_iterator __l) { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ 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 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 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; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { __hs1.swap(__hs2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Specialization of insert_iterator so that it will work for hash_set // and hash_multiset. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template class insert_iterator > { protected: typedef 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 insert_iterator > { protected: typedef 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; } }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HASH_SET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_hashtable.h ================================================ /* * 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 __SGI_STL_INTERNAL_HASHTABLE_H #define __SGI_STL_INTERNAL_HASHTABLE_H // Hashtable class, used to implement the hashed associative containers // hash_set, hash_map, hash_multiset, and hash_multimap. #include #include #include #include #include #include #include #include #include __STL_BEGIN_NAMESPACE template struct _Hashtable_node { _Hashtable_node* _M_next; _Val _M_val; }; template class hashtable; template struct _Hashtable_iterator; template struct _Hashtable_const_iterator; template 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; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_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 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; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_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 { __stl_num_primes = 28 }; static const unsigned long __stl_prime_list[__stl_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)__stl_num_primes; const unsigned long* pos = lower_bound(__first, __last, __n); return pos == __last ? *(__last - 1) : *pos; } // Forward declaration of operator==. template class hashtable; template 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 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; #ifdef __STL_USE_STD_ALLOCATORS public: typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_node_allocator; } private: typename _Alloc_traits<_Node, _Alloc>::allocator_type _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); } # define __HASH_ALLOC_INIT(__a) _M_node_allocator(__a), #else /* __STL_USE_STD_ALLOCATORS */ public: typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(); } private: typedef simple_alloc<_Node, _Alloc> _M_node_allocator_type; _Node* _M_get_node() { return _M_node_allocator_type::allocate(1); } void _M_put_node(_Node* __p) { _M_node_allocator_type::deallocate(__p, 1); } # define __HASH_ALLOC_INIT(__a) #endif /* __STL_USE_STD_ALLOCATORS */ private: hasher _M_hash; key_equal _M_equals; _ExtractKey _M_get_key; vector<_Node*,_Alloc> _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()) : __HASH_ALLOC_INIT(__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()) : __HASH_ALLOC_INIT(__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) : __HASH_ALLOC_INIT(__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); } #undef __HASH_ALLOC_INIT 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); } #ifdef __STL_MEMBER_TEMPLATES template friend bool operator== (const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const hashtable&, const hashtable&); #endif /* __STL_MEMBER_TEMPLATES */ public: size_type bucket_count() const { return _M_buckets.size(); } size_type max_bucket_count() const { return __stl_prime_list[(int)__stl_num_primes - 1]; } size_type elems_in_bucket(size_type __bucket) const { size_type __result = 0; for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) __result += 1; return __result; } pair 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 insert_unique_noresize(const value_type& __obj); iterator insert_equal_noresize(const value_type& __obj); #ifdef __STL_MEMBER_TEMPLATES template void insert_unique(_InputIterator __f, _InputIterator __l) { insert_unique(__f, __l, __ITERATOR_CATEGORY(__f)); } template void insert_equal(_InputIterator __f, _InputIterator __l) { insert_equal(__f, __l, __ITERATOR_CATEGORY(__f)); } template void insert_unique(_InputIterator __f, _InputIterator __l, input_iterator_tag) { for ( ; __f != __l; ++__f) insert_unique(*__f); } template void insert_equal(_InputIterator __f, _InputIterator __l, input_iterator_tag) { for ( ; __f != __l; ++__f) insert_equal(*__f); } template void insert_unique(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { size_type __n = 0; distance(__f, __l, __n); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_unique_noresize(*__f); } template void insert_equal(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { size_type __n = 0; distance(__f, __l, __n); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_equal_noresize(*__f); } #else /* __STL_MEMBER_TEMPLATES */ void insert_unique(const value_type* __f, const value_type* __l) { size_type __n = __l - __f; resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_unique_noresize(*__f); } void insert_equal(const value_type* __f, const value_type* __l) { size_type __n = __l - __f; resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_equal_noresize(*__f); } void insert_unique(const_iterator __f, const_iterator __l) { size_type __n = 0; distance(__f, __l, __n); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_unique_noresize(*__f); } void insert_equal(const_iterator __f, const_iterator __l) { size_type __n = 0; distance(__f, __l, __n); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_equal_noresize(*__f); } #endif /*__STL_MEMBER_TEMPLATES */ 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 equal_range(const key_type& __key); pair 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; __STL_TRY { construct(&__n->_M_val, __obj); return __n; } __STL_UNWIND(_M_put_node(__n)); } void _M_delete_node(_Node* __n) { 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 _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 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 _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 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; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline forward_iterator_tag iterator_category(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return forward_iterator_tag(); } template inline _Val* value_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return (_Val*) 0; } template inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* distance_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; } template inline forward_iterator_tag iterator_category(const _Hashtable_const_iterator<_Val,_Key,_HF, _ExK,_EqK,_All>&) { return forward_iterator_tag(); } template inline _Val* value_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return (_Val*) 0; } template inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* distance_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template 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 (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) { _Node* __cur1 = __ht1._M_buckets[__n]; _Node* __cur2 = __ht2._M_buckets[__n]; for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val; __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) {} if (__cur1 || __cur2) return false; } return true; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template 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 inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { __ht1.swap(__ht2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template pair::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(__cur, this), false); _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return pair(iterator(__tmp, this), true); } template 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 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 pair::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 _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 pair::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 _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 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 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 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 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(__first._M_ht)), iterator(const_cast<_Node*>(__last._M_cur), const_cast(__last._M_ht))); } template inline void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) { erase(iterator(const_cast<_Node*>(__it._M_cur), const_cast(__it._M_ht))); } template 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<_Node*, _All> __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); __STL_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); } # ifdef __STL_USE_EXCEPTIONS 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; } # endif /* __STL_USE_EXCEPTIONS */ } } } template 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 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 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 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); __STL_TRY { for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { const _Node* __cur = __ht._M_buckets[__i]; if (__cur) { _Node* __copy = _M_new_node(__cur->_M_val); _M_buckets[__i] = __copy; for (_Node* __next = __cur->_M_next; __next; __cur = __next, __next = __cur->_M_next) { __copy->_M_next = _M_new_node(__next->_M_val); __copy = __copy->_M_next; } } } _M_num_elements = __ht._M_num_elements; } __STL_UNWIND(clear()); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HASHTABLE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_heap.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_HEAP_H #define __SGI_STL_INTERNAL_HEAP_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1209 #endif // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. template 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; } template inline void __push_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance*, _Tp*) { __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), _Tp(*(__last - 1))); } template inline void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, _LessThanComparable); __push_heap_aux(__first, __last, __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); } template 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; } template inline void __push_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _Distance*, _Tp*) { __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), _Tp(*(__last - 1)), __comp); } template inline void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); __push_heap_aux(__first, __last, __comp, __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); } template void __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, _Distance __len, _Tp __value) { _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; } __push_heap(__first, __holeIndex, __topIndex, __value); } template inline void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __result, _Tp __value, _Distance*) { *__result = *__first; __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value); } template inline void __pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, _Tp*) { __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __DISTANCE_TYPE(__first)); } template inline void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, _LessThanComparable); __pop_heap_aux(__first, __last, __VALUE_TYPE(__first)); } template void __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, _Distance __len, _Tp __value, _Compare __comp) { _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; } __push_heap(__first, __holeIndex, __topIndex, __value, __comp); } template inline void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __result, _Tp __value, _Compare __comp, _Distance*) { *__result = *__first; __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value, __comp); } template inline void __pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, _Tp*, _Compare __comp) { __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp, __DISTANCE_TYPE(__first)); } template inline void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); __pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp); } template void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Tp*, _Distance*) { if (__last - __first < 2) return; _Distance __len = __last - __first; _Distance __parent = (__len - 2)/2; while (true) { __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent))); if (__parent == 0) return; __parent--; } } template inline void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, _LessThanComparable); __make_heap(__first, __last, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } template void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _Tp*, _Distance*) { if (__last - __first < 2) return; _Distance __len = __last - __first; _Distance __parent = (__len - 2)/2; while (true) { __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)), __comp); if (__parent == 0) return; __parent--; } } template inline void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); __make_heap(__first, __last, __comp, __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } template void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); __STL_REQUIRES(typename iterator_traits<_RandomAccessIterator>::value_type, _LessThanComparable); while (__last - __first > 1) pop_heap(__first, __last--); } template void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { __STL_REQUIRES(_RandomAccessIterator, _Mutable_RandomAccessIterator); while (__last - __first > 1) pop_heap(__first, __last--, __comp); } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1209 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HEAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_iterator.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ITERATOR_H #define __SGI_STL_INTERNAL_ITERATOR_H __STL_BEGIN_NAMESPACE template class back_insert_iterator { protected: _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; explicit back_insert_iterator(_Container& __x) : container(&__x) {} back_insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->push_back(__value); return *this; } back_insert_iterator<_Container>& operator*() { return *this; } back_insert_iterator<_Container>& operator++() { return *this; } back_insert_iterator<_Container>& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const back_insert_iterator<_Container>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline back_insert_iterator<_Container> back_inserter(_Container& __x) { return back_insert_iterator<_Container>(__x); } template class front_insert_iterator { protected: _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; explicit front_insert_iterator(_Container& __x) : container(&__x) {} front_insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->push_front(__value); return *this; } front_insert_iterator<_Container>& operator*() { return *this; } front_insert_iterator<_Container>& operator++() { return *this; } front_insert_iterator<_Container>& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const front_insert_iterator<_Container>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline front_insert_iterator<_Container> front_inserter(_Container& __x) { return front_insert_iterator<_Container>(__x); } template class insert_iterator { protected: _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), iter(__i) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { iter = container->insert(iter, __value); ++iter; return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const insert_iterator<_Container>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) { typedef typename _Container::iterator __iter; return insert_iterator<_Container>(__x, __iter(__i)); } #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template #else template #endif class reverse_bidirectional_iterator { typedef reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, _Reference, _Distance> _Self; protected: _BidirectionalIterator current; public: typedef bidirectional_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Reference reference; reverse_bidirectional_iterator() {} explicit reverse_bidirectional_iterator(_BidirectionalIterator __x) : current(__x) {} _BidirectionalIterator base() const { return current; } _Reference operator*() const { _BidirectionalIterator __tmp = current; return *--__tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ _Self& operator++() { --current; return *this; } _Self operator++(int) { _Self __tmp = *this; --current; return __tmp; } _Self& operator--() { ++current; return *this; } _Self operator--(int) { _Self __tmp = *this; ++current; return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline bidirectional_iterator_tag iterator_category(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, _Reference, _Distance>&) { return bidirectional_iterator_tag(); } template inline _Tp* value_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, _Reference, _Distance>&) { return (_Tp*) 0; } template inline _Distance* distance_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, _Reference, _Distance>&) { return (_Distance*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline bool operator==( const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y) { return __x.base() == __y.base(); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=( const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y) { return !(__x == __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION // This is the new version of reverse_iterator, as defined in the // draft C++ standard. It relies on the iterator_traits template, // which in turn relies on partial specialization. The class // reverse_bidirectional_iterator is no longer part of the draft // standard, but it is retained for backward compatibility. template class reverse_iterator { protected: _Iterator 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>::pointer pointer; typedef typename iterator_traits<_Iterator>::reference reference; typedef _Iterator iterator_type; typedef reverse_iterator<_Iterator> _Self; public: reverse_iterator() {} explicit reverse_iterator(iterator_type __x) : current(__x) {} reverse_iterator(const _Self& __x) : current(__x.current) {} #ifdef __STL_MEMBER_TEMPLATES template reverse_iterator(const reverse_iterator<_Iter>& __x) : current(__x.base()) {} #endif /* __STL_MEMBER_TEMPLATES */ iterator_type base() const { return current; } reference operator*() const { _Iterator __tmp = current; return *--__tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ _Self& operator++() { --current; return *this; } _Self operator++(int) { _Self __tmp = *this; --current; return __tmp; } _Self& operator--() { ++current; return *this; } _Self operator--(int) { _Self __tmp = *this; ++current; return __tmp; } _Self operator+(difference_type __n) const { return _Self(current - __n); } _Self& operator+=(difference_type __n) { current -= __n; return *this; } _Self operator-(difference_type __n) const { return _Self(current + __n); } _Self& operator-=(difference_type __n) { current += __n; return *this; } reference operator[](difference_type __n) const { return *(*this + __n); } }; template inline bool operator==(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __x.base() == __y.base(); } template inline bool operator<(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y.base() < __x.base(); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__x == __y); } template inline bool operator>(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y < __x; } template inline bool operator<=(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__y < __x); } template inline bool operator>=(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__x < __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template inline typename reverse_iterator<_Iterator>::difference_type operator-(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y.base() - __x.base(); } template inline reverse_iterator<_Iterator> operator+(typename reverse_iterator<_Iterator>::difference_type __n, const reverse_iterator<_Iterator>& __x) { return reverse_iterator<_Iterator>(__x.base() - __n); } #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // This is the old version of reverse_iterator, as found in the original // HP STL. It does not use partial specialization. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template #else template #endif class reverse_iterator { typedef reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance> _Self; protected: _RandomAccessIterator current; public: typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Reference reference; reverse_iterator() {} explicit reverse_iterator(_RandomAccessIterator __x) : current(__x) {} _RandomAccessIterator base() const { return current; } _Reference operator*() const { return *(current - 1); } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ _Self& operator++() { --current; return *this; } _Self operator++(int) { _Self __tmp = *this; --current; return __tmp; } _Self& operator--() { ++current; return *this; } _Self operator--(int) { _Self __tmp = *this; ++current; return __tmp; } _Self operator+(_Distance __n) const { return _Self(current - __n); } _Self& operator+=(_Distance __n) { current -= __n; return *this; } _Self operator-(_Distance __n) const { return _Self(current + __n); } _Self& operator-=(_Distance __n) { current += __n; return *this; } _Reference operator[](_Distance __n) const { return *(*this + __n); } }; template inline random_access_iterator_tag iterator_category(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>&) { return random_access_iterator_tag(); } template inline _Tp* value_type(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>&) { return (_Tp*) 0; } template inline _Distance* distance_type(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>&) { return (_Distance*) 0; } template inline bool operator==(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __x, const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __y) { return __x.base() == __y.base(); } template inline bool operator<(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __x, const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __y) { return __y.base() < __x.base(); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __x, const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __y) { return !(__x == __y); } template inline bool operator>(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __x, const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __y) { return __y < __x; } template inline bool operator<=(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __x, const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __y) { return !(__y < __x); } template inline bool operator>=(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __x, const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __y) { return !(__x < __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template inline _Distance operator-(const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __x, const reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>& __y) { return __y.base() - __x.base(); } template inline reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist> operator+(_Dist __n, const reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>& __x) { return reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>(__x.base() - __n); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // istream_iterator and ostream_iterator look very different if we're // using new, templatized iostreams than if we're using the old cfront // version. #ifdef __STL_USE_NEW_IOSTREAMS template , class _Dist = ptrdiff_t> class istream_iterator { public: typedef _CharT char_type; typedef _Traits traits_type; typedef basic_istream<_CharT, _Traits> istream_type; typedef input_iterator_tag iterator_category; typedef _Tp value_type; typedef _Dist difference_type; typedef const _Tp* pointer; typedef const _Tp& reference; istream_iterator() : _M_stream(0), _M_ok(false) {} istream_iterator(istream_type& __s) : _M_stream(&__s) { _M_read(); } reference operator*() const { return _M_value; } pointer operator->() const { return &(operator*()); } istream_iterator& operator++() { _M_read(); return *this; } istream_iterator operator++(int) { 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: istream_type* _M_stream; _Tp _M_value; bool _M_ok; void _M_read() { _M_ok = (_M_stream && *_M_stream) ? true : false; if (_M_ok) { *_M_stream >> _M_value; _M_ok = *_M_stream ? true : false; } } }; template inline bool operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { return __x._M_equal(__y); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { return !__x._M_equal(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template > class ostream_iterator { public: typedef _CharT char_type; typedef _Traits traits_type; typedef basic_ostream<_CharT, _Traits> ostream_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {} ostream_iterator(ostream_type& __s, const _CharT* __c) : _M_stream(&__s), _M_string(__c) {} ostream_iterator<_Tp>& operator=(const _Tp& __value) { *_M_stream << __value; if (_M_string) *_M_stream << _M_string; return *this; } ostream_iterator<_Tp>& operator*() { return *this; } ostream_iterator<_Tp>& operator++() { return *this; } ostream_iterator<_Tp>& operator++(int) { return *this; } private: ostream_type* _M_stream; const _CharT* _M_string; }; // The default template argument is declared in iosfwd // We do not read any characters until operator* is called. The first // time operator* is called, it calls getc. Subsequent calls to getc // return a cached character, and calls to operator++ use snextc. Before // operator* or operator++ has been called, _M_is_initialized is false. template class istreambuf_iterator : public iterator { public: 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; public: istreambuf_iterator(streambuf_type* __p = 0) { this->_M_init(__p); } istreambuf_iterator(istream_type& __is) { this->_M_init(__is.rdbuf()); } char_type operator*() const { return _M_is_initialized ? _M_c : _M_dereference_aux(); } istreambuf_iterator& operator++() { this->_M_nextc(); return *this; } istreambuf_iterator operator++(int) { if (!_M_is_initialized) _M_postincr_aux(); istreambuf_iterator __tmp = *this; this->_M_nextc(); return __tmp; } bool equal(const istreambuf_iterator& __i) const { return this->_M_is_initialized && __i._M_is_initialized ? this->_M_eof == __i._M_eof : this->_M_equal_aux(__i); } private: void _M_init(streambuf_type* __p) { _M_buf = __p; _M_eof = !__p; _M_is_initialized = _M_eof; } char_type _M_dereference_aux() const; bool _M_equal_aux(const istreambuf_iterator&) const; void _M_postincr_aux(); void _M_nextc() { int_type __c = _M_buf->snextc(); _M_c = traits_type::to_char_type(__c); _M_eof = traits_type::eq_int_type(__c, traits_type::eof()); _M_is_initialized = true; } void _M_getc() const { int_type __c = _M_buf->sgetc(); _M_c = traits_type::to_char_type(__c); _M_eof = traits_type::eq_int_type(__c, traits_type::eof()); _M_is_initialized = true; } private: streambuf_type* _M_buf; mutable _CharT _M_c; mutable bool _M_eof : 1; mutable bool _M_is_initialized : 1; }; template _CharT istreambuf_iterator<_CharT, _Traits>::_M_dereference_aux() const { this->_M_getc(); return _M_c; } template bool istreambuf_iterator<_CharT, _Traits> ::_M_equal_aux(const istreambuf_iterator& __i) const { if (!this->_M_is_initialized) this->_M_getc(); if (!__i._M_is_initialized) __i._M_getc(); return this->_M_eof == __i._M_eof; } template void istreambuf_iterator<_CharT, _Traits>::_M_postincr_aux() { this->_M_getc(); } template inline bool operator==(const istreambuf_iterator<_CharT, _Traits>& __x, const istreambuf_iterator<_CharT, _Traits>& __y) { return __x.equal(__y); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const istreambuf_iterator<_CharT, _Traits>& __x, const istreambuf_iterator<_CharT, _Traits>& __y) { return !__x.equal(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // The default template argument is declared in iosfwd template class ostreambuf_iterator : public iterator { public: typedef _CharT char_type; typedef _Traits traits_type; typedef typename _Traits::int_type int_type; typedef basic_streambuf<_CharT, _Traits> streambuf_type; typedef basic_ostream<_CharT, _Traits> ostream_type; public: ostreambuf_iterator(streambuf_type* __buf) : _M_buf(__buf), _M_ok(__buf) {} ostreambuf_iterator(ostream_type& __o) : _M_buf(__o.rdbuf()), _M_ok(__o.rdbuf() != 0) {} ostreambuf_iterator& operator=(char_type __c) { _M_ok = _M_ok && !traits_type::eq_int_type(_M_buf->sputc(__c), traits_type::eof()); return *this; } ostreambuf_iterator& operator*() { return *this; } ostreambuf_iterator& operator++() { return *this; } ostreambuf_iterator& operator++(int) { return *this; } bool failed() const { return !_M_ok; } private: streambuf_type* _M_buf; bool _M_ok; }; #else /* __STL_USE_NEW_IOSTREAMS */ template class istream_iterator; template inline bool operator==(const istream_iterator<_Tp, _Dist>&, const istream_iterator<_Tp, _Dist>&); template class istream_iterator { #ifdef __STL_TEMPLATE_FRIENDS template friend bool operator==(const istream_iterator<_T1, _D1>&, const istream_iterator<_T1, _D1>&); #else /* __STL_TEMPLATE_FRIENDS */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const istream_iterator&, const istream_iterator&); #endif /* __STL_TEMPLATE_FRIENDS */ protected: istream* _M_stream; _Tp _M_value; bool _M_end_marker; void _M_read() { _M_end_marker = (*_M_stream) ? true : false; if (_M_end_marker) *_M_stream >> _M_value; _M_end_marker = (*_M_stream) ? true : false; } public: typedef input_iterator_tag iterator_category; typedef _Tp value_type; typedef _Dist difference_type; typedef const _Tp* pointer; typedef const _Tp& reference; istream_iterator() : _M_stream(&cin), _M_end_marker(false) {} istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); } reference operator*() const { return _M_value; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ istream_iterator<_Tp, _Dist>& operator++() { _M_read(); return *this; } istream_iterator<_Tp, _Dist> operator++(int) { istream_iterator<_Tp, _Dist> __tmp = *this; _M_read(); return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline input_iterator_tag iterator_category(const istream_iterator<_Tp, _Dist>&) { return input_iterator_tag(); } template inline _Tp* value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; } template inline _Dist* distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline bool operator==(const istream_iterator<_Tp, _Distance>& __x, const istream_iterator<_Tp, _Distance>& __y) { return (__x._M_stream == __y._M_stream && __x._M_end_marker == __y._M_end_marker) || __x._M_end_marker == false && __y._M_end_marker == false; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const istream_iterator<_Tp, _Distance>& __x, const istream_iterator<_Tp, _Distance>& __y) { return !(__x == __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template class ostream_iterator { protected: ostream* _M_stream; const char* _M_string; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {} ostream_iterator(ostream& __s, const char* __c) : _M_stream(&__s), _M_string(__c) {} ostream_iterator<_Tp>& operator=(const _Tp& __value) { *_M_stream << __value; if (_M_string) *_M_stream << _M_string; return *this; } ostream_iterator<_Tp>& operator*() { return *this; } ostream_iterator<_Tp>& operator++() { return *this; } ostream_iterator<_Tp>& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const ostream_iterator<_Tp>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ #endif /* __STL_USE_NEW_IOSTREAMS */ __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ITERATOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_iterator_base.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ITERATOR_BASE_H #define __SGI_STL_INTERNAL_ITERATOR_BASE_H // This file contains all of the general iterator-related utilities. // The internal file stl_iterator.h contains predefined iterators, // such as front_insert_iterator and istream_iterator. #include __STL_BEGIN_NAMESPACE struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; // 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 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 struct forward_iterator { typedef forward_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; }; template struct bidirectional_iterator { typedef bidirectional_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; }; template 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; }; #ifdef __STL_USE_NAMESPACES template struct iterator { typedef _Category iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Pointer pointer; typedef _Reference reference; }; #endif /* __STL_USE_NAMESPACES */ #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template 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 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 struct iterator_traits { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef ptrdiff_t difference_type; typedef const _Tp* pointer; typedef const _Tp& reference; }; // The overloaded functions iterator_category, distance_type, and // value_type are not part of the C++ standard. (They have been // replaced by struct iterator_traits.) They are included for // backward compatibility with the HP STL. // We introduce internal names for these functions. template inline typename iterator_traits<_Iter>::iterator_category __iterator_category(const _Iter&) { typedef typename iterator_traits<_Iter>::iterator_category _Category; return _Category(); } template inline typename iterator_traits<_Iter>::difference_type* __distance_type(const _Iter&) { return static_cast::difference_type*>(0); } template inline typename iterator_traits<_Iter>::value_type* __value_type(const _Iter&) { return static_cast::value_type*>(0); } template inline typename iterator_traits<_Iter>::iterator_category iterator_category(const _Iter& __i) { return __iterator_category(__i); } template inline typename iterator_traits<_Iter>::difference_type* distance_type(const _Iter& __i) { return __distance_type(__i); } template inline typename iterator_traits<_Iter>::value_type* value_type(const _Iter& __i) { return __value_type(__i); } #define __ITERATOR_CATEGORY(__i) __iterator_category(__i) #define __DISTANCE_TYPE(__i) __distance_type(__i) #define __VALUE_TYPE(__i) __value_type(__i) #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline input_iterator_tag iterator_category(const input_iterator<_Tp, _Distance>&) { return input_iterator_tag(); } inline output_iterator_tag iterator_category(const output_iterator&) { return output_iterator_tag(); } template inline forward_iterator_tag iterator_category(const forward_iterator<_Tp, _Distance>&) { return forward_iterator_tag(); } template inline bidirectional_iterator_tag iterator_category(const bidirectional_iterator<_Tp, _Distance>&) { return bidirectional_iterator_tag(); } template inline random_access_iterator_tag iterator_category(const random_access_iterator<_Tp, _Distance>&) { return random_access_iterator_tag(); } template inline random_access_iterator_tag iterator_category(const _Tp*) { return random_access_iterator_tag(); } template inline _Tp* value_type(const input_iterator<_Tp, _Distance>&) { return (_Tp*)(0); } template inline _Tp* value_type(const forward_iterator<_Tp, _Distance>&) { return (_Tp*)(0); } template inline _Tp* value_type(const bidirectional_iterator<_Tp, _Distance>&) { return (_Tp*)(0); } template inline _Tp* value_type(const random_access_iterator<_Tp, _Distance>&) { return (_Tp*)(0); } template inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); } template inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&) { return (_Distance*)(0); } template inline _Distance* distance_type(const forward_iterator<_Tp, _Distance>&) { return (_Distance*)(0); } template inline _Distance* distance_type(const bidirectional_iterator<_Tp, _Distance>&) { return (_Distance*)(0); } template inline _Distance* distance_type(const random_access_iterator<_Tp, _Distance>&) { return (_Distance*)(0); } template inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); } // Without partial specialization we can't use iterator_traits, so // we must keep the old iterator query functions around. #define __ITERATOR_CATEGORY(__i) iterator_category(__i) #define __DISTANCE_TYPE(__i) distance_type(__i) #define __VALUE_TYPE(__i) value_type(__i) #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline void __distance(_InputIterator __first, _InputIterator __last, _Distance& __n, input_iterator_tag) { while (__first != __last) { ++__first; ++__n; } } template inline void __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance& __n, random_access_iterator_tag) { __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); __n += __last - __first; } template inline void distance(_InputIterator __first, _InputIterator __last, _Distance& __n) { __STL_REQUIRES(_InputIterator, _InputIterator); __distance(__first, __last, __n, iterator_category(__first)); } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template inline typename iterator_traits<_InputIterator>::difference_type __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) { typename iterator_traits<_InputIterator>::difference_type __n = 0; while (__first != __last) { ++__first; ++__n; } return __n; } template inline typename iterator_traits<_RandomAccessIterator>::difference_type __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); return __last - __first; } template inline typename iterator_traits<_InputIterator>::difference_type distance(_InputIterator __first, _InputIterator __last) { typedef typename iterator_traits<_InputIterator>::iterator_category _Category; __STL_REQUIRES(_InputIterator, _InputIterator); return __distance(__first, __last, _Category()); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) { while (__n--) ++__i; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1183 #endif template inline void __advance(_BidirectionalIterator& __i, _Distance __n, bidirectional_iterator_tag) { __STL_REQUIRES(_BidirectionalIterator, _BidirectionalIterator); if (__n >= 0) while (__n--) ++__i; else while (__n++) --__i; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1183 #endif template inline void __advance(_RandomAccessIterator& __i, _Distance __n, random_access_iterator_tag) { __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); __i += __n; } template inline void advance(_InputIterator& __i, _Distance __n) { __STL_REQUIRES(_InputIterator, _InputIterator); __advance(__i, __n, iterator_category(__i)); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ITERATOR_BASE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_list.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_LIST_H #define __SGI_STL_INTERNAL_LIST_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif struct _List_node_base { _List_node_base* _M_next; _List_node_base* _M_prev; }; template struct _List_node : public _List_node_base { _Tp _M_data; }; struct _List_iterator_base { typedef size_t size_type; typedef ptrdiff_t difference_type; typedef bidirectional_iterator_tag iterator_category; _List_node_base* _M_node; _List_iterator_base(_List_node_base* __x) : _M_node(__x) {} _List_iterator_base() {} void _M_incr() { _M_node = _M_node->_M_next; } void _M_decr() { _M_node = _M_node->_M_prev; } bool operator==(const _List_iterator_base& __x) const { return _M_node == __x._M_node; } bool operator!=(const _List_iterator_base& __x) const { return _M_node != __x._M_node; } }; template struct _List_iterator : public _List_iterator_base { typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; typedef _List_iterator<_Tp,_Ref,_Ptr> _Self; typedef _Tp value_type; typedef _Ptr pointer; typedef _Ref reference; typedef _List_node<_Tp> _Node; _List_iterator(_Node* __x) : _List_iterator_base(__x) {} _List_iterator() {} _List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {} reference operator*() const { return ((_Node*) _M_node)->_M_data; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ _Self& operator++() { this->_M_incr(); return *this; } _Self operator++(int) { _Self __tmp = *this; this->_M_incr(); return __tmp; } _Self& operator--() { this->_M_decr(); return *this; } _Self operator--(int) { _Self __tmp = *this; this->_M_decr(); return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION inline bidirectional_iterator_tag iterator_category(const _List_iterator_base&) { return bidirectional_iterator_tag(); } template inline _Tp* value_type(const _List_iterator<_Tp, _Ref, _Ptr>&) { return 0; } inline ptrdiff_t* distance_type(const _List_iterator_base&) { return 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // Base class that encapsulates details of allocators. Three cases: // an ordinary standard-conforming allocator, a standard-conforming // allocator with no non-static data, and an SGI-style allocator. // This complexity is necessary only because we're worrying about backward // compatibility and because we want to avoid wasting storage on an // allocator instance if it isn't necessary. #ifdef __STL_USE_STD_ALLOCATORS // Base for general standard-conforming allocators. template class _List_alloc_base { public: typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return _Node_allocator; } _List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {} protected: _List_node<_Tp>* _M_get_node() { return _Node_allocator.allocate(1); } void _M_put_node(_List_node<_Tp>* __p) { _Node_allocator.deallocate(__p, 1); } protected: typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type _Node_allocator; _List_node<_Tp>* _M_node; }; // Specialization for instanceless allocators. template class _List_alloc_base<_Tp, _Allocator, true> { public: typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _List_alloc_base(const allocator_type&) {} protected: typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type _Alloc_type; _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } protected: _List_node<_Tp>* _M_node; }; template class _List_base : public _List_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { public: typedef _List_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base; typedef typename _Base::allocator_type allocator_type; _List_base(const allocator_type& __a) : _Base(__a) { _M_node = _M_get_node(); _M_node->_M_next = _M_node; _M_node->_M_prev = _M_node; } ~_List_base() { clear(); _M_put_node(_M_node); } void clear(); }; #else /* __STL_USE_STD_ALLOCATORS */ template class _List_base { public: typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(); } _List_base(const allocator_type&) { _M_node = _M_get_node(); _M_node->_M_next = _M_node; _M_node->_M_prev = _M_node; } ~_List_base() { clear(); _M_put_node(_M_node); } void clear(); protected: typedef simple_alloc<_List_node<_Tp>, _Alloc> _Alloc_type; _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } protected: _List_node<_Tp>* _M_node; }; #endif /* __STL_USE_STD_ALLOCATORS */ template void _List_base<_Tp,_Alloc>::clear() { _List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next; while (__cur != _M_node) { _List_node<_Tp>* __tmp = __cur; __cur = (_List_node<_Tp>*) __cur->_M_next; _Destroy(&__tmp->_M_data); _M_put_node(__tmp); } _M_node->_M_next = _M_node; _M_node->_M_prev = _M_node; } template class list : protected _List_base<_Tp, _Alloc> { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); typedef _List_base<_Tp, _Alloc> _Base; protected: typedef void* _Void_pointer; 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 _List_node<_Tp> _Node; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef typename _Base::allocator_type allocator_type; allocator_type get_allocator() const { return _Base::get_allocator(); } public: typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_bidirectional_iterator const_reverse_iterator; typedef reverse_bidirectional_iterator reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: #ifdef __STL_HAS_NAMESPACES using _Base::_M_node; using _Base::_M_put_node; using _Base::_M_get_node; #endif /* __STL_HAS_NAMESPACES */ protected: _Node* _M_create_node(const _Tp& __x) { _Node* __p = _M_get_node(); __STL_TRY { _Construct(&__p->_M_data, __x); } __STL_UNWIND(_M_put_node(__p)); return __p; } _Node* _M_create_node() { _Node* __p = _M_get_node(); __STL_TRY { _Construct(&__p->_M_data); } __STL_UNWIND(_M_put_node(__p)); return __p; } public: explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {} iterator begin() { return (_Node*)(_M_node->_M_next); } const_iterator begin() const { return (_Node*)(_M_node->_M_next); } iterator end() { return _M_node; } const_iterator end() const { return _M_node; } 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_node->_M_next == _M_node; } size_type size() const { size_type __result = 0; distance(begin(), end(), __result); return __result; } size_type max_size() const { return size_type(-1); } reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(--end()); } const_reference back() const { return *(--end()); } void swap(list<_Tp, _Alloc>& __x) { __STD::swap(_M_node, __x._M_node); } iterator insert(iterator __position, const _Tp& __x) { _Node* __tmp = _M_create_node(__x); __tmp->_M_next = __position._M_node; __tmp->_M_prev = __position._M_node->_M_prev; __position._M_node->_M_prev->_M_next = __tmp; __position._M_node->_M_prev = __tmp; return __tmp; } iterator insert(iterator __position) { return insert(__position, _Tp()); } #ifdef __STL_MEMBER_TEMPLATES // Check whether it's an integral type. If so, it's not an iterator. template void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type) { _M_fill_insert(__pos, (size_type) __n, (_Tp) __x); } template void _M_insert_dispatch(iterator __pos, _InputIterator __first, _InputIterator __last, __false_type); template void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_insert_dispatch(__pos, __first, __last, _Integral()); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator __position, const _Tp* __first, const _Tp* __last); void insert(iterator __position, const_iterator __first, const_iterator __last); #endif /* __STL_MEMBER_TEMPLATES */ void insert(iterator __pos, size_type __n, const _Tp& __x) { _M_fill_insert(__pos, __n, __x); } void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x); void push_front(const _Tp& __x) { insert(begin(), __x); } void push_front() {insert(begin());} void push_back(const _Tp& __x) { insert(end(), __x); } void push_back() {insert(end());} iterator erase(iterator __position) { _List_node_base* __next_node = __position._M_node->_M_next; _List_node_base* __prev_node = __position._M_node->_M_prev; _Node* __n = (_Node*) __position._M_node; __prev_node->_M_next = __next_node; __next_node->_M_prev = __prev_node; _Destroy(&__n->_M_data); _M_put_node(__n); return iterator((_Node*) __next_node); } iterator erase(iterator __first, iterator __last); void clear() { _Base::clear(); } void resize(size_type __new_size, const _Tp& __x); void resize(size_type __new_size) { this->resize(__new_size, _Tp()); } void pop_front() { erase(begin()); } void pop_back() { iterator __tmp = end(); erase(--__tmp); } list(size_type __n, const _Tp& __value, const allocator_type& __a = allocator_type()) : _Base(__a) { insert(begin(), __n, __value); } explicit list(size_type __n) : _Base(allocator_type()) { insert(begin(), __n, _Tp()); } #ifdef __STL_MEMBER_TEMPLATES // We don't need any dispatching tricks here, because insert does all of // that anyway. template list(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { insert(begin(), __first, __last); } #else /* __STL_MEMBER_TEMPLATES */ list(const _Tp* __first, const _Tp* __last, const allocator_type& __a = allocator_type()) : _Base(__a) { this->insert(begin(), __first, __last); } list(const_iterator __first, const_iterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { this->insert(begin(), __first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator()) { insert(begin(), __x.begin(), __x.end()); } ~list() { } list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x); 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); #ifdef __STL_MEMBER_TEMPLATES template void assign(_InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_assign_dispatch(__first, __last, _Integral()); } template void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign((size_type) __n, (_Tp) __val); } template void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type); #endif /* __STL_MEMBER_TEMPLATES */ protected: void transfer(iterator __position, iterator __first, iterator __last) { if (__position != __last) { // Remove [first, last) from its old position. __last._M_node->_M_prev->_M_next = __position._M_node; __first._M_node->_M_prev->_M_next = __last._M_node; __position._M_node->_M_prev->_M_next = __first._M_node; // Splice [first, last) into its new position. _List_node_base* __tmp = __position._M_node->_M_prev; __position._M_node->_M_prev = __last._M_node->_M_prev; __last._M_node->_M_prev = __first._M_node->_M_prev; __first._M_node->_M_prev = __tmp; } } public: void splice(iterator __position, list& __x) { if (!__x.empty()) this->transfer(__position, __x.begin(), __x.end()); } void splice(iterator __position, list&, iterator __i) { iterator __j = __i; ++__j; if (__position == __i || __position == __j) return; this->transfer(__position, __i, __j); } void splice(iterator __position, list&, iterator __first, iterator __last) { if (__first != __last) this->transfer(__position, __first, __last); } void remove(const _Tp& __value); void unique(); void merge(list& __x); void reverse(); void sort(); #ifdef __STL_MEMBER_TEMPLATES template void remove_if(_Predicate); template void unique(_BinaryPredicate); template void merge(list&, _StrictWeakOrdering); template void sort(_StrictWeakOrdering); #endif /* __STL_MEMBER_TEMPLATES */ }; template 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; } template inline bool operator<(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { return lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { return !(__x == __y); } template inline bool operator>(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { return __y < __x; } template inline bool operator<=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { return !(__y < __x); } template inline bool operator>=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { return !(__x < __y); } template inline void swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifdef __STL_MEMBER_TEMPLATES template template void list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position, _InputIter __first, _InputIter __last, __false_type) { for ( ; __first != __last; ++__first) insert(__position, *__first); } #else /* __STL_MEMBER_TEMPLATES */ template void list<_Tp, _Alloc>::insert(iterator __position, const _Tp* __first, const _Tp* __last) { for ( ; __first != __last; ++__first) insert(__position, *__first); } template void list<_Tp, _Alloc>::insert(iterator __position, const_iterator __first, const_iterator __last) { for ( ; __first != __last; ++__first) insert(__position, *__first); } #endif /* __STL_MEMBER_TEMPLATES */ template void list<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n, const _Tp& __x) { for ( ; __n > 0; --__n) insert(__position, __x); } template typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first, iterator __last) { while (__first != __last) erase(__first++); return __last; } template void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __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 list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x) { if (this != &__x) { iterator __first1 = begin(); iterator __last1 = end(); const_iterator __first2 = __x.begin(); const_iterator __last2 = __x.end(); while (__first1 != __last1 && __first2 != __last2) *__first1++ = *__first2++; if (__first2 == __last2) erase(__first1, __last1); else insert(__last1, __first2, __last2); } return *this; } template void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { iterator __i = begin(); for ( ; __i != end() && __n > 0; ++__i, --__n) *__i = __val; if (__n > 0) insert(end(), __n, __val); else erase(__i, end()); } #ifdef __STL_MEMBER_TEMPLATES template template void list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __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); } #endif /* __STL_MEMBER_TEMPLATES */ template void list<_Tp, _Alloc>::remove(const _Tp& __value) { iterator __first = begin(); iterator __last = end(); while (__first != __last) { iterator __next = __first; ++__next; if (*__first == __value) erase(__first); __first = __next; } } template void list<_Tp, _Alloc>::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 void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __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; transfer(__first1, __first2, ++__next); __first2 = __next; } else ++__first1; if (__first2 != __last2) transfer(__last1, __first2, __last2); } inline void __List_base_reverse(_List_node_base* __p) { _List_node_base* __tmp = __p; do { __STD::swap(__tmp->_M_next, __tmp->_M_prev); __tmp = __tmp->_M_prev; // Old next node is now prev. } while (__tmp != __p); } template inline void list<_Tp, _Alloc>::reverse() { __List_base_reverse(this->_M_node); } template void list<_Tp, _Alloc>::sort() { // Do nothing if the list has length 0 or 1. if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) { list<_Tp, _Alloc> __carry; list<_Tp, _Alloc> __counter[64]; int __fill = 0; while (!empty()) { __carry.splice(__carry.begin(), *this, begin()); int __i = 0; while(__i < __fill && !__counter[__i].empty()) { __counter[__i].merge(__carry); __carry.swap(__counter[__i++]); } __carry.swap(__counter[__i]); if (__i == __fill) ++__fill; } for (int __i = 1; __i < __fill; ++__i) __counter[__i].merge(__counter[__i-1]); swap(__counter[__fill-1]); } } #ifdef __STL_MEMBER_TEMPLATES template template void list<_Tp, _Alloc>::remove_if(_Predicate __pred) { iterator __first = begin(); iterator __last = end(); while (__first != __last) { iterator __next = __first; ++__next; if (__pred(*__first)) erase(__first); __first = __next; } } template template 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)) erase(__next); else __first = __next; __next = __first; } } template template void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x, _StrictWeakOrdering __comp) { 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; transfer(__first1, __first2, ++__next); __first2 = __next; } else ++__first1; if (__first2 != __last2) transfer(__last1, __first2, __last2); } template template void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) { // Do nothing if the list has length 0 or 1. if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) { list<_Tp, _Alloc> __carry; list<_Tp, _Alloc> __counter[64]; int __fill = 0; while (!empty()) { __carry.splice(__carry.begin(), *this, begin()); int __i = 0; while(__i < __fill && !__counter[__i].empty()) { __counter[__i].merge(__carry, __comp); __carry.swap(__counter[__i++]); } __carry.swap(__counter[__i]); if (__i == __fill) ++__fill; } for (int __i = 1; __i < __fill; ++__i) __counter[__i].merge(__counter[__i-1], __comp); swap(__counter[__fill-1]); } } #endif /* __STL_MEMBER_TEMPLATES */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_LIST_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_map.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_MAP_H #define __SGI_STL_INTERNAL_MAP_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // Forward declarations of operators == and <, needed for friend declarations. template ), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > class map; template inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y); template inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y); template class map { public: // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); // typedefs: typedef _Key key_type; typedef _Tp data_type; typedef _Tp mapped_type; typedef pair value_type; typedef _Compare key_compare; class value_compare : public binary_function { 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: typedef _Rb_tree, key_compare, _Alloc> _Rep_type; _Rep_type _M_t; // red-black tree representing map public: typedef typename _Rep_type::pointer pointer; typedef typename _Rep_type::const_pointer const_pointer; typedef typename _Rep_type::reference reference; typedef typename _Rep_type::const_reference const_reference; typedef typename _Rep_type::iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::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; typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation map() : _M_t(_Compare(), allocator_type()) {} explicit map(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES template map(_InputIterator __first, _InputIterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } template map(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #else map(const value_type* __first, const value_type* __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } map(const value_type* __first, const value_type* __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } map(const_iterator __first, const_iterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } map(const_iterator __first, const_iterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ map(const map<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} map<_Key,_Tp,_Compare,_Alloc>& operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x) { _M_t = __x._M_t; return *this; } // accessors: key_compare key_comp() const { return _M_t.key_comp(); } value_compare value_comp() const { return value_compare(_M_t.key_comp()); } allocator_type get_allocator() const { return _M_t.get_allocator(); } iterator begin() { return _M_t.begin(); } const_iterator begin() const { return _M_t.begin(); } iterator end() { return _M_t.end(); } const_iterator end() const { return _M_t.end(); } reverse_iterator rbegin() { return _M_t.rbegin(); } const_reverse_iterator rbegin() const { return _M_t.rbegin(); } reverse_iterator rend() { return _M_t.rend(); } const_reverse_iterator rend() const { return _M_t.rend(); } bool empty() const { return _M_t.empty(); } size_type size() const { return _M_t.size(); } size_type max_size() const { return _M_t.max_size(); } _Tp& operator[](const key_type& __k) { 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, _Tp())); return (*__i).second; } void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase pair insert(const value_type& __x) { return _M_t.insert_unique(__x); } iterator insert(iterator position, const value_type& __x) { return _M_t.insert_unique(position, __x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(_InputIterator __first, _InputIterator __last) { _M_t.insert_unique(__first, __last); } #else void insert(const value_type* __first, const value_type* __last) { _M_t.insert_unique(__first, __last); } void insert(const_iterator __first, const_iterator __last) { _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator __position) { _M_t.erase(__position); } size_type erase(const key_type& __x) { return _M_t.erase(__x); } void erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } void clear() { _M_t.clear(); } // map operations: iterator find(const key_type& __x) { return _M_t.find(__x); } const_iterator find(const key_type& __x) const { return _M_t.find(__x); } size_type count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } 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); } 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); } pair equal_range(const key_type& __x) { return _M_t.equal_range(__x); } pair equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } #ifdef __STL_TEMPLATE_FRIENDS template friend bool operator== (const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); template friend bool operator< (const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); #else /* __STL_TEMPLATE_FRIENDS */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const map&, const map&); friend bool __STD_QUALIFIER operator< __STL_NULL_TMPL_ARGS (const map&, const map&); #endif /* __STL_TEMPLATE_FRIENDS */ }; template inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return __x._M_t == __y._M_t; } template inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x == __y); } template inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return __y < __x; } template inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__y < __x); } template inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x < __y); } template inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_MAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_multimap.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_MULTIMAP_H #define __SGI_STL_INTERNAL_MULTIMAP_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // Forward declaration of operators < and ==, needed for friend declaration. template ), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > class multimap; template inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y); template inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y); template class multimap { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); public: // typedefs: typedef _Key key_type; typedef _Tp data_type; typedef _Tp mapped_type; typedef pair value_type; typedef _Compare key_compare; class value_compare : public binary_function { 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: typedef _Rb_tree, key_compare, _Alloc> _Rep_type; _Rep_type _M_t; // red-black tree representing multimap public: typedef typename _Rep_type::pointer pointer; typedef typename _Rep_type::const_pointer const_pointer; typedef typename _Rep_type::reference reference; typedef typename _Rep_type::const_reference const_reference; typedef typename _Rep_type::iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::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; typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation multimap() : _M_t(_Compare(), allocator_type()) { } explicit multimap(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { } #ifdef __STL_MEMBER_TEMPLATES template multimap(_InputIterator __first, _InputIterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } template multimap(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #else multimap(const value_type* __first, const value_type* __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } multimap(const value_type* __first, const value_type* __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } multimap(const_iterator __first, const_iterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } multimap(const_iterator __first, const_iterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ multimap(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) { } multimap<_Key,_Tp,_Compare,_Alloc>& operator=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t = __x._M_t; return *this; } // accessors: key_compare key_comp() const { return _M_t.key_comp(); } value_compare value_comp() const { return value_compare(_M_t.key_comp()); } allocator_type get_allocator() const { return _M_t.get_allocator(); } iterator begin() { return _M_t.begin(); } const_iterator begin() const { return _M_t.begin(); } iterator end() { return _M_t.end(); } const_iterator end() const { return _M_t.end(); } reverse_iterator rbegin() { return _M_t.rbegin(); } const_reverse_iterator rbegin() const { return _M_t.rbegin(); } reverse_iterator rend() { return _M_t.rend(); } const_reverse_iterator rend() const { return _M_t.rend(); } bool empty() const { return _M_t.empty(); } size_type size() const { return _M_t.size(); } size_type max_size() const { return _M_t.max_size(); } void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); } iterator insert(iterator __position, const value_type& __x) { return _M_t.insert_equal(__position, __x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(_InputIterator __first, _InputIterator __last) { _M_t.insert_equal(__first, __last); } #else void insert(const value_type* __first, const value_type* __last) { _M_t.insert_equal(__first, __last); } void insert(const_iterator __first, const_iterator __last) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator __position) { _M_t.erase(__position); } size_type erase(const key_type& __x) { return _M_t.erase(__x); } void erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } void clear() { _M_t.clear(); } // multimap operations: iterator find(const key_type& __x) { return _M_t.find(__x); } const_iterator find(const key_type& __x) const { return _M_t.find(__x); } size_type count(const key_type& __x) const { return _M_t.count(__x); } 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); } 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); } pair equal_range(const key_type& __x) { return _M_t.equal_range(__x); } pair equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } #ifdef __STL_TEMPLATE_FRIENDS template friend bool operator== (const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); template friend bool operator< (const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); #else /* __STL_TEMPLATE_FRIENDS */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); friend bool __STD_QUALIFIER operator< __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); #endif /* __STL_TEMPLATE_FRIENDS */ }; template inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return __x._M_t == __y._M_t; } template inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x == __y); } template inline bool operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return __y < __x; } template inline bool operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__y < __x); } template inline bool operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x < __y); } template inline void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, multimap<_Key,_Tp,_Compare,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_MULTIMAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_multiset.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_MULTISET_H #define __SGI_STL_INTERNAL_MULTISET_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // Forward declaration of operators < and ==, needed for friend declaration. template ), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > class multiset; template inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y); template inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y); template class multiset { // requirements: __STL_CLASS_REQUIRES(_Key, _Assignable); __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); public: // typedefs: typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; private: typedef _Rb_tree, key_compare, _Alloc> _Rep_type; _Rep_type _M_t; // red-black tree representing multiset public: typedef typename _Rep_type::const_pointer pointer; typedef typename _Rep_type::const_pointer const_pointer; typedef typename _Rep_type::const_reference reference; typedef typename _Rep_type::const_reference const_reference; 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; typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation multiset() : _M_t(_Compare(), allocator_type()) {} explicit multiset(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES template multiset(_InputIterator __first, _InputIterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } template multiset(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #else multiset(const value_type* __first, const value_type* __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } multiset(const value_type* __first, const value_type* __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } multiset(const_iterator __first, const_iterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } multiset(const_iterator __first, const_iterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} multiset<_Key,_Compare,_Alloc>& operator=(const multiset<_Key,_Compare,_Alloc>& __x) { _M_t = __x._M_t; return *this; } // accessors: key_compare key_comp() const { return _M_t.key_comp(); } value_compare value_comp() const { return _M_t.key_comp(); } allocator_type get_allocator() const { return _M_t.get_allocator(); } iterator begin() const { return _M_t.begin(); } iterator end() const { return _M_t.end(); } reverse_iterator rbegin() const { return _M_t.rbegin(); } reverse_iterator rend() const { return _M_t.rend(); } bool empty() const { return _M_t.empty(); } size_type size() const { return _M_t.size(); } size_type max_size() const { return _M_t.max_size(); } void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); } iterator insert(iterator __position, const value_type& __x) { typedef typename _Rep_type::iterator _Rep_iterator; return _M_t.insert_equal((_Rep_iterator&)__position, __x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(_InputIterator __first, _InputIterator __last) { _M_t.insert_equal(__first, __last); } #else void insert(const value_type* __first, const value_type* __last) { _M_t.insert_equal(__first, __last); } void insert(const_iterator __first, const_iterator __last) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator __position) { typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__position); } size_type erase(const key_type& __x) { return _M_t.erase(__x); } void erase(iterator __first, iterator __last) { typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); } void clear() { _M_t.clear(); } // multiset operations: iterator find(const key_type& __x) const { return _M_t.find(__x); } size_type count(const key_type& __x) const { return _M_t.count(__x); } iterator lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } iterator upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } pair equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } #ifdef __STL_TEMPLATE_FRIENDS template friend bool operator== (const multiset<_K1,_C1,_A1>&, const multiset<_K1,_C1,_A1>&); template friend bool operator< (const multiset<_K1,_C1,_A1>&, const multiset<_K1,_C1,_A1>&); #else /* __STL_TEMPLATE_FRIENDS */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); friend bool __STD_QUALIFIER operator< __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); #endif /* __STL_TEMPLATE_FRIENDS */ }; template inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return __x._M_t == __y._M_t; } template inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return !(__x == __y); } template inline bool operator>(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return __y < __x; } template inline bool operator<=(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return !(__y < __x); } template inline bool operator>=(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return !(__x < __y); } template inline void swap(multiset<_Key,_Compare,_Alloc>& __x, multiset<_Key,_Compare,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_MULTISET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_numeric.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_NUMERIC_H #define __SGI_STL_INTERNAL_NUMERIC_H __STL_BEGIN_NAMESPACE template _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) { __STL_REQUIRES(_InputIterator, _InputIterator); for ( ; __first != __last; ++__first) __init = __init + *__first; return __init; } template _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIterator, _InputIterator); for ( ; __first != __last; ++__first) __init = __binary_op(__init, *__first); return __init; } template _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) { __STL_REQUIRES(_InputIterator2, _InputIterator); __STL_REQUIRES(_InputIterator2, _InputIterator); for ( ; __first1 != __last1; ++__first1, ++__first2) __init = __init + (*__first1 * *__first2); return __init; } template _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { __STL_REQUIRES(_InputIterator2, _InputIterator); __STL_REQUIRES(_InputIterator2, _InputIterator); for ( ; __first1 != __last1; ++__first1, ++__first2) __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); return __init; } template _OutputIterator __partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*) { _Tp __value = *__first; while (++__first != __last) { __value = __value + *__first; *++__result = __value; } return ++__result; } template _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result; *__result = *__first; return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first)); } template _OutputIterator __partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) { _Tp __value = *__first; while (++__first != __last) { __value = __binary_op(__value, *__first); *++__result = __value; } return ++__result; } template _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result; *__result = *__first; return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first), __binary_op); } template _OutputIterator __adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*) { _Tp __value = *__first; while (++__first != __last) { _Tp __tmp = *__first; *++__result = __tmp - __value; __value = __tmp; } return ++__result; } template _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result; *__result = *__first; return __adjacent_difference(__first, __last, __result, __VALUE_TYPE(__first)); } template _OutputIterator __adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) { _Tp __value = *__first; while (++__first != __last) { _Tp __tmp = *__first; *++__result = __binary_op(__tmp, __value); __value = __tmp; } return ++__result; } template _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result; *__result = *__first; return __adjacent_difference(__first, __last, __result, __VALUE_TYPE(__first), __binary_op); } // Returns __x ** __n, where __n >= 0. _Note that "multiplication" // is required to be associative, but not necessarily commutative. template _Tp __power(_Tp __x, _Integer __n, _MonoidOperation __opr) { if (__n == 0) return identity_element(__opr); else { while ((__n & 1) == 0) { __n >>= 1; __x = __opr(__x, __x); } _Tp __result = __x; __n >>= 1; while (__n != 0) { __x = __opr(__x, __x); if ((__n & 1) != 0) __result = __opr(__result, __x); __n >>= 1; } return __result; } } template inline _Tp __power(_Tp __x, _Integer __n) { return __power(__x, __n, multiplies<_Tp>()); } // Alias for the internal name __power. Note that power is an extension, // not part of the C++ standard. template inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __opr) { return __power(__x, __n, __opr); } template inline _Tp power(_Tp __x, _Integer __n) { return __power(__x, __n); } // iota is not part of the C++ standard. It is an extension. template void iota(_ForwardIter __first, _ForwardIter __last, _Tp __value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); while (__first != __last) *__first++ = __value++; } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_NUMERIC_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_pair.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_PAIR_H #define __SGI_STL_INTERNAL_PAIR_H __STL_BEGIN_NAMESPACE template struct pair { typedef _T1 first_type; typedef _T2 second_type; _T1 first; _T2 second; pair() : first(_T1()), second(_T2()) {} pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {} #ifdef __STL_MEMBER_TEMPLATES template pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} #endif }; template inline bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return __x.first == __y.first && __x.second == __y.second; } template 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); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__x == __y); } template inline bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return __y < __x; } template inline bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__y < __x); } template inline bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__x < __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template inline pair<_T1, _T2> make_pair(const _T1& __x, const _T2& __y) { return pair<_T1, _T2>(__x, __y); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_PAIR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_queue.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_QUEUE_H #define __SGI_STL_INTERNAL_QUEUE_H #include __STL_BEGIN_NAMESPACE // Forward declarations of operators < and ==, needed for friend declaration. template ) > class queue; template inline bool operator==(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&); template inline bool operator<(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&); template class queue { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_REQUIRES(_Sequence, _FrontInsertionSequence); __STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence); typedef typename _Sequence::value_type _Sequence_value_type; __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type); #ifdef __STL_MEMBER_TEMPLATES template friend bool operator== (const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); template friend bool operator< (const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const queue&, const queue&); friend bool __STD_QUALIFIER operator< __STL_NULL_TMPL_ARGS (const queue&, const queue&); #endif /* __STL_MEMBER_TEMPLATES */ public: typedef typename _Sequence::value_type value_type; typedef typename _Sequence::size_type size_type; typedef _Sequence container_type; typedef typename _Sequence::reference reference; typedef typename _Sequence::const_reference const_reference; protected: _Sequence c; public: queue() : c() {} explicit queue(const _Sequence& __c) : c(__c) {} bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference front() { return c.front(); } const_reference front() const { return c.front(); } reference back() { return c.back(); } const_reference back() const { return c.back(); } void push(const value_type& __x) { c.push_back(__x); } void pop() { c.pop_front(); } }; template bool operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) { return __x.c == __y.c; } template bool operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) { return __x.c < __y.c; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template bool operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) { return !(__x == __y); } template bool operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) { return __y < __x; } template bool operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) { return !(__y < __x); } template bool operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) { return !(__x < __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template ), class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less) > class priority_queue { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_REQUIRES(_Sequence, _Sequence); __STL_CLASS_REQUIRES(_Sequence, _RandomAccessContainer); typedef typename _Sequence::value_type _Sequence_value_type; __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type); __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp); public: typedef typename _Sequence::value_type value_type; typedef typename _Sequence::size_type size_type; typedef _Sequence container_type; typedef typename _Sequence::reference reference; typedef typename _Sequence::const_reference const_reference; protected: _Sequence c; _Compare comp; public: priority_queue() : c() {} explicit priority_queue(const _Compare& __x) : c(), comp(__x) {} priority_queue(const _Compare& __x, const _Sequence& __s) : c(__s), comp(__x) { make_heap(c.begin(), c.end(), comp); } #ifdef __STL_MEMBER_TEMPLATES template priority_queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } template priority_queue(_InputIterator __first, _InputIterator __last, const _Compare& __x) : c(__first, __last), comp(__x) { make_heap(c.begin(), c.end(), comp); } template priority_queue(_InputIterator __first, _InputIterator __last, const _Compare& __x, const _Sequence& __s) : c(__s), comp(__x) { c.insert(c.end(), __first, __last); make_heap(c.begin(), c.end(), comp); } #else /* __STL_MEMBER_TEMPLATES */ priority_queue(const value_type* __first, const value_type* __last) : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } priority_queue(const value_type* __first, const value_type* __last, const _Compare& __x) : c(__first, __last), comp(__x) { make_heap(c.begin(), c.end(), comp); } priority_queue(const value_type* __first, const value_type* __last, const _Compare& __x, const _Sequence& __c) : c(__c), comp(__x) { c.insert(c.end(), __first, __last); make_heap(c.begin(), c.end(), comp); } #endif /* __STL_MEMBER_TEMPLATES */ bool empty() const { return c.empty(); } size_type size() const { return c.size(); } const_reference top() const { return c.front(); } void push(const value_type& __x) { __STL_TRY { c.push_back(__x); push_heap(c.begin(), c.end(), comp); } __STL_UNWIND(c.clear()); } void pop() { __STL_TRY { pop_heap(c.begin(), c.end(), comp); c.pop_back(); } __STL_UNWIND(c.clear()); } }; // no equality is provided __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_QUEUE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_range_errors.h ================================================ /* * Copyright (c) 1999 * 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. * */ #ifndef __STL_RANGE_ERRORS_H #define __STL_RANGE_ERRORS_H // A few places in the STL throw range errors, using standard exception // classes defined in . This header file provides functions // to throw those exception objects. // __STL_DONT_THROW_RANGE_ERRORS is a hook so that users can disable // this exception throwing. #include #if defined(__STL_CAN_THROW_RANGE_ERRORS) && \ defined(__STL_USE_EXCEPTIONS) && \ !defined(__STL_DONT_THROW_RANGE_ERRORS) # define __STL_THROW_RANGE_ERRORS #endif // For the SGI 7.3 compiler, declare these functions here and define them // elsewhere. #if defined(__STL_THROW_RANGE_ERRORS) && \ defined(__sgi) && !defined(__GNUC__) && \ _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) __STL_BEGIN_NAMESPACE void __stl_throw_range_error(const char* __msg); void __stl_throw_length_error(const char* __msg); __STL_END_NAMESPACE // For other compilers where we're throwing range errors, include the // stdexcept header and throw the appropriate exceptions directly. #elif defined(__STL_THROW_RANGE_ERRORS) #include __STL_BEGIN_NAMESPACE inline void __stl_throw_range_error(const char* __msg) { throw range_error(__msg); } inline void __stl_throw_length_error(const char* __msg) { throw length_error(__msg); } __STL_END_NAMESPACE // Otherwise, define inline functions that do nothing. #else __STL_BEGIN_NAMESPACE inline void __stl_throw_range_error(const char*) {} inline void __stl_throw_length_error(const char*) {} __STL_END_NAMESPACE #endif #endif /* __STL_RANGE_ERRORS_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_raw_storage_iter.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H #define __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H __STL_BEGIN_NAMESPACE template class raw_storage_iterator { protected: _ForwardIterator _M_iter; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {} raw_storage_iterator& operator*() { return *this; } raw_storage_iterator& operator=(const _Tp& __element) { 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; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const raw_storage_iterator<_ForwardIterator, _Tp>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_relops.h ================================================ /* * * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_RELOPS #define __SGI_STL_INTERNAL_RELOPS __STL_BEGIN_RELOPS_NAMESPACE template inline bool operator!=(const _Tp& __x, const _Tp& __y) { return !(__x == __y); } template inline bool operator>(const _Tp& __x, const _Tp& __y) { return __y < __x; } template inline bool operator<=(const _Tp& __x, const _Tp& __y) { return !(__y < __x); } template inline bool operator>=(const _Tp& __x, const _Tp& __y) { return !(__x < __y); } __STL_END_RELOPS_NAMESPACE #endif /* __SGI_STL_INTERNAL_RELOPS */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_rope.h ================================================ /* * Copyright (c) 1997-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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ // rope<_CharT,_Alloc> is a sequence of _CharT. // Ropes appear to be mutable, but update operations // really copy enough of the data structure to leave the original // valid. Thus ropes can be logically copied by just copying // a pointer value. #ifndef __SGI_STL_INTERNAL_ROPE_H # define __SGI_STL_INTERNAL_ROPE_H # ifdef __GC # define __GC_CONST const # else # include # define __GC_CONST // constant except for deallocation # endif # ifdef __STL_SGI_THREADS # include # endif __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif // 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 inline _CharT _S_eos(_CharT*) { return _CharT(); } // Test for basic character types. // For basic character types leaves having a trailing eos. template inline bool _S_is_basic_char_type(_CharT*) { return false; } template 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 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 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 // 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 and a // little like containers. template // The 3rd parameter works around a common compiler bug. class sequence_buffer : public output_iterator { public: # ifndef __TYPEDEF_WORKAROUND typedef typename _Sequence::value_type value_type; # else typedef _V value_type; # endif 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; 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; 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; size_t __j = 0; for (; __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 _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 rope; template struct _Rope_RopeConcatenation; template struct _Rope_RopeLeaf; template struct _Rope_RopeFunction; template struct _Rope_RopeSubstring; template class _Rope_iterator; template class _Rope_const_iterator; template class _Rope_char_ref_proxy; template class _Rope_char_ptr_proxy; template bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); template _Rope_const_iterator<_CharT,_Alloc> operator- (const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n); template _Rope_const_iterator<_CharT,_Alloc> operator+ (const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n); template _Rope_const_iterator<_CharT,_Alloc> operator+ (ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x); template bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y); template bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y); template ptrdiff_t operator- (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y); template _Rope_iterator<_CharT,_Alloc> operator- (const _Rope_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n); template _Rope_iterator<_CharT,_Alloc> operator+ (const _Rope_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n); template _Rope_iterator<_CharT,_Alloc> operator+ (ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x); template bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y); template bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y); template ptrdiff_t operator- (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y); template rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, const rope<_CharT,_Alloc>& __right); template rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, const _CharT* __right); template 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 struct _Rope_Concat_fn : public binary_function, rope<_CharT,_Alloc>, rope<_CharT,_Alloc> > { rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { return __x + __y; } }; template inline rope<_CharT,_Alloc> identity_element(_Rope_Concat_fn<_CharT, _Alloc>) { return rope<_CharT,_Alloc>(); } // // 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 occurence 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. // // A macro to introduce various allocation and deallocation functions // These need to be defined differently depending on whether or not // we are using standard conforming allocators, and whether the allocator // instances have real state. Thus this macro is invoked repeatedly // with different definitions of __ROPE_DEFINE_ALLOC. // __ROPE_DEFINE_ALLOC(type,name) defines // type * name_allocate(size_t) and // void name_deallocate(tipe *, size_t) // Both functions may or may not be static. #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. // The _Rope_rep_base class encapsulates // the differences between SGI-style allocators and standard-conforming // allocators. #ifdef __STL_USE_STD_ALLOCATORS #define __STATIC_IF_SGI_ALLOC /* not static */ // Base class for ordinary allocators. template class _Rope_rep_alloc_base { public: typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_data_allocator; } _Rope_rep_alloc_base(size_t __size, const allocator_type& __a) : _M_size(__size), _M_data_allocator(__a) {} size_t _M_size; // This is here only to avoid wasting space // for an otherwise empty base class. protected: allocator_type _M_data_allocator; # define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef typename \ _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ /*static*/ _Tp * __name##_allocate(size_t __n) \ { return __name##Allocator(_M_data_allocator).allocate(__n); } \ void __name##_deallocate(_Tp* __p, size_t __n) \ { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } __ROPE_DEFINE_ALLOCS(_Allocator); # undef __ROPE_DEFINE_ALLOC }; // Specialization for allocators that have the property that we don't // actually have to store an allocator object. template class _Rope_rep_alloc_base<_CharT,_Allocator,true> { public: typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Rope_rep_alloc_base(size_t __size, const allocator_type&) : _M_size(__size) {} size_t _M_size; protected: # define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef typename \ _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ typedef typename \ _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ static _Tp* __name##_allocate(size_t __n) \ { return __name##Alloc::allocate(__n); } \ void __name##_deallocate(_Tp *__p, size_t __n) \ { __name##Alloc::deallocate(__p, __n); } __ROPE_DEFINE_ALLOCS(_Allocator); # undef __ROPE_DEFINE_ALLOC }; template struct _Rope_rep_base : public _Rope_rep_alloc_base<_CharT,_Alloc, _Alloc_traits<_CharT,_Alloc>::_S_instanceless> { typedef _Rope_rep_alloc_base<_CharT,_Alloc, _Alloc_traits<_CharT,_Alloc>::_S_instanceless> _Base; typedef typename _Base::allocator_type allocator_type; _Rope_rep_base(size_t __size, const allocator_type& __a) : _Base(__size, __a) {} }; #else /* !__STL_USE_STD_ALLOCATORS */ #define __STATIC_IF_SGI_ALLOC static template class _Rope_rep_base { public: typedef _Alloc allocator_type; static allocator_type get_allocator() { return allocator_type(); } _Rope_rep_base(size_t __size, const allocator_type&) : _M_size(__size) {} size_t _M_size; protected: # define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef simple_alloc<_Tp, _Alloc> __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 }; #endif /* __STL_USE_STD_ALLOCATORS */ template struct _Rope_RopeRep : public _Rope_rep_base<_CharT,_Alloc> # ifndef __GC , _Refcount_Base # endif { public: enum { _S_max_rope_depth = 45 }; enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; _Tag _M_tag:8; bool _M_is_balanced:8; unsigned char _M_depth; __GC_CONST _CharT* _M_c_string; /* 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; _Rope_RopeRep(_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 __GC void _M_incr () {} # endif # ifdef __STL_USE_STD_ALLOCATORS 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); # else static void _S_free_string(__GC_CONST _CharT*, size_t __len); # define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l); # endif // 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 }; template 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 accomodate 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 + _S_alloc_granularity-1) &~ (_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>(_S_leaf, 0, true, __size, __a), _M_data(__d) { __stl_assert(__size > 0); if (_S_is_basic_char_type((_CharT *)0)) { // already eos terminated. _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() { if (_M_data != _M_c_string) { _M_free_c_string(); } __STL_FREE_STRING(_M_data, _M_size, get_allocator()); } # endif }; template 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>(_S_concat, 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() { _M_free_c_string(); _M_left->_M_unref_nonnil(); _M_right->_M_unref_nonnil(); } # endif }; template 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>(_S_function, 0, true, __size, __a) , _M_fn(__f) # ifndef __GC , _M_delete_when_done(__d) # endif { __stl_assert(__size > 0); # ifdef __GC if (__d) { GC_REGISTER_FINALIZER( this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0); } # endif } # ifndef __GC ~_Rope_RopeFunction() { _M_free_c_string(); if (_M_delete_when_done) { delete _M_fn; } } # endif }; // 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 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 _S_function: case _S_substringfn: { char_producer<_CharT>* __fn = ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; __stl_assert(__start_pos + __req_len <= _M_size); __stl_assert(_M_start + _M_size <= _M_base->_M_size); (*__fn)(__start_pos + _M_start, __req_len, __buffer); } break; case _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: __stl_assert(false); } } 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) { __stl_assert(__l > 0); __stl_assert(__s + __l <= __b->_M_size); # ifndef __GC _M_base->_M_ref_nonnil(); # endif _M_tag = _S_substringfn; } virtual ~_Rope_RopeSubstring() { # 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 struct _Rope_self_destruct_ptr { _Rope_RopeRep<_CharT,_Alloc>* _M_ptr; ~_Rope_self_destruct_ptr() { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); } # ifdef __STL_USE_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 _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_valid(false), _M_root(__r) {} _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) : _M_pos(__x._M_pos), _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); } }; #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, _Rope_char_ref_proxy <_CharT, __Alloc > __b) { _CharT __tmp = __a; __a = __b; __b = __tmp; } #else // There is no really acceptable way to handle this. The default // definition of swap doesn't work for proxy references. // It can't really be made to work, even with ugly hacks, since // the only unusual operation it uses is the copy constructor, which // is needed for other purposes. We provide a macro for // full specializations, and instantiate the most common case. # define _ROPE_SWAP_SPECIALIZATION(_CharT, __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; \ } _ROPE_SWAP_SPECIALIZATION(char,__STL_DEFAULT_ALLOCATOR(char)) #endif /* !__STL_FUNCTION_TMPL_PARTIAL_ORDER */ template 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) { __stl_assert(0 == __x); } _Rope_char_ptr_proxy& operator= (const _Rope_char_ptr_proxy& __x) { _M_pos = __x._M_pos; _M_root = __x._M_root; return *this; } #ifdef __STL_MEMBER_TEMPLATES template friend bool operator== (const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __x, const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __y); #else friend bool operator== __STL_NULL_TMPL_ARGS (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); #endif _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. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1375 #endif template class _Rope_iterator_base : public random_access_iterator<_CharT, ptrdiff_t> { friend class rope<_CharT,_Alloc>; public: typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; // Borland doesnt 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 _Rope_iterator; template class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> { friend class rope<_CharT,_Alloc>; protected: # ifdef __STL_HAS_NAMESPACES typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; // The one from the base class may not be directly visible. # endif _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 { _M_current_pos = __x._M_current_pos; _M_root = __x._M_root; _M_buf_ptr = 0; } return(*this); } reference operator*() { if (0 == _M_buf_ptr) _S_setcache(*this); return *_M_buf_ptr; } _Rope_const_iterator& operator++() { __GC_CONST _CharT* __next; if (0 != _M_buf_ptr && (__next = _M_buf_ptr + 1) < _M_buf_end) { _M_buf_ptr = __next; ++_M_current_pos; } else { _M_incr(1); } return *this; } _Rope_const_iterator& operator+=(ptrdiff_t __n) { if (__n >= 0) { _M_incr(__n); } else { _M_decr(-__n); } return *this; } _Rope_const_iterator& operator--() { _M_decr(1); return *this; } _Rope_const_iterator& operator-=(ptrdiff_t __n) { if (__n >= 0) { _M_decr(__n); } else { _M_incr(-__n); } return *this; } _Rope_const_iterator operator++(int) { size_t __old_pos = _M_current_pos; _M_incr(1); return _Rope_const_iterator<_CharT,_Alloc>(_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 = _M_current_pos; _M_decr(1); return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos); } #if defined(__STL_MEMBER_TEMPLATES) && defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) template friend _Rope_const_iterator<_CharT2,_Alloc2> operator- (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, ptrdiff_t __n); template friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, ptrdiff_t __n); template friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ (ptrdiff_t __n, const _Rope_const_iterator<_CharT2,_Alloc2>& __x); #else friend _Rope_const_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS (const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n); friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS (const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n); friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS (ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x); #endif reference operator[](size_t __n) { return rope<_CharT,_Alloc>::_S_fetch(_M_root, _M_current_pos + __n); } #if defined(__STL_MEMBER_TEMPLATES) && defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) template friend bool operator== (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, const _Rope_const_iterator<_CharT2,_Alloc2>& __y); template friend bool operator< (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, const _Rope_const_iterator<_CharT2,_Alloc2>& __y); template friend ptrdiff_t operator- (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, const _Rope_const_iterator<_CharT2,_Alloc2>& __y); #else friend bool operator== __STL_NULL_TMPL_ARGS (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y); friend bool operator< __STL_NULL_TMPL_ARGS (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y); friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y); #endif }; template class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> { friend class rope<_CharT,_Alloc>; protected: 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(_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; public: rope<_CharT,_Alloc>& container() { return *_M_root_rope; } _Rope_iterator() { _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(_M_root); } _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos); ~_Rope_iterator() { _RopeRep::_S_unref(_M_root); } _Rope_iterator& operator= (const _Rope_iterator& __x) { _RopeRep* __old = _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 { _M_current_pos = __x._M_current_pos; _M_root = __x._M_root; _M_root_rope = __x._M_root_rope; _M_buf_ptr = 0; } _RopeRep::_S_unref(__old); return(*this); } reference operator*() { _M_check(); if (0 == _M_buf_ptr) { return _Rope_char_ref_proxy<_CharT,_Alloc>( _M_root_rope, _M_current_pos); } else { return _Rope_char_ref_proxy<_CharT,_Alloc>( _M_root_rope, _M_current_pos, *_M_buf_ptr); } } _Rope_iterator& operator++() { _M_incr(1); return *this; } _Rope_iterator& operator+=(ptrdiff_t __n) { if (__n >= 0) { _M_incr(__n); } else { _M_decr(-__n); } return *this; } _Rope_iterator& operator--() { _M_decr(1); return *this; } _Rope_iterator& operator-=(ptrdiff_t __n) { if (__n >= 0) { _M_decr(__n); } else { _M_incr(-__n); } return *this; } _Rope_iterator operator++(int) { size_t __old_pos = _M_current_pos; _M_incr(1); return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); } _Rope_iterator operator--(int) { size_t __old_pos = _M_current_pos; _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, _M_current_pos + __n); } #if defined(__STL_MEMBER_TEMPLATES) && defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) template friend bool operator== (const _Rope_iterator<_CharT2,_Alloc2>& __x, const _Rope_iterator<_CharT2,_Alloc2>& __y); template friend bool operator< (const _Rope_iterator<_CharT2,_Alloc2>& __x, const _Rope_iterator<_CharT2,_Alloc2>& __y); template friend ptrdiff_t operator- (const _Rope_iterator<_CharT2,_Alloc2>& __x, const _Rope_iterator<_CharT2,_Alloc2>& __y); template friend _Rope_iterator<_CharT2,_Alloc2> operator- (const _Rope_iterator<_CharT2,_Alloc2>& __x, ptrdiff_t __n); template friend _Rope_iterator<_CharT2,_Alloc2> operator+ (const _Rope_iterator<_CharT2,_Alloc2>& __x, ptrdiff_t __n); template friend _Rope_iterator<_CharT2,_Alloc2> operator+ (ptrdiff_t __n, const _Rope_iterator<_CharT2,_Alloc2>& __x); #else friend bool operator== __STL_NULL_TMPL_ARGS (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y); friend bool operator< __STL_NULL_TMPL_ARGS (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y); friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y); friend _Rope_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS (const _Rope_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n); friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS (const _Rope_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n); friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS (ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x); #endif }; #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1375 #endif // The rope base class encapsulates // the differences between SGI-style allocators and standard-conforming // allocators. #ifdef __STL_USE_STD_ALLOCATORS // Base class for ordinary allocators. template class _Rope_alloc_base { public: typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_data_allocator; } _Rope_alloc_base(_RopeRep *__t, const allocator_type& __a) : _M_tree_ptr(__t), _M_data_allocator(__a) {} _Rope_alloc_base(const allocator_type& __a) : _M_data_allocator(__a) {} protected: // The only data members of a rope: allocator_type _M_data_allocator; _RopeRep* _M_tree_ptr; # define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef typename \ _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ _Tp* __name##_allocate(size_t __n) const \ { return __name##Allocator(_M_data_allocator).allocate(__n); } \ void __name##_deallocate(_Tp *__p, size_t __n) const \ { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } __ROPE_DEFINE_ALLOCS(_Allocator) # undef __ROPE_DEFINE_ALLOC }; // Specialization for allocators that have the property that we don't // actually have to store an allocator object. template class _Rope_alloc_base<_CharT,_Allocator,true> { public: typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Rope_alloc_base(_RopeRep *__t, const allocator_type&) : _M_tree_ptr(__t) {} _Rope_alloc_base(const allocator_type&) {} protected: // The only data member of a rope: _RopeRep *_M_tree_ptr; # define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef typename \ _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ typedef typename \ _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ 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(_Allocator) # undef __ROPE_DEFINE_ALLOC }; template struct _Rope_base : public _Rope_alloc_base<_CharT,_Alloc, _Alloc_traits<_CharT,_Alloc>::_S_instanceless> { typedef _Rope_alloc_base<_CharT,_Alloc, _Alloc_traits<_CharT,_Alloc>::_S_instanceless> _Base; typedef typename _Base::allocator_type allocator_type; 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& __a) : _Base(__t, __a) {} _Rope_base(const allocator_type& __a) : _Base(__a) {} }; #else /* !__STL_USE_STD_ALLOCATORS */ template class _Rope_base { public: typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; typedef _Alloc allocator_type; static allocator_type get_allocator() { return allocator_type(); } _Rope_base(_RopeRep * __t, const allocator_type&) : _M_tree_ptr(__t) {} _Rope_base(const allocator_type&) {} protected: // The only data member of a rope: _RopeRep* _M_tree_ptr; # define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef simple_alloc<_Tp, _Alloc> __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 }; #endif /* __STL_USE_STD_ALLOCATORS */ template 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; # ifdef __STL_USE_NAMESPACES using _Base::_M_tree_ptr; # endif 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 // relevent 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, _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) { # ifdef __STL_USE_STD_ALLOCATORS _RopeLeaf* __space = _LAllocator(__a).allocate(1); # else _RopeLeaf* __space = _L_allocate(1); # endif return new(__space) _RopeLeaf(__s, __size, __a); } static _RopeConcatenation* _S_new_RopeConcatenation( _RopeRep* __left, _RopeRep* __right, allocator_type __a) { # ifdef __STL_USE_STD_ALLOCATORS _RopeConcatenation* __space = _CAllocator(__a).allocate(1); # else _RopeConcatenation* __space = _C_allocate(1); # endif return new(__space) _RopeConcatenation(__left, __right, __a); } static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, size_t __size, bool __d, allocator_type __a) { # ifdef __STL_USE_STD_ALLOCATORS _RopeFunction* __space = _FAllocator(__a).allocate(1); # else _RopeFunction* __space = _F_allocate(1); # endif 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) { # ifdef __STL_USE_STD_ALLOCATORS _RopeSubstring* __space = _SAllocator(__a).allocate(1); # else _RopeSubstring* __space = _S_allocate(1); # endif return new(__space) _RopeSubstring(__b, __s, __l, __a); } # ifdef __STL_USE_STD_ALLOCATORS 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) # else static _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr2(const _CharT* __s, size_t __size) # define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ _S_RopeLeaf_from_unowned_char_ptr2(__s, __size) # endif { if (0 == __size) return 0; # ifdef __STL_USE_STD_ALLOCATORS _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); # else _CharT* __buf = _Data_allocate(_S_rounded_up_size(__size)); allocator_type __a = allocator_type(); # endif uninitialized_copy_n(__s, __size, __buf); _S_cond_store_eos(__buf[__size]); __STL_TRY { return _S_new_RopeLeaf(__buf, __size, __a); } __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, __size, __a)) } // 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[_RopeRep::_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 == _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(_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 = _Data_allocate(_S_rounded_up_size(1)); construct(__buf, __c); __STL_TRY { _M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); } __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, 1, __a)) } 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) { _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(_M_tree_ptr); } ~rope() { _S_unref(_M_tree_ptr); } rope& operator=(const rope& __x) { _RopeRep* __old = _M_tree_ptr; # ifdef __STL_USE_STD_ALLOCATORS __stl_assert(get_allocator() == __x.get_allocator()); # endif _M_tree_ptr = __x._M_tree_ptr; _S_ref(_M_tree_ptr); _S_unref(__old); return(*this); } void clear() { _S_unref(_M_tree_ptr); _M_tree_ptr = 0; } void push_back(_CharT __x) { _RopeRep* __old = _M_tree_ptr; _M_tree_ptr = _S_destr_concat_char_iter(_M_tree_ptr, &__x, 1); _S_unref(__old); } void pop_back() { _RopeRep* __old = _M_tree_ptr; _M_tree_ptr = _S_substring(_M_tree_ptr, 0, _M_tree_ptr->_M_size - 1); _S_unref(__old); } _CharT back() const { return _S_fetch(_M_tree_ptr, _M_tree_ptr->_M_size - 1); } void push_front(_CharT __x) { _RopeRep* __old = _M_tree_ptr; _RopeRep* __left = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, get_allocator()); __STL_TRY { _M_tree_ptr = _S_concat(__left, _M_tree_ptr); _S_unref(__old); _S_unref(__left); } __STL_UNWIND(_S_unref(__left)) } void pop_front() { _RopeRep* __old = _M_tree_ptr; _M_tree_ptr = _S_substring(_M_tree_ptr, 1, _M_tree_ptr->_M_size); _S_unref(__old); } _CharT front() const { return _S_fetch(_M_tree_ptr, 0); } void balance() { _RopeRep* __old = _M_tree_ptr; _M_tree_ptr = _S_balance(_M_tree_ptr); _S_unref(__old); } void copy(_CharT* __buffer) const { destroy(__buffer, __buffer + size()); _S_flatten(_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); _S_flatten(_M_tree_ptr, __pos, __len, __buffer); return __len; } // Print to stdout, exposing structure. May be useful for // performance debugging. void dump() { _S_dump(_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 == _M_tree_ptr) return; if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && ((_RopeLeaf*)_M_tree_ptr)->_M_data == _M_tree_ptr->_M_c_string) { // Representation shared return; } # ifndef __GC _M_tree_ptr->_M_free_c_string(); # endif _M_tree_ptr->_M_c_string = 0; } _CharT operator[] (size_type __pos) const { return _S_fetch(_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(_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(_M_tree_ptr, 0)); } const_iterator end() const { return(const_iterator(_M_tree_ptr, size())); } const_iterator const_end() const { return(const_iterator(_M_tree_ptr, size())); } size_type size() const { return(0 == _M_tree_ptr? 0 : _M_tree_ptr->_M_size); } size_type length() const { return size(); } size_type max_size() const { return _S_min_len[_RopeRep::_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. } # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; # else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator const_reverse_iterator; # endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 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()); } #if defined(__STL_MEMBER_TEMPLATES) && defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) template friend rope<_CharT2,_Alloc2> operator+ (const rope<_CharT2,_Alloc2>& __left, const rope<_CharT2,_Alloc2>& __right); template friend rope<_CharT2,_Alloc2> operator+ (const rope<_CharT2,_Alloc2>& __left, const _CharT2* __right); template friend rope<_CharT2,_Alloc2> operator+ (const rope<_CharT2,_Alloc2>& __left, _CharT2 __right); #else friend rope<_CharT,_Alloc> __STD_QUALIFIER operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, const rope<_CharT,_Alloc>& __right); friend rope<_CharT,_Alloc> __STD_QUALIFIER operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, const _CharT* __right); friend rope<_CharT,_Alloc> __STD_QUALIFIER operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, _CharT __right); #endif // 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(_M_tree_ptr, __iter, __n); _S_unref(_M_tree_ptr); _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(_M_tree_ptr, __s, __e - __s); _S_unref(_M_tree_ptr); _M_tree_ptr = __result; return *this; } rope& append(const_iterator __s, const_iterator __e) { __stl_assert(__s._M_root == __e._M_root); # ifdef __STL_USE_STD_ALLOCATORS __stl_assert(get_allocator() == __s._M_root->get_allocator()); # endif _Self_destruct_ptr __appendee(_S_substring( __s._M_root, __s._M_current_pos, __e._M_current_pos)); _RopeRep* __result = _S_concat(_M_tree_ptr, (_RopeRep*)__appendee); _S_unref(_M_tree_ptr); _M_tree_ptr = __result; return *this; } rope& append(_CharT __c) { _RopeRep* __result = _S_destr_concat_char_iter(_M_tree_ptr, &__c, 1); _S_unref(_M_tree_ptr); _M_tree_ptr = __result; return *this; } rope& append() { return append(_CharT()); } // XXX why? rope& append(const rope& __y) { # ifdef __STL_USE_STD_ALLOCATORS __stl_assert(__y.get_allocator() == get_allocator()); # endif _RopeRep* __result = _S_concat(_M_tree_ptr, __y._M_tree_ptr); _S_unref(_M_tree_ptr); _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) { # ifdef __STL_USE_STD_ALLOCATORS __stl_assert(get_allocator() == __b.get_allocator()); # endif _RopeRep* __tmp = _M_tree_ptr; _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; # ifdef __STL_USE_STD_ALLOCATORS __stl_assert(__old->get_allocator() == __r->get_allocator()); # endif 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(_M_tree_ptr, __p, __p, __r._M_tree_ptr); # ifdef __STL_USE_STD_ALLOCATORS __stl_assert(get_allocator() == __r.get_allocator()); # endif _S_unref(_M_tree_ptr); _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(_M_tree_ptr, 0, __p)); _Self_destruct_ptr __right(_S_substring(_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(_M_tree_ptr); _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(_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); _S_unref(_M_tree_ptr); _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(_M_tree_ptr, __p, __p + __n, 0); _S_unref(_M_tree_ptr); _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(_M_tree_ptr, __start, __start + __len)); } rope substr(iterator __start, iterator __end) const { return rope<_CharT,_Alloc>( _S_substring(_M_tree_ptr, __start.index(), __end.index())); } rope substr(iterator __start) const { size_t __pos = __start.index(); return rope<_CharT,_Alloc>( _S_substring(_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(_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(_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 = 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())); } # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator reverse_iterator; # else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator reverse_iterator; # endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 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 const rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = (size_type)(-1); template 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 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); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!= (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y) { return !(__x == __y); } template inline bool operator> (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y) { return __y < __x; } template inline bool operator<= (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y) { return !(__y < __x); } template inline bool operator>= (const _Rope_const_iterator<_CharT,_Alloc>& __x, const _Rope_const_iterator<_CharT,_Alloc>& __y) { return !(__x < __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template 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 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 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 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 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 inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y) { return (__x._M_current_pos < __y._M_current_pos); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!= (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y) { return !(__x == __y); } template inline bool operator> (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y) { return __y < __x; } template inline bool operator<= (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y) { return !(__y < __x); } template inline bool operator>= (const _Rope_iterator<_CharT,_Alloc>& __x, const _Rope_iterator<_CharT,_Alloc>& __y) { return !(__x < __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template 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 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 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 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 inline rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, const rope<_CharT,_Alloc>& __right) { # ifdef __STL_USE_STD_ALLOCATORS __stl_assert(__left.get_allocator() == __right.get_allocator()); # endif return rope<_CharT,_Alloc>( rope<_CharT,_Alloc>::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); // Inlining this should make it possible to keep __left and // __right in registers. } template inline rope<_CharT,_Alloc>& operator+= (rope<_CharT,_Alloc>& __left, const rope<_CharT,_Alloc>& __right) { __left.append(__right); return __left; } template inline rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, const _CharT* __right) { size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right); return rope<_CharT,_Alloc>( rope<_CharT,_Alloc>::_S_concat_char_iter( __left._M_tree_ptr, __right, __rlen)); } template inline rope<_CharT,_Alloc>& operator+= (rope<_CharT,_Alloc>& __left, const _CharT* __right) { __left.append(__right); return __left; } template inline rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) { return rope<_CharT,_Alloc>( rope<_CharT,_Alloc>::_S_concat_char_iter( __left._M_tree_ptr, &__right, 1)); } template inline rope<_CharT,_Alloc>& operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) { __left.append(__right); return __left; } template bool operator< (const rope<_CharT,_Alloc>& __left, const rope<_CharT,_Alloc>& __right) { return __left.compare(__right) < 0; } template bool operator== (const rope<_CharT,_Alloc>& __left, const rope<_CharT,_Alloc>& __right) { return __left.compare(__right) == 0; } template 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); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { return !(__x == __y); } template inline bool operator> (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { return __y < __x; } template inline bool operator<= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { return !(__y < __x); } template inline bool operator>= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { return !(__x < __y); } template inline bool operator!= (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { return !(__x == __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifdef __STL_USE_NEW_IOSTREAMS template basic_ostream<_CharT, _Traits>& operator<< (basic_ostream<_CharT, _Traits>& __o, const rope<_CharT, _Alloc>& __r); #else template ostream& operator<< (ostream& __o, const rope<_CharT, _Alloc>& __r); #endif typedef rope crope; typedef rope 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); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(rope<_CharT,_Alloc>& __x, rope<_CharT,_Alloc>& __y) { __x.swap(__y); } #else inline void swap(crope __x, crope __y) { __x.swap(__y); } inline void swap(wrope __x, wrope __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Hash functions should probably be revisited later: __STL_TEMPLATE_NULL struct hash { 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; } }; __STL_TEMPLATE_NULL struct hash { 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; } }; #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE # include # endif /* __SGI_STL_INTERNAL_ROPE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_set.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_SET_H #define __SGI_STL_INTERNAL_SET_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // Forward declarations of operators < and ==, needed for friend declaration. template ), class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > class set; template inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y); template inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y); template class set { // requirements: __STL_CLASS_REQUIRES(_Key, _Assignable); __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key); public: // typedefs: typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; private: typedef _Rb_tree, key_compare, _Alloc> _Rep_type; _Rep_type _M_t; // red-black tree representing set public: typedef typename _Rep_type::const_pointer pointer; typedef typename _Rep_type::const_pointer const_pointer; typedef typename _Rep_type::const_reference reference; typedef typename _Rep_type::const_reference const_reference; 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; typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation set() : _M_t(_Compare(), allocator_type()) {} explicit set(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES template set(_InputIterator __first, _InputIterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } template set(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #else set(const value_type* __first, const value_type* __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } set(const value_type* __first, const value_type* __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } set(const_iterator __first, const_iterator __last) : _M_t(_Compare(), allocator_type()) { _M_t.insert_unique(__first, __last); } set(const_iterator __first, const_iterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ set(const set<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} set<_Key,_Compare,_Alloc>& operator=(const set<_Key, _Compare, _Alloc>& __x) { _M_t = __x._M_t; return *this; } // accessors: key_compare key_comp() const { return _M_t.key_comp(); } value_compare value_comp() const { return _M_t.key_comp(); } allocator_type get_allocator() const { return _M_t.get_allocator(); } iterator begin() const { return _M_t.begin(); } iterator end() const { return _M_t.end(); } reverse_iterator rbegin() const { return _M_t.rbegin(); } reverse_iterator rend() const { return _M_t.rend(); } bool empty() const { return _M_t.empty(); } size_type size() const { return _M_t.size(); } size_type max_size() const { return _M_t.max_size(); } void swap(set<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase pair insert(const value_type& __x) { pair __p = _M_t.insert_unique(__x); return pair(__p.first, __p.second); } iterator insert(iterator __position, const value_type& __x) { typedef typename _Rep_type::iterator _Rep_iterator; return _M_t.insert_unique((_Rep_iterator&)__position, __x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(_InputIterator __first, _InputIterator __last) { _M_t.insert_unique(__first, __last); } #else void insert(const_iterator __first, const_iterator __last) { _M_t.insert_unique(__first, __last); } void insert(const value_type* __first, const value_type* __last) { _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator __position) { typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__position); } size_type erase(const key_type& __x) { return _M_t.erase(__x); } void erase(iterator __first, iterator __last) { typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); } void clear() { _M_t.clear(); } // set operations: iterator find(const key_type& __x) const { return _M_t.find(__x); } size_type count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } iterator lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } iterator upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } pair equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } #ifdef __STL_TEMPLATE_FRIENDS template friend bool operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); template friend bool operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); #else /* __STL_TEMPLATE_FRIENDS */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const set&, const set&); friend bool __STD_QUALIFIER operator< __STL_NULL_TMPL_ARGS (const set&, const set&); #endif /* __STL_TEMPLATE_FRIENDS */ }; template inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return __x._M_t == __y._M_t; } template inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return !(__x == __y); } template inline bool operator>(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return __y < __x; } template inline bool operator<=(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return !(__y < __x); } template inline bool operator>=(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) { return !(__x < __y); } template inline void swap(set<_Key,_Compare,_Alloc>& __x, set<_Key,_Compare,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_SET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_slist.h ================================================ /* * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_SLIST_H #define __SGI_STL_INTERNAL_SLIST_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif 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 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 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 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; _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; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ _Self& operator++() { _M_incr(); return *this; } _Self operator++(int) { _Self __tmp = *this; _M_incr(); return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION inline ptrdiff_t* distance_type(const _Slist_iterator_base&) { return 0; } inline forward_iterator_tag iterator_category(const _Slist_iterator_base&) { return forward_iterator_tag(); } template inline _Tp* value_type(const _Slist_iterator<_Tp, _Ref, _Ptr>&) { return 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // Base class that encapsulates details of allocators. Three cases: // an ordinary standard-conforming allocator, a standard-conforming // allocator with no non-static data, and an SGI-style allocator. // This complexity is necessary only because we're worrying about backward // compatibility and because we want to avoid wasting storage on an // allocator instance if it isn't necessary. #ifdef __STL_USE_STD_ALLOCATORS // Base for general standard-conforming allocators. template class _Slist_alloc_base { public: typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_node_allocator; } _Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {} protected: _Slist_node<_Tp>* _M_get_node() { return _M_node_allocator.allocate(1); } void _M_put_node(_Slist_node<_Tp>* __p) { _M_node_allocator.deallocate(__p, 1); } protected: typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type _M_node_allocator; _Slist_node_base _M_head; }; // Specialization for instanceless allocators. template class _Slist_alloc_base<_Tp,_Allocator, true> { public: typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Slist_alloc_base(const allocator_type&) {} protected: typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type _Alloc_type; _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } protected: _Slist_node_base _M_head; }; template struct _Slist_base : public _Slist_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { typedef _Slist_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base; typedef typename _Base::allocator_type allocator_type; _Slist_base(const allocator_type& __a) : _Base(__a) { this->_M_head._M_next = 0; } ~_Slist_base() { _M_erase_after(&this->_M_head, 0); } 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; destroy(&__next->_M_data); _M_put_node(__next); return __next_next; } _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); }; #else /* __STL_USE_STD_ALLOCATORS */ template struct _Slist_base { typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Slist_base(const allocator_type&) { _M_head._M_next = 0; } ~_Slist_base() { _M_erase_after(&_M_head, 0); } protected: typedef simple_alloc<_Slist_node<_Tp>, _Alloc> _Alloc_type; _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } _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; destroy(&__next->_M_data); _M_put_node(__next); return __next_next; } _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); protected: _Slist_node_base _M_head; }; #endif /* __STL_USE_STD_ALLOCATORS */ template _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; destroy(&__tmp->_M_data); _M_put_node(__tmp); } __before_first->_M_next = __last_node; return __last_node; } template class slist : private _Slist_base<_Tp,_Alloc> { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); 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(); __STL_TRY { construct(&__node->_M_data, __x); __node->_M_next = 0; } __STL_UNWIND(this->_M_put_node(__node)); return __node; } _Node* _M_create_node() { _Node* __node = this->_M_get_node(); __STL_TRY { construct(&__node->_M_data); __node->_M_next = 0; } __STL_UNWIND(this->_M_put_node(__node)); 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()); } #ifdef __STL_MEMBER_TEMPLATES // We don't need any dispatching tricks here, because _M_insert_after_range // already does them. template slist(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_insert_after_range(&this->_M_head, __first, __last); } #else /* __STL_MEMBER_TEMPLATES */ slist(const_iterator __first, const_iterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_insert_after_range(&this->_M_head, __first, __last); } slist(const value_type* __first, const value_type* __last, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_insert_after_range(&this->_M_head, __first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ 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); #ifdef __STL_MEMBER_TEMPLATES template void assign(_InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_assign_dispatch(__first, __last, _Integral()); } template void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign((size_type) __n, (_Tp) __val); } template void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type); #endif /* __STL_MEMBER_TEMPLATES */ 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; 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)); } #ifdef __STL_MEMBER_TEMPLATES // Check whether it's an integral type. If so, it's not an iterator. template void _M_insert_after_range(_Node_base* __pos, _InIter __first, _InIter __last) { typedef typename _Is_integer<_InIter>::_Integral _Integral; _M_insert_after_range(__pos, __first, __last, _Integral()); } template void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, __true_type) { _M_insert_after_fill(__pos, __n, __x); } template void _M_insert_after_range(_Node_base* __pos, _InIter __first, _InIter __last, __false_type) { while (__first != __last) { __pos = __slist_make_link(__pos, _M_create_node(*__first)); ++__first; } } #else /* __STL_MEMBER_TEMPLATES */ void _M_insert_after_range(_Node_base* __pos, const_iterator __first, const_iterator __last) { while (__first != __last) { __pos = __slist_make_link(__pos, _M_create_node(*__first)); ++__first; } } void _M_insert_after_range(_Node_base* __pos, const value_type* __first, const value_type* __last) { while (__first != __last) { __pos = __slist_make_link(__pos, _M_create_node(*__first)); ++__first; } } #endif /* __STL_MEMBER_TEMPLATES */ 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); } #ifdef __STL_MEMBER_TEMPLATES // We don't need any dispatching tricks here, because _M_insert_after_range // already does them. template void insert_after(iterator __pos, _InIter __first, _InIter __last) { _M_insert_after_range(__pos._M_node, __first, __last); } #else /* __STL_MEMBER_TEMPLATES */ void insert_after(iterator __pos, const_iterator __first, const_iterator __last) { _M_insert_after_range(__pos._M_node, __first, __last); } void insert_after(iterator __pos, const value_type* __first, const value_type* __last) { _M_insert_after_range(__pos._M_node, __first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ 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); } #ifdef __STL_MEMBER_TEMPLATES // We don't need any dispatching tricks here, because _M_insert_after_range // already does them. template void insert(iterator __pos, _InIter __first, _InIter __last) { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), __first, __last); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator __pos, const_iterator __first, const_iterator __last) { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), __first, __last); } void insert(iterator __pos, const value_type* __first, const value_type* __last) { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), __first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ 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 (_Node*) this->_M_erase_after(__slist_previous(&this->_M_head, __pos._M_node)); } iterator erase(iterator __first, iterator __last) { return (_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(); #ifdef __STL_MEMBER_TEMPLATES template void remove_if(_Predicate __pred); template void unique(_BinaryPredicate __pred); template void merge(slist&, _StrictWeakOrdering); template void sort(_StrictWeakOrdering __comp); #endif /* __STL_MEMBER_TEMPLATES */ }; template 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 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); } #ifdef __STL_MEMBER_TEMPLATES template template void slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __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); } #endif /* __STL_MEMBER_TEMPLATES */ template 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 inline bool operator<(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { return lexicographical_compare(_SL1.begin(), _SL1.end(), _SL2.begin(), _SL2.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { return !(_SL1 == _SL2); } template inline bool operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { return _SL2 < _SL1; } template inline bool operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { return !(_SL2 < _SL1); } template inline bool operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { return !(_SL1 < _SL2); } template inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template 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 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 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 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 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]); } } #ifdef __STL_MEMBER_TEMPLATES template template 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 template 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 template 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 template 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]); } } #endif /* __STL_MEMBER_TEMPLATES */ // Specialization of insert_iterator so that insertions will be constant // time rather than linear time. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template class insert_iterator > { protected: typedef 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; } }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_SLIST_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_stack.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_STACK_H #define __SGI_STL_INTERNAL_STACK_H #include __STL_BEGIN_NAMESPACE // Forward declarations of operators == and <, needed for friend declaration. template ) > class stack; template bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); template bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); template class stack { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence); typedef typename _Sequence::value_type _Sequence_value_type; __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type); #ifdef __STL_MEMBER_TEMPLATES template friend bool operator== (const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); template friend bool operator< (const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); #else /* __STL_MEMBER_TEMPLATES */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&); friend bool __STD_QUALIFIER operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&); #endif /* __STL_MEMBER_TEMPLATES */ public: typedef typename _Sequence::value_type value_type; typedef typename _Sequence::size_type size_type; typedef _Sequence container_type; typedef typename _Sequence::reference reference; typedef typename _Sequence::const_reference const_reference; protected: _Sequence c; public: stack() : c() {} explicit stack(const _Sequence& __s) : c(__s) {} bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference top() { return c.back(); } const_reference top() const { return c.back(); } void push(const value_type& __x) { c.push_back(__x); } void pop() { c.pop_back(); } }; template bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return __x.c == __y.c; } template bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return __x.c < __y.c; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template bool operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return !(__x == __y); } template bool operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return __y < __x; } template bool operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return !(__y < __x); } template bool operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) { return !(__x < __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_STACK_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_string_fwd.h ================================================ /* * 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 __SGI_STL_STRING_FWD_H #define __SGI_STL_STRING_FWD_H #include #include #include #include __STL_BEGIN_NAMESPACE template , class _Alloc = __STL_DEFAULT_ALLOCATOR(_CharT) > class basic_string; typedef basic_string string; typedef basic_string wstring; static const char* __get_c_string(const string&); __STL_END_NAMESPACE #endif /* __SGI_STL_STRING_FWD_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_tempbuf.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_TEMPBUF_H #define __SGI_STL_INTERNAL_TEMPBUF_H __STL_BEGIN_NAMESPACE template pair<_Tp*, ptrdiff_t> __get_temporary_buffer(ptrdiff_t __len, _Tp*) { if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp))) __len = INT_MAX / sizeof(_Tp); while (__len > 0) { _Tp* __tmp = (_Tp*) malloc((size_t)__len * sizeof(_Tp)); if (__tmp != 0) return pair<_Tp*, ptrdiff_t>(__tmp, __len); __len /= 2; } return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); } #ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS template inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) { return __get_temporary_buffer(__len, (_Tp*) 0); } #endif /* __STL_EXPLICIT_FUNCTION_TMPL_ARGS */ // This overload is not required by the standard; it is an extension. // It is supported for backward compatibility with the HP STL, and // because not all compilers support the language feature (explicit // function template arguments) that is required for the standard // version of get_temporary_buffer. template inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) { return __get_temporary_buffer(__len, (_Tp*) 0); } template void return_temporary_buffer(_Tp* __p) { free(__p); } template class _Temporary_buffer { private: ptrdiff_t _M_original_len; ptrdiff_t _M_len; _Tp* _M_buffer; void _M_allocate_buffer() { _M_original_len = _M_len; _M_buffer = 0; if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp))) _M_len = INT_MAX / sizeof(_Tp); while (_M_len > 0) { _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp)); if (_M_buffer) break; _M_len /= 2; } } void _M_initialize_buffer(const _Tp&, __true_type) {} void _M_initialize_buffer(const _Tp& val, __false_type) { uninitialized_fill_n(_M_buffer, _M_len, val); } public: ptrdiff_t size() const { return _M_len; } ptrdiff_t requested_size() const { return _M_original_len; } _Tp* begin() { return _M_buffer; } _Tp* end() { return _M_buffer + _M_len; } _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) { // Workaround for a __type_traits bug in the pre-7.3 compiler. # if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION < 730 typedef typename __type_traits<_Tp>::is_POD_type _Trivial; # else typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Trivial; # endif __STL_TRY { _M_len = 0; distance(__first, __last, _M_len); _M_allocate_buffer(); if (_M_len > 0) _M_initialize_buffer(*__first, _Trivial()); } __STL_UNWIND(free(_M_buffer); _M_buffer = 0; _M_len = 0); } ~_Temporary_buffer() { destroy(_M_buffer, _M_buffer + _M_len); free(_M_buffer); } private: // Disable copy constructor and assignment operator. _Temporary_buffer(const _Temporary_buffer&) {} void operator=(const _Temporary_buffer&) {} }; // Class temporary_buffer is not part of the standard. It is an extension. template ::value_type #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ > struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> { temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {} ~temporary_buffer() {} }; __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_TEMPBUF_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_threads.h ================================================ /* * 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. */ // WARNING: This is an internal header file, included by other C++ // standard library headers. You should not attempt to use this header // file directly. // Stl_config.h should be included before this file. #ifndef __SGI_STL_INTERNAL_THREADS_H #define __SGI_STL_INTERNAL_THREADS_H // Supported threading models are native SGI, pthreads, uithreads // (similar to pthreads, but based on an earlier draft of the Posix // threads standard), and Win32 threads. Uithread support by Jochen // Schlick, 1999. #if defined(__STL_SGI_THREADS) #include #include #elif defined(__STL_PTHREADS) #include #elif defined(__STL_UITHREADS) #include #include #elif defined(__STL_WIN32THREADS) #include #endif __STL_BEGIN_NAMESPACE // 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. // Hack for SGI o32 compilers. #if defined(__STL_SGI_THREADS) && !defined(__add_and_fetch) && \ (__mips < 3 || !(defined (_ABIN32) || defined(_ABI64))) # define __add_and_fetch(__l,__v) add_then_test((unsigned long*)__l,__v) # define __test_and_set(__l,__v) test_and_set(__l,__v) #endif /* o32 */ struct _Refcount_Base { // The type _RC_t # ifdef __STL_WIN32THREADS typedef long _RC_t; # else typedef size_t _RC_t; #endif // The data member _M_ref_count volatile _RC_t _M_ref_count; // Constructor # ifdef __STL_PTHREADS pthread_mutex_t _M_ref_count_lock; _Refcount_Base(_RC_t __n) : _M_ref_count(__n) { pthread_mutex_init(&_M_ref_count_lock, 0); } # elif defined(__STL_UITHREADS) mutex_t _M_ref_count_lock; _Refcount_Base(_RC_t __n) : _M_ref_count(__n) { mutex_init(&_M_ref_count_lock, USYNC_THREAD, 0); } # else _Refcount_Base(_RC_t __n) : _M_ref_count(__n) {} # endif // _M_incr and _M_decr # ifdef __STL_SGI_THREADS void _M_incr() { __add_and_fetch(&_M_ref_count, 1); } _RC_t _M_decr() { return __add_and_fetch(&_M_ref_count, (size_t) -1); } # elif defined (__STL_WIN32THREADS) void _M_incr() { InterlockedIncrement((_RC_t*)&_M_ref_count); } _RC_t _M_decr() { return InterlockedDecrement((_RC_t*)&_M_ref_count); } # elif defined(__STL_PTHREADS) void _M_incr() { pthread_mutex_lock(&_M_ref_count_lock); ++_M_ref_count; pthread_mutex_unlock(&_M_ref_count_lock); } _RC_t _M_decr() { pthread_mutex_lock(&_M_ref_count_lock); volatile _RC_t __tmp = --_M_ref_count; pthread_mutex_unlock(&_M_ref_count_lock); return __tmp; } # elif defined(__STL_UITHREADS) void _M_incr() { mutex_lock(&_M_ref_count_lock); ++_M_ref_count; mutex_unlock(&_M_ref_count_lock); } _RC_t _M_decr() { mutex_lock(&_M_ref_count_lock); /*volatile*/ _RC_t __tmp = --_M_ref_count; mutex_unlock(&_M_ref_count_lock); return __tmp; } # else /* No threads */ void _M_incr() { ++_M_ref_count; } _RC_t _M_decr() { return --_M_ref_count; } # endif }; // Atomic swap on unsigned long // This is guaranteed to behave as though it were atomic only if all // possibly concurrent updates use _Atomic_swap. // In some cases the operation is emulated with a lock. # ifdef __STL_SGI_THREADS inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { # if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) return test_and_set(__p, __q); # else return __test_and_set(__p, (unsigned long)__q); # endif } # elif defined(__STL_WIN32THREADS) inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { return (unsigned long) InterlockedExchange((LPLONG)__p, (LONG)__q); } # elif defined(__STL_PTHREADS) // We use a template here only to get a unique initialized instance. template struct _Swap_lock_struct { static pthread_mutex_t _S_swap_lock; }; template pthread_mutex_t _Swap_lock_struct<__dummy>::_S_swap_lock = PTHREAD_MUTEX_INITIALIZER; // This should be portable, but performance is expected // to be quite awful. This really needs platform specific // code. inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { pthread_mutex_lock(&_Swap_lock_struct<0>::_S_swap_lock); unsigned long __result = *__p; *__p = __q; pthread_mutex_unlock(&_Swap_lock_struct<0>::_S_swap_lock); return __result; } # elif defined(__STL_UITHREADS) // We use a template here only to get a unique initialized instance. template struct _Swap_lock_struct { static mutex_t _S_swap_lock; }; template mutex_t _Swap_lock_struct<__dummy>::_S_swap_lock = DEFAULTMUTEX; // This should be portable, but performance is expected // to be quite awful. This really needs platform specific // code. inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { mutex_lock(&_Swap_lock_struct<0>::_S_swap_lock); unsigned long __result = *__p; *__p = __q; mutex_unlock(&_Swap_lock_struct<0>::_S_swap_lock); return __result; } # elif defined (__STL_SOLARIS_THREADS) // any better solutions ? // We use a template here only to get a unique initialized instance. template struct _Swap_lock_struct { static mutex_t _S_swap_lock; }; # if ( __STL_STATIC_TEMPLATE_DATA > 0 ) template mutex_t _Swap_lock_struct<__dummy>::_S_swap_lock = DEFAULTMUTEX; # else __DECLARE_INSTANCE(mutex_t, _Swap_lock_struct<__dummy>::_S_swap_lock, =DEFAULTMUTEX); # endif /* ( __STL_STATIC_TEMPLATE_DATA > 0 ) */ // This should be portable, but performance is expected // to be quite awful. This really needs platform specific // code. inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { mutex_lock(&_Swap_lock_struct<0>::_S_swap_lock); unsigned long __result = *__p; *__p = __q; mutex_unlock(&_Swap_lock_struct<0>::_S_swap_lock); return __result; } # else static inline unsigned long _Atomic_swap(unsigned long * __p, unsigned long __q) { unsigned long __result = *__p; *__p = __q; return __result; } # endif // Locking class. Note that this class *does not have a constructor*. // It must be initialized either statically, with __STL_MUTEX_INITIALIZER, // or dynamically, by explicitly calling the _M_initialize member function. // (This is similar to the ways that a pthreads mutex can be initialized.) // There are explicit member functions for acquiring and releasing the lock. // There is no constructor because static initialization is essential for // some uses, and only a class aggregate (see section 8.5.1 of the C++ // standard) can be initialized that way. That means we must have no // constructors, no base classes, no virtual functions, and no private or // protected members. // Helper struct. This is a workaround for various compilers that don't // handle static variables in inline functions properly. template struct _STL_mutex_spin { enum { __low_max = 30, __high_max = 1000 }; // Low if we suspect uniprocessor, high for multiprocessor. static unsigned __max; static unsigned __last; }; template unsigned _STL_mutex_spin<__inst>::__max = _STL_mutex_spin<__inst>::__low_max; template unsigned _STL_mutex_spin<__inst>::__last = 0; struct _STL_mutex_lock { #if defined(__STL_SGI_THREADS) || defined(__STL_WIN32THREADS) // It should be relatively easy to get this to work on any modern Unix. volatile unsigned long _M_lock; void _M_initialize() { _M_lock = 0; } static void _S_nsec_sleep(int __log_nsec) { # ifdef __STL_SGI_THREADS struct timespec __ts; /* Max sleep is 2**27nsec ~ 60msec */ __ts.tv_sec = 0; __ts.tv_nsec = 1 << __log_nsec; nanosleep(&__ts, 0); # elif defined(__STL_WIN32THREADS) if (__log_nsec <= 20) { Sleep(0); } else { Sleep(1 << (__log_nsec - 20)); } # else # error unimplemented # endif } void _M_acquire_lock() { volatile unsigned long* __lock = &this->_M_lock; if (!_Atomic_swap((unsigned long*)__lock, 1)) { return; } unsigned __my_spin_max = _STL_mutex_spin<0>::__max; unsigned __my_last_spins = _STL_mutex_spin<0>::__last; volatile unsigned __junk = 17; // Value doesn't matter. unsigned __i; for (__i = 0; __i < __my_spin_max; __i++) { if (__i < __my_last_spins/2 || *__lock) { __junk *= __junk; __junk *= __junk; __junk *= __junk; __junk *= __junk; continue; } if (!_Atomic_swap((unsigned long*)__lock, 1)) { // got it! // Spinning worked. Thus we're probably not being scheduled // against the other process with which we were contending. // Thus it makes sense to spin longer the next time. _STL_mutex_spin<0>::__last = __i; _STL_mutex_spin<0>::__max = _STL_mutex_spin<0>::__high_max; return; } } // We are probably being scheduled against the other process. Sleep. _STL_mutex_spin<0>::__max = _STL_mutex_spin<0>::__low_max; for (__i = 0 ;; ++__i) { int __log_nsec = __i + 6; if (__log_nsec > 27) __log_nsec = 27; if (!_Atomic_swap((unsigned long *)__lock, 1)) { return; } _S_nsec_sleep(__log_nsec); } } void _M_release_lock() { volatile unsigned long* __lock = &_M_lock; # if defined(__STL_SGI_THREADS) && defined(__GNUC__) && __mips >= 3 asm("sync"); *__lock = 0; # elif defined(__STL_SGI_THREADS) && __mips >= 3 \ && (defined (_ABIN32) || defined(_ABI64)) __lock_release(__lock); # else *__lock = 0; // This is not sufficient on many multiprocessors, since // writes to protected variables and the lock may be reordered. # endif } // We no longer use win32 critical sections. // They appear to be slower in the contention-free case, // and they appear difficult to initialize without introducing a race. #elif defined(__STL_PTHREADS) pthread_mutex_t _M_lock; void _M_initialize() { pthread_mutex_init(&_M_lock, NULL); } void _M_acquire_lock() { pthread_mutex_lock(&_M_lock); } void _M_release_lock() { pthread_mutex_unlock(&_M_lock); } #elif defined(__STL_UITHREADS) mutex_t _M_lock; void _M_initialize() { mutex_init(&_M_lock, USYNC_THREAD, 0); } void _M_acquire_lock() { mutex_lock(&_M_lock); } void _M_release_lock() { mutex_unlock(&_M_lock); } #else /* No threads */ void _M_initialize() {} void _M_acquire_lock() {} void _M_release_lock() {} #endif }; #ifdef __STL_PTHREADS // Pthreads locks must be statically initialized to something other than // the default value of zero. # define __STL_MUTEX_INITIALIZER = { PTHREAD_MUTEX_INITIALIZER } #elif defined(__STL_UITHREADS) // UIthreads locks must be statically initialized to something other than // the default value of zero. # define __STL_MUTEX_INITIALIZER = { DEFAULTMUTEX } #elif defined(__STL_SGI_THREADS) || defined(__STL_WIN32THREADS) # define __STL_MUTEX_INITIALIZER = { 0 } #else # define __STL_MUTEX_INITIALIZER #endif // A locking class that uses _STL_mutex_lock. The constructor takes a // reference to an _STL_mutex_lock, and acquires a lock. The // destructor releases the lock. It's not clear that this is exactly // the right functionality. It will probably change in the future. struct _STL_auto_lock { _STL_mutex_lock& _M_lock; _STL_auto_lock(_STL_mutex_lock& __lock) : _M_lock(__lock) { _M_lock._M_acquire_lock(); } ~_STL_auto_lock() { _M_lock._M_release_lock(); } private: void operator=(const _STL_auto_lock&); _STL_auto_lock(const _STL_auto_lock&); }; __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_THREADS_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_tree.h ================================================ /* * * 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 __SGI_STL_INTERNAL_TREE_H #define __SGI_STL_INTERNAL_TREE_H /* 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. */ #include #include #include #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1375 #endif typedef bool _Rb_tree_Color_type; const _Rb_tree_Color_type _S_rb_tree_red = false; const _Rb_tree_Color_type _S_rb_tree_black = true; struct _Rb_tree_node_base { typedef _Rb_tree_Color_type _Color_type; typedef _Rb_tree_node_base* _Base_ptr; _Color_type _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 _Base_ptr _S_maximum(_Base_ptr __x) { while (__x->_M_right != 0) __x = __x->_M_right; return __x; } }; template struct _Rb_tree_node : public _Rb_tree_node_base { typedef _Rb_tree_node<_Value>* _Link_type; _Value _M_value_field; }; struct _Rb_tree_base_iterator { typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; typedef bidirectional_iterator_tag iterator_category; typedef ptrdiff_t difference_type; _Base_ptr _M_node; void _M_increment() { if (_M_node->_M_right != 0) { _M_node = _M_node->_M_right; while (_M_node->_M_left != 0) _M_node = _M_node->_M_left; } else { _Base_ptr __y = _M_node->_M_parent; while (_M_node == __y->_M_right) { _M_node = __y; __y = __y->_M_parent; } if (_M_node->_M_right != __y) _M_node = __y; } } void _M_decrement() { if (_M_node->_M_color == _S_rb_tree_red && _M_node->_M_parent->_M_parent == _M_node) _M_node = _M_node->_M_right; else if (_M_node->_M_left != 0) { _Base_ptr __y = _M_node->_M_left; while (__y->_M_right != 0) __y = __y->_M_right; _M_node = __y; } else { _Base_ptr __y = _M_node->_M_parent; while (_M_node == __y->_M_left) { _M_node = __y; __y = __y->_M_parent; } _M_node = __y; } } }; template struct _Rb_tree_iterator : public _Rb_tree_base_iterator { typedef _Value value_type; typedef _Ref reference; typedef _Ptr pointer; typedef _Rb_tree_iterator<_Value, _Value&, _Value*> iterator; typedef _Rb_tree_iterator<_Value, const _Value&, const _Value*> const_iterator; typedef _Rb_tree_iterator<_Value, _Ref, _Ptr> _Self; typedef _Rb_tree_node<_Value>* _Link_type; _Rb_tree_iterator() {} _Rb_tree_iterator(_Link_type __x) { _M_node = __x; } _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; } reference operator*() const { return _Link_type(_M_node)->_M_value_field; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ _Self& operator++() { _M_increment(); return *this; } _Self operator++(int) { _Self __tmp = *this; _M_increment(); return __tmp; } _Self& operator--() { _M_decrement(); return *this; } _Self operator--(int) { _Self __tmp = *this; _M_decrement(); return __tmp; } }; inline bool operator==(const _Rb_tree_base_iterator& __x, const _Rb_tree_base_iterator& __y) { return __x._M_node == __y._M_node; } inline bool operator!=(const _Rb_tree_base_iterator& __x, const _Rb_tree_base_iterator& __y) { return __x._M_node != __y._M_node; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION inline bidirectional_iterator_tag iterator_category(const _Rb_tree_base_iterator&) { return bidirectional_iterator_tag(); } inline _Rb_tree_base_iterator::difference_type* distance_type(const _Rb_tree_base_iterator&) { return (_Rb_tree_base_iterator::difference_type*) 0; } template inline _Value* value_type(const _Rb_tree_iterator<_Value, _Ref, _Ptr>&) { return (_Value*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ inline void _Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) { _Rb_tree_node_base* __y = __x->_M_right; __x->_M_right = __y->_M_left; if (__y->_M_left !=0) __y->_M_left->_M_parent = __x; __y->_M_parent = __x->_M_parent; if (__x == __root) __root = __y; else if (__x == __x->_M_parent->_M_left) __x->_M_parent->_M_left = __y; else __x->_M_parent->_M_right = __y; __y->_M_left = __x; __x->_M_parent = __y; } inline void _Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) { _Rb_tree_node_base* __y = __x->_M_left; __x->_M_left = __y->_M_right; if (__y->_M_right != 0) __y->_M_right->_M_parent = __x; __y->_M_parent = __x->_M_parent; if (__x == __root) __root = __y; else if (__x == __x->_M_parent->_M_right) __x->_M_parent->_M_right = __y; else __x->_M_parent->_M_left = __y; __y->_M_right = __x; __x->_M_parent = __y; } inline void _Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) { __x->_M_color = _S_rb_tree_red; while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) { if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) { _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right; if (__y && __y->_M_color == _S_rb_tree_red) { __x->_M_parent->_M_color = _S_rb_tree_black; __y->_M_color = _S_rb_tree_black; __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; __x = __x->_M_parent->_M_parent; } else { if (__x == __x->_M_parent->_M_right) { __x = __x->_M_parent; _Rb_tree_rotate_left(__x, __root); } __x->_M_parent->_M_color = _S_rb_tree_black; __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root); } } else { _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left; if (__y && __y->_M_color == _S_rb_tree_red) { __x->_M_parent->_M_color = _S_rb_tree_black; __y->_M_color = _S_rb_tree_black; __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; __x = __x->_M_parent->_M_parent; } else { if (__x == __x->_M_parent->_M_left) { __x = __x->_M_parent; _Rb_tree_rotate_right(__x, __root); } __x->_M_parent->_M_color = _S_rb_tree_black; __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root); } } } __root->_M_color = _S_rb_tree_black; } inline _Rb_tree_node_base* _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z, _Rb_tree_node_base*& __root, _Rb_tree_node_base*& __leftmost, _Rb_tree_node_base*& __rightmost) { _Rb_tree_node_base* __y = __z; _Rb_tree_node_base* __x = 0; _Rb_tree_node_base* __x_parent = 0; if (__y->_M_left == 0) // __z has at most one non-null child. y == z. __x = __y->_M_right; // __x might be null. else if (__y->_M_right == 0) // __z has exactly one non-null child. y == z. __x = __y->_M_left; // __x is not null. else { // __z has two non-null children. Set __y to __y = __y->_M_right; // __z's successor. __x might be null. while (__y->_M_left != 0) __y = __y->_M_left; __x = __y->_M_right; } if (__y != __z) { // relink y in place of z. y is z's successor __z->_M_left->_M_parent = __y; __y->_M_left = __z->_M_left; if (__y != __z->_M_right) { __x_parent = __y->_M_parent; if (__x) __x->_M_parent = __y->_M_parent; __y->_M_parent->_M_left = __x; // __y must be a child of _M_left __y->_M_right = __z->_M_right; __z->_M_right->_M_parent = __y; } else __x_parent = __y; if (__root == __z) __root = __y; else if (__z->_M_parent->_M_left == __z) __z->_M_parent->_M_left = __y; else __z->_M_parent->_M_right = __y; __y->_M_parent = __z->_M_parent; __STD::swap(__y->_M_color, __z->_M_color); __y = __z; // __y now points to node to be actually deleted } else { // __y == __z __x_parent = __y->_M_parent; if (__x) __x->_M_parent = __y->_M_parent; if (__root == __z) __root = __x; else if (__z->_M_parent->_M_left == __z) __z->_M_parent->_M_left = __x; else __z->_M_parent->_M_right = __x; if (__leftmost == __z) if (__z->_M_right == 0) // __z->_M_left must be null also __leftmost = __z->_M_parent; // makes __leftmost == _M_header if __z == __root else __leftmost = _Rb_tree_node_base::_S_minimum(__x); if (__rightmost == __z) if (__z->_M_left == 0) // __z->_M_right must be null also __rightmost = __z->_M_parent; // makes __rightmost == _M_header if __z == __root else // __x == __z->_M_left __rightmost = _Rb_tree_node_base::_S_maximum(__x); } if (__y->_M_color != _S_rb_tree_red) { while (__x != __root && (__x == 0 || __x->_M_color == _S_rb_tree_black)) if (__x == __x_parent->_M_left) { _Rb_tree_node_base* __w = __x_parent->_M_right; if (__w->_M_color == _S_rb_tree_red) { __w->_M_color = _S_rb_tree_black; __x_parent->_M_color = _S_rb_tree_red; _Rb_tree_rotate_left(__x_parent, __root); __w = __x_parent->_M_right; } if ((__w->_M_left == 0 || __w->_M_left->_M_color == _S_rb_tree_black) && (__w->_M_right == 0 || __w->_M_right->_M_color == _S_rb_tree_black)) { __w->_M_color = _S_rb_tree_red; __x = __x_parent; __x_parent = __x_parent->_M_parent; } else { if (__w->_M_right == 0 || __w->_M_right->_M_color == _S_rb_tree_black) { if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; __w->_M_color = _S_rb_tree_red; _Rb_tree_rotate_right(__w, __root); __w = __x_parent->_M_right; } __w->_M_color = __x_parent->_M_color; __x_parent->_M_color = _S_rb_tree_black; if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; _Rb_tree_rotate_left(__x_parent, __root); break; } } else { // same as above, with _M_right <-> _M_left. _Rb_tree_node_base* __w = __x_parent->_M_left; if (__w->_M_color == _S_rb_tree_red) { __w->_M_color = _S_rb_tree_black; __x_parent->_M_color = _S_rb_tree_red; _Rb_tree_rotate_right(__x_parent, __root); __w = __x_parent->_M_left; } if ((__w->_M_right == 0 || __w->_M_right->_M_color == _S_rb_tree_black) && (__w->_M_left == 0 || __w->_M_left->_M_color == _S_rb_tree_black)) { __w->_M_color = _S_rb_tree_red; __x = __x_parent; __x_parent = __x_parent->_M_parent; } else { if (__w->_M_left == 0 || __w->_M_left->_M_color == _S_rb_tree_black) { if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; __w->_M_color = _S_rb_tree_red; _Rb_tree_rotate_left(__w, __root); __w = __x_parent->_M_left; } __w->_M_color = __x_parent->_M_color; __x_parent->_M_color = _S_rb_tree_black; if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; _Rb_tree_rotate_right(__x_parent, __root); break; } } if (__x) __x->_M_color = _S_rb_tree_black; } return __y; } // Base class to encapsulate the differences between old SGI-style // allocators and standard-conforming allocators. In order to avoid // having an empty base class, we arbitrarily move one of rb_tree's // data members into the base class. #ifdef __STL_USE_STD_ALLOCATORS // _Base for general standard-conforming allocators. template class _Rb_tree_alloc_base { public: typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_node_allocator; } _Rb_tree_alloc_base(const allocator_type& __a) : _M_node_allocator(__a), _M_header(0) {} protected: typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type _M_node_allocator; _Rb_tree_node<_Tp>* _M_header; _Rb_tree_node<_Tp>* _M_get_node() { return _M_node_allocator.allocate(1); } void _M_put_node(_Rb_tree_node<_Tp>* __p) { _M_node_allocator.deallocate(__p, 1); } }; // Specialization for instanceless allocators. template class _Rb_tree_alloc_base<_Tp, _Alloc, true> { public: typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {} protected: _Rb_tree_node<_Tp>* _M_header; typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type _Alloc_type; _Rb_tree_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } void _M_put_node(_Rb_tree_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } }; template struct _Rb_tree_base : public _Rb_tree_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { typedef _Rb_tree_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base; typedef typename _Base::allocator_type allocator_type; _Rb_tree_base(const allocator_type& __a) : _Base(__a) { _M_header = _M_get_node(); } ~_Rb_tree_base() { _M_put_node(_M_header); } }; #else /* __STL_USE_STD_ALLOCATORS */ template struct _Rb_tree_base { typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Rb_tree_base(const allocator_type&) : _M_header(0) { _M_header = _M_get_node(); } ~_Rb_tree_base() { _M_put_node(_M_header); } protected: _Rb_tree_node<_Tp>* _M_header; typedef simple_alloc<_Rb_tree_node<_Tp>, _Alloc> _Alloc_type; _Rb_tree_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } void _M_put_node(_Rb_tree_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } }; #endif /* __STL_USE_STD_ALLOCATORS */ template class _Rb_tree : protected _Rb_tree_base<_Value, _Alloc> { typedef _Rb_tree_base<_Value, _Alloc> _Base; protected: typedef _Rb_tree_node_base* _Base_ptr; typedef _Rb_tree_node<_Value> _Rb_tree_node; typedef _Rb_tree_Color_type _Color_type; public: typedef _Key key_type; typedef _Value 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 size_t size_type; typedef ptrdiff_t difference_type; typedef typename _Base::allocator_type allocator_type; allocator_type get_allocator() const { return _Base::get_allocator(); } protected: #ifdef __STL_USE_NAMESPACES using _Base::_M_get_node; using _Base::_M_put_node; using _Base::_M_header; #endif /* __STL_USE_NAMESPACES */ protected: _Link_type _M_create_node(const value_type& __x) { _Link_type __tmp = _M_get_node(); __STL_TRY { construct(&__tmp->_M_value_field, __x); } __STL_UNWIND(_M_put_node(__tmp)); return __tmp; } _Link_type _M_clone_node(_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 destroy_node(_Link_type __p) { destroy(&__p->_M_value_field); _M_put_node(__p); } protected: size_type _M_node_count; // keeps track of size of tree _Compare _M_key_compare; _Link_type& _M_root() const { return (_Link_type&) _M_header->_M_parent; } _Link_type& _M_leftmost() const { return (_Link_type&) _M_header->_M_left; } _Link_type& _M_rightmost() const { return (_Link_type&) _M_header->_M_right; } static _Link_type& _S_left(_Link_type __x) { return (_Link_type&)(__x->_M_left); } static _Link_type& _S_right(_Link_type __x) { return (_Link_type&)(__x->_M_right); } static _Link_type& _S_parent(_Link_type __x) { return (_Link_type&)(__x->_M_parent); } static reference _S_value(_Link_type __x) { return __x->_M_value_field; } static const _Key& _S_key(_Link_type __x) { return _KeyOfValue()(_S_value(__x)); } static _Color_type& _S_color(_Link_type __x) { return (_Color_type&)(__x->_M_color); } static _Link_type& _S_left(_Base_ptr __x) { return (_Link_type&)(__x->_M_left); } static _Link_type& _S_right(_Base_ptr __x) { return (_Link_type&)(__x->_M_right); } static _Link_type& _S_parent(_Base_ptr __x) { return (_Link_type&)(__x->_M_parent); } static reference _S_value(_Base_ptr __x) { return ((_Link_type)__x)->_M_value_field; } static const _Key& _S_key(_Base_ptr __x) { return _KeyOfValue()(_S_value(_Link_type(__x)));} static _Color_type& _S_color(_Base_ptr __x) { return (_Color_type&)(_Link_type(__x)->_M_color); } static _Link_type _S_minimum(_Link_type __x) { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); } static _Link_type _S_maximum(_Link_type __x) { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); } public: typedef _Rb_tree_iterator iterator; typedef _Rb_tree_iterator const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_bidirectional_iterator reverse_iterator; typedef reverse_bidirectional_iterator const_reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ private: iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); _Link_type _M_copy(_Link_type __x, _Link_type __p); void _M_erase(_Link_type __x); public: // allocation/deallocation _Rb_tree() : _Base(allocator_type()), _M_node_count(0), _M_key_compare() { _M_empty_initialize(); } _Rb_tree(const _Compare& __comp) : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp) { _M_empty_initialize(); } _Rb_tree(const _Compare& __comp, const allocator_type& __a) : _Base(__a), _M_node_count(0), _M_key_compare(__comp) { _M_empty_initialize(); } _Rb_tree(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) : _Base(__x.get_allocator()), _M_node_count(0), _M_key_compare(__x._M_key_compare) { if (__x._M_root() == 0) _M_empty_initialize(); else { _S_color(_M_header) = _S_rb_tree_red; _M_root() = _M_copy(__x._M_root(), _M_header); _M_leftmost() = _S_minimum(_M_root()); _M_rightmost() = _S_maximum(_M_root()); } _M_node_count = __x._M_node_count; } ~_Rb_tree() { clear(); } _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x); private: void _M_empty_initialize() { _S_color(_M_header) = _S_rb_tree_red; // used to distinguish header from // __root, in iterator.operator++ _M_root() = 0; _M_leftmost() = _M_header; _M_rightmost() = _M_header; } public: // accessors: _Compare key_comp() const { return _M_key_compare; } iterator begin() { return _M_leftmost(); } const_iterator begin() const { return _M_leftmost(); } iterator end() { return _M_header; } const_iterator end() const { return _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_node_count == 0; } size_type size() const { return _M_node_count; } size_type max_size() const { return size_type(-1); } void swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __t) { __STD::swap(_M_header, __t._M_header); __STD::swap(_M_node_count, __t._M_node_count); __STD::swap(_M_key_compare, __t._M_key_compare); } public: // insert/erase pair insert_unique(const value_type& __x); iterator insert_equal(const value_type& __x); iterator insert_unique(iterator __position, const value_type& __x); iterator insert_equal(iterator __position, const value_type& __x); #ifdef __STL_MEMBER_TEMPLATES template void insert_unique(_InputIterator __first, _InputIterator __last); template void insert_equal(_InputIterator __first, _InputIterator __last); #else /* __STL_MEMBER_TEMPLATES */ void insert_unique(const_iterator __first, const_iterator __last); void insert_unique(const value_type* __first, const value_type* __last); void insert_equal(const_iterator __first, const_iterator __last); void insert_equal(const value_type* __first, const value_type* __last); #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator __position); size_type erase(const key_type& __x); void erase(iterator __first, iterator __last); void erase(const key_type* __first, const key_type* __last); void clear() { if (_M_node_count != 0) { _M_erase(_M_root()); _M_leftmost() = _M_header; _M_root() = 0; _M_rightmost() = _M_header; _M_node_count = 0; } } public: // 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 equal_range(const key_type& __x); pair equal_range(const key_type& __x) const; public: // Debugging. bool __rb_verify() const; }; template inline bool operator==(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { return __x.size() == __y.size() && equal(__x.begin(), __x.end(), __y.begin()); } template inline bool operator<(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { return lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { return !(__x == __y); } template inline bool operator>(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { return __y < __x; } template inline bool operator<=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { return !(__y < __x); } template inline bool operator>=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { return !(__x < __y); } template inline void swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) { if (this != &__x) { // Note that _Key may be a constant type. clear(); _M_node_count = 0; _M_key_compare = __x._M_key_compare; if (__x._M_root() == 0) { _M_root() = 0; _M_leftmost() = _M_header; _M_rightmost() = _M_header; } else { _M_root() = _M_copy(__x._M_root(), _M_header); _M_leftmost() = _S_minimum(_M_root()); _M_rightmost() = _S_maximum(_M_root()); _M_node_count = __x._M_node_count; } } return *this; } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::_M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Value& __v) { _Link_type __x = (_Link_type) __x_; _Link_type __y = (_Link_type) __y_; _Link_type __z; if (__y == _M_header || __x != 0 || _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) { __z = _M_create_node(__v); _S_left(__y) = __z; // also makes _M_leftmost() = __z // when __y == _M_header if (__y == _M_header) { _M_root() = __z; _M_rightmost() = __z; } else if (__y == _M_leftmost()) _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node } else { __z = _M_create_node(__v); _S_right(__y) = __z; if (__y == _M_rightmost()) _M_rightmost() = __z; // maintain _M_rightmost() pointing to max node } _S_parent(__z) = __y; _S_left(__z) = 0; _S_right(__z) = 0; _Rb_tree_rebalance(__z, _M_header->_M_parent); ++_M_node_count; return iterator(__z); } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::insert_equal(const _Value& __v) { _Link_type __y = _M_header; _Link_type __x = _M_root(); while (__x != 0) { __y = __x; __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? _S_left(__x) : _S_right(__x); } return _M_insert(__x, __y, __v); } template pair::iterator, bool> _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::insert_unique(const _Value& __v) { _Link_type __y = _M_header; _Link_type __x = _M_root(); bool __comp = true; while (__x != 0) { __y = __x; __comp = _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(_M_insert(__x, __y, __v), true); else --__j; if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) return pair(_M_insert(__x, __y, __v), true); return pair(__j, false); } template typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> ::insert_unique(iterator __position, const _Val& __v) { if (__position._M_node == _M_header->_M_left) { // begin() if (size() > 0 && _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) return _M_insert(__position._M_node, __position._M_node, __v); // first argument just needs to be non-null else return insert_unique(__v).first; } else if (__position._M_node == _M_header) { // end() if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) return _M_insert(0, _M_rightmost(), __v); else return insert_unique(__v).first; } else { iterator __before = __position; --__before; if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v)) && _M_key_compare(_KeyOfValue()(__v), _S_key(__position._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); // first argument just needs to be non-null } else return insert_unique(__v).first; } } template typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc> ::insert_equal(iterator __position, const _Val& __v) { if (__position._M_node == _M_header->_M_left) { // begin() if (size() > 0 && !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) return _M_insert(__position._M_node, __position._M_node, __v); // first argument just needs to be non-null else return insert_equal(__v); } else if (__position._M_node == _M_header) {// end() if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) return _M_insert(0, _M_rightmost(), __v); else return insert_equal(__v); } else { iterator __before = __position; --__before; if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node)) && !_M_key_compare(_S_key(__position._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); // first argument just needs to be non-null } else return insert_equal(__v); } } #ifdef __STL_MEMBER_TEMPLATES template template void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> ::insert_equal(_II __first, _II __last) { for ( ; __first != __last; ++__first) insert_equal(*__first); } template template void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> ::insert_unique(_II __first, _II __last) { for ( ; __first != __last; ++__first) insert_unique(*__first); } #else /* __STL_MEMBER_TEMPLATES */ template void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> ::insert_equal(const _Val* __first, const _Val* __last) { for ( ; __first != __last; ++__first) insert_equal(*__first); } template void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> ::insert_equal(const_iterator __first, const_iterator __last) { for ( ; __first != __last; ++__first) insert_equal(*__first); } template void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> ::insert_unique(const _Val* __first, const _Val* __last) { for ( ; __first != __last; ++__first) insert_unique(*__first); } template void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> ::insert_unique(const_iterator __first, const_iterator __last) { for ( ; __first != __last; ++__first) insert_unique(*__first); } #endif /* __STL_MEMBER_TEMPLATES */ template inline void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::erase(iterator __position) { _Link_type __y = (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node, _M_header->_M_parent, _M_header->_M_left, _M_header->_M_right); destroy_node(__y); --_M_node_count; } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) { pair __p = equal_range(__x); size_type __n = 0; distance(__p.first, __p.second, __n); erase(__p.first, __p.second); return __n; } template typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type _Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc> ::_M_copy(_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; __STL_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); } } __STL_UNWIND(_M_erase(__top)); return __top; } template void _Rb_tree<_Key,_Value,_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); destroy_node(__x); __x = __y; } } template void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::erase(iterator __first, iterator __last) { if (__first == begin() && __last == end()) clear(); else while (__first != __last) erase(__first++); } template void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::erase(const _Key* __first, const _Key* __last) { while (__first != __last) erase(*__first++); } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) { _Link_type __y = _M_header; // Last node which is not less than __k. _Link_type __x = _M_root(); // Current node. while (__x != 0) if (!_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_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) const { _Link_type __y = _M_header; /* Last node which is not less than __k. */ _Link_type __x = _M_root(); /* Current node. */ while (__x != 0) { if (!_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_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::count(const _Key& __k) const { pair __p = equal_range(__k); size_type __n = 0; distance(__p.first, __p.second, __n); return __n; } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::lower_bound(const _Key& __k) { _Link_type __y = _M_header; /* Last node which is not less than __k. */ _Link_type __x = _M_root(); /* Current node. */ while (__x != 0) if (!_M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); return iterator(__y); } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::lower_bound(const _Key& __k) const { _Link_type __y = _M_header; /* Last node which is not less than __k. */ _Link_type __x = _M_root(); /* Current node. */ while (__x != 0) if (!_M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); return const_iterator(__y); } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::upper_bound(const _Key& __k) { _Link_type __y = _M_header; /* Last node which is greater than __k. */ _Link_type __x = _M_root(); /* Current node. */ while (__x != 0) if (_M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); return iterator(__y); } template typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::upper_bound(const _Key& __k) const { _Link_type __y = _M_header; /* Last node which is greater than __k. */ _Link_type __x = _M_root(); /* Current node. */ while (__x != 0) if (_M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); return const_iterator(__y); } template inline pair::iterator, typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator> _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::equal_range(const _Key& __k) { return pair(lower_bound(__k), upper_bound(__k)); } template inline pair::const_iterator, typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::const_iterator> _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc> ::equal_range(const _Key& __k) const { return pair(lower_bound(__k), upper_bound(__k)); } inline int __black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) { if (__node == 0) return 0; else { int __bc = __node->_M_color == _S_rb_tree_black ? 1 : 0; if (__node == __root) return __bc; else return __bc + __black_count(__node->_M_parent, __root); } } template bool _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const { if (_M_node_count == 0 || begin() == end()) return _M_node_count == 0 && begin() == end() && _M_header->_M_left == _M_header && _M_header->_M_right == _M_header; int __len = __black_count(_M_leftmost(), _M_root()); for (const_iterator __it = begin(); __it != end(); ++__it) { _Link_type __x = (_Link_type) __it._M_node; _Link_type __L = _S_left(__x); _Link_type __R = _S_right(__x); if (__x->_M_color == _S_rb_tree_red) if ((__L && __L->_M_color == _S_rb_tree_red) || (__R && __R->_M_color == _S_rb_tree_red)) return false; if (__L && _M_key_compare(_S_key(__x), _S_key(__L))) return false; if (__R && _M_key_compare(_S_key(__R), _S_key(__x))) return false; if (!__L && !__R && __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; } // Class rb_tree is not part of the C++ standard. It is provided for // compatibility with the HP STL. template 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() {} }; #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_TREE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_uninitialized.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H #define __SGI_STL_INTERNAL_UNINITIALIZED_H __STL_BEGIN_NAMESPACE // uninitialized_copy // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. template inline _ForwardIter __uninitialized_copy_aux(_InputIter __first, _InputIter __last, _ForwardIter __result, __true_type) { return copy(__first, __last, __result); } template _ForwardIter __uninitialized_copy_aux(_InputIter __first, _InputIter __last, _ForwardIter __result, __false_type) { _ForwardIter __cur = __result; __STL_TRY { for ( ; __first != __last; ++__first, ++__cur) _Construct(&*__cur, *__first); return __cur; } __STL_UNWIND(_Destroy(__result, __cur)); } template inline _ForwardIter __uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, _Tp*) { typedef typename __type_traits<_Tp>::is_POD_type _Is_POD; return __uninitialized_copy_aux(__first, __last, __result, _Is_POD()); } template inline _ForwardIter uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result) { return __uninitialized_copy(__first, __last, __result, __VALUE_TYPE(__result)); } inline char* uninitialized_copy(const char* __first, const char* __last, char* __result) { 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) { memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); return __result + (__last - __first); } // uninitialized_copy_n (not part of the C++ standard) template pair<_InputIter, _ForwardIter> __uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result, input_iterator_tag) { _ForwardIter __cur = __result; __STL_TRY { for ( ; __count > 0 ; --__count, ++__first, ++__cur) _Construct(&*__cur, *__first); return pair<_InputIter, _ForwardIter>(__first, __cur); } __STL_UNWIND(_Destroy(__result, __cur)); } template inline pair<_RandomAccessIter, _ForwardIter> __uninitialized_copy_n(_RandomAccessIter __first, _Size __count, _ForwardIter __result, random_access_iterator_tag) { _RandomAccessIter __last = __first + __count; return pair<_RandomAccessIter, _ForwardIter>( __last, uninitialized_copy(__first, __last, __result)); } template inline pair<_InputIter, _ForwardIter> __uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result) { return __uninitialized_copy_n(__first, __count, __result, __ITERATOR_CATEGORY(__first)); } template inline pair<_InputIter, _ForwardIter> uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result) { return __uninitialized_copy_n(__first, __count, __result, __ITERATOR_CATEGORY(__first)); } // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. template inline void __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, __true_type) { fill(__first, __last, __x); } template void __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, __false_type) { _ForwardIter __cur = __first; __STL_TRY { for ( ; __cur != __last; ++__cur) _Construct(&*__cur, __x); } __STL_UNWIND(_Destroy(__first, __cur)); } template inline void __uninitialized_fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, _Tp1*) { typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; __uninitialized_fill_aux(__first, __last, __x, _Is_POD()); } template inline void uninitialized_fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x) { __uninitialized_fill(__first, __last, __x, __VALUE_TYPE(__first)); } // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. template inline _ForwardIter __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, const _Tp& __x, __true_type) { return fill_n(__first, __n, __x); } template _ForwardIter __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, const _Tp& __x, __false_type) { _ForwardIter __cur = __first; __STL_TRY { for ( ; __n > 0; --__n, ++__cur) _Construct(&*__cur, __x); return __cur; } __STL_UNWIND(_Destroy(__first, __cur)); } template inline _ForwardIter __uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x, _Tp1*) { typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); } template inline _ForwardIter uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x) { return __uninitialized_fill_n(__first, __n, __x, __VALUE_TYPE(__first)); } // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, // __uninitialized_fill_copy. // __uninitialized_copy_copy // Copies [first1, last1) into [result, result + (last1 - first1)), and // copies [first2, last2) into // [result, result + (last1 - first1) + (last2 - first2)). template inline _ForwardIter __uninitialized_copy_copy(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _ForwardIter __result) { _ForwardIter __mid = uninitialized_copy(__first1, __last1, __result); __STL_TRY { return uninitialized_copy(__first2, __last2, __mid); } __STL_UNWIND(_Destroy(__result, __mid)); } // __uninitialized_fill_copy // Fills [result, mid) with x, and copies [first, last) into // [mid, mid + (last - first)). template inline _ForwardIter __uninitialized_fill_copy(_ForwardIter __result, _ForwardIter __mid, const _Tp& __x, _InputIter __first, _InputIter __last) { uninitialized_fill(__result, __mid, __x); __STL_TRY { return uninitialized_copy(__first, __last, __mid); } __STL_UNWIND(_Destroy(__result, __mid)); } // __uninitialized_copy_fill // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and // fills [first2 + (last1 - first1), last2) with x. template inline void __uninitialized_copy_fill(_InputIter __first1, _InputIter __last1, _ForwardIter __first2, _ForwardIter __last2, const _Tp& __x) { _ForwardIter __mid2 = uninitialized_copy(__first1, __last1, __first2); __STL_TRY { uninitialized_fill(__mid2, __last2, __x); } __STL_UNWIND(_Destroy(__first2, __mid2)); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_UNINITIALIZED_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/stl_vector.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_VECTOR_H #define __SGI_STL_INTERNAL_VECTOR_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // The vector base class serves two purposes. First, its constructor // and destructor allocate (but don't initialize) storage. This makes // exception safety easier. Second, the base class encapsulates all of // the differences between SGI-style allocators and standard-conforming // allocators. #ifdef __STL_USE_STD_ALLOCATORS // Base class for ordinary allocators. template class _Vector_alloc_base { public: typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_data_allocator; } _Vector_alloc_base(const allocator_type& __a) : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) {} protected: allocator_type _M_data_allocator; _Tp* _M_start; _Tp* _M_finish; _Tp* _M_end_of_storage; _Tp* _M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); } void _M_deallocate(_Tp* __p, size_t __n) { if (__p) _M_data_allocator.deallocate(__p, __n); } }; // Specialization for allocators that have the property that we don't // actually have to store an allocator object. template class _Vector_alloc_base<_Tp, _Allocator, true> { public: typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Vector_alloc_base(const allocator_type&) : _M_start(0), _M_finish(0), _M_end_of_storage(0) {} protected: _Tp* _M_start; _Tp* _M_finish; _Tp* _M_end_of_storage; typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type; _Tp* _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); } void _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n);} }; template struct _Vector_base : public _Vector_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { typedef _Vector_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base; typedef typename _Base::allocator_type allocator_type; _Vector_base(const allocator_type& __a) : _Base(__a) {} _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) { _M_start = _M_allocate(__n); _M_finish = _M_start; _M_end_of_storage = _M_start + __n; } ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } }; #else /* __STL_USE_STD_ALLOCATORS */ template class _Vector_base { public: typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Vector_base(const _Alloc&) : _M_start(0), _M_finish(0), _M_end_of_storage(0) {} _Vector_base(size_t __n, const _Alloc&) : _M_start(0), _M_finish(0), _M_end_of_storage(0) { _M_start = _M_allocate(__n); _M_finish = _M_start; _M_end_of_storage = _M_start + __n; } ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } protected: _Tp* _M_start; _Tp* _M_finish; _Tp* _M_end_of_storage; typedef simple_alloc<_Tp, _Alloc> _M_data_allocator; _Tp* _M_allocate(size_t __n) { return _M_data_allocator::allocate(__n); } void _M_deallocate(_Tp* __p, size_t __n) { _M_data_allocator::deallocate(__p, __n); } }; #endif /* __STL_USE_STD_ALLOCATORS */ template class vector : protected _Vector_base<_Tp, _Alloc> { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); private: typedef _Vector_base<_Tp, _Alloc> _Base; public: typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type* iterator; typedef const value_type* const_iterator; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef typename _Base::allocator_type allocator_type; allocator_type get_allocator() const { return _Base::get_allocator(); } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: #ifdef __STL_HAS_NAMESPACES using _Base::_M_allocate; using _Base::_M_deallocate; using _Base::_M_start; using _Base::_M_finish; using _Base::_M_end_of_storage; #endif /* __STL_HAS_NAMESPACES */ protected: void _M_insert_aux(iterator __position, const _Tp& __x); void _M_insert_aux(iterator __position); public: iterator begin() { return _M_start; } const_iterator begin() const { return _M_start; } iterator end() { return _M_finish; } const_iterator end() const { return _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 { return size_type(-1) / sizeof(_Tp); } size_type capacity() const { return size_type(_M_end_of_storage - begin()); } bool empty() const { return begin() == end(); } reference operator[](size_type __n) { return *(begin() + __n); } const_reference operator[](size_type __n) const { return *(begin() + __n); } #ifdef __STL_THROW_RANGE_ERRORS void _M_range_check(size_type __n) const { if (__n >= this->size()) __stl_throw_range_error("vector"); } 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]; } #endif /* __STL_THROW_RANGE_ERRORS */ explicit vector(const allocator_type& __a = allocator_type()) : _Base(__a) {} vector(size_type __n, const _Tp& __value, const allocator_type& __a = allocator_type()) : _Base(__n, __a) { _M_finish = uninitialized_fill_n(_M_start, __n, __value); } explicit vector(size_type __n) : _Base(__n, allocator_type()) { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); } vector(const vector<_Tp, _Alloc>& __x) : _Base(__x.size(), __x.get_allocator()) { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); } #ifdef __STL_MEMBER_TEMPLATES // Check whether it's an integral type. If so, it's not an iterator. template vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_initialize_aux(__first, __last, _Integral()); } template void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) { _M_start = _M_allocate(__n); _M_end_of_storage = _M_start + __n; _M_finish = uninitialized_fill_n(_M_start, __n, __value); } template void _M_initialize_aux(_InputIterator __first, _InputIterator __last, __false_type) { _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); } #else vector(const _Tp* __first, const _Tp* __last, const allocator_type& __a = allocator_type()) : _Base(__last - __first, __a) { _M_finish = uninitialized_copy(__first, __last, _M_start); } #endif /* __STL_MEMBER_TEMPLATES */ ~vector() { destroy(_M_start, _M_finish); } vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x); void reserve(size_type __n) { if (capacity() < __n) { const size_type __old_size = size(); iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish); destroy(_M_start, _M_finish); _M_deallocate(_M_start, _M_end_of_storage - _M_start); _M_start = __tmp; _M_finish = __tmp + __old_size; _M_end_of_storage = _M_start + __n; } } // 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); #ifdef __STL_MEMBER_TEMPLATES template void assign(_InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_assign_dispatch(__first, __last, _Integral()); } template void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign((size_type) __n, (_Tp) __val); } template void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } template void _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag); template void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(end() - 1); } const_reference back() const { return *(end() - 1); } void push_back(const _Tp& __x) { if (_M_finish != _M_end_of_storage) { construct(_M_finish, __x); ++_M_finish; } else _M_insert_aux(end(), __x); } void push_back() { if (_M_finish != _M_end_of_storage) { construct(_M_finish); ++_M_finish; } else _M_insert_aux(end()); } void swap(vector<_Tp, _Alloc>& __x) { __STD::swap(_M_start, __x._M_start); __STD::swap(_M_finish, __x._M_finish); __STD::swap(_M_end_of_storage, __x._M_end_of_storage); } iterator insert(iterator __position, const _Tp& __x) { size_type __n = __position - begin(); if (_M_finish != _M_end_of_storage && __position == end()) { construct(_M_finish, __x); ++_M_finish; } else _M_insert_aux(__position, __x); return begin() + __n; } iterator insert(iterator __position) { size_type __n = __position - begin(); if (_M_finish != _M_end_of_storage && __position == end()) { construct(_M_finish); ++_M_finish; } else _M_insert_aux(__position); return begin() + __n; } #ifdef __STL_MEMBER_TEMPLATES // Check whether it's an integral type. If so, it's not an iterator. template void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_insert_dispatch(__pos, __first, __last, _Integral()); } template void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type) { _M_fill_insert(__pos, (size_type) __n, (_Tp) __val); } template void _M_insert_dispatch(iterator __pos, _InputIterator __first, _InputIterator __last, __false_type) { _M_range_insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator __position, const_iterator __first, const_iterator __last); #endif /* __STL_MEMBER_TEMPLATES */ void insert (iterator __pos, size_type __n, const _Tp& __x) { _M_fill_insert(__pos, __n, __x); } void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x); void pop_back() { --_M_finish; destroy(_M_finish); } iterator erase(iterator __position) { if (__position + 1 != end()) copy(__position + 1, _M_finish, __position); --_M_finish; destroy(_M_finish); return __position; } iterator erase(iterator __first, iterator __last) { iterator __i = copy(__last, _M_finish, __first); destroy(__i, _M_finish); _M_finish = _M_finish - (__last - __first); return __first; } void resize(size_type __new_size, const _Tp& __x) { if (__new_size < size()) erase(begin() + __new_size, end()); else insert(end(), __new_size - size(), __x); } void resize(size_type __new_size) { resize(__new_size, _Tp()); } void clear() { erase(begin(), end()); } protected: #ifdef __STL_MEMBER_TEMPLATES template iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first, _ForwardIterator __last) { iterator __result = _M_allocate(__n); __STL_TRY { uninitialized_copy(__first, __last, __result); return __result; } __STL_UNWIND(_M_deallocate(__result, __n)); } #else /* __STL_MEMBER_TEMPLATES */ iterator _M_allocate_and_copy(size_type __n, const_iterator __first, const_iterator __last) { iterator __result = _M_allocate(__n); __STL_TRY { uninitialized_copy(__first, __last, __result); return __result; } __STL_UNWIND(_M_deallocate(__result, __n)); } #endif /* __STL_MEMBER_TEMPLATES */ #ifdef __STL_MEMBER_TEMPLATES template void _M_range_initialize(_InputIterator __first, _InputIterator __last, input_iterator_tag) { for ( ; __first != __last; ++__first) push_back(*__first); } // This function is only called by the constructor. template void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { size_type __n = 0; distance(__first, __last, __n); _M_start = _M_allocate(__n); _M_end_of_storage = _M_start + __n; _M_finish = uninitialized_copy(__first, __last, _M_start); } template void _M_range_insert(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag); template void _M_range_insert(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ }; template inline bool operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return __x.size() == __y.size() && equal(__x.begin(), __x.end(), __y.begin()); } template inline bool operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) { __x.swap(__y); } template inline bool operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__x == __y); } template inline bool operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return __y < __x; } template inline bool operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__y < __x); } template inline bool operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__x < __y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template vector<_Tp,_Alloc>& vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x) { if (&__x != this) { const size_type __xlen = __x.size(); if (__xlen > capacity()) { iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); destroy(_M_start, _M_finish); _M_deallocate(_M_start, _M_end_of_storage - _M_start); _M_start = __tmp; _M_end_of_storage = _M_start + __xlen; } else if (size() >= __xlen) { iterator __i = copy(__x.begin(), __x.end(), begin()); destroy(__i, _M_finish); } else { copy(__x.begin(), __x.begin() + size(), _M_start); uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish); } _M_finish = _M_start + __xlen; } return *this; } template void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const value_type& __val) { if (__n > capacity()) { vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator()); __tmp.swap(*this); } else if (__n > size()) { fill(begin(), end(), __val); _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val); } else erase(fill_n(begin(), __n, __val), end()); } #ifdef __STL_MEMBER_TEMPLATES template template void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag) { iterator __cur = begin(); for ( ; __first != __last && __cur != end(); ++__cur, ++__first) *__cur = *__first; if (__first == __last) erase(__cur, end()); else insert(end(), __first, __last); } template template void vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last, forward_iterator_tag) { size_type __len = 0; distance(__first, __last, __len); if (__len > capacity()) { iterator __tmp = _M_allocate_and_copy(__len, __first, __last); destroy(_M_start, _M_finish); _M_deallocate(_M_start, _M_end_of_storage - _M_start); _M_start = __tmp; _M_end_of_storage = _M_finish = _M_start + __len; } else if (size() >= __len) { iterator __new_finish = copy(__first, __last, _M_start); destroy(__new_finish, _M_finish); _M_finish = __new_finish; } else { _ForwardIter __mid = __first; advance(__mid, size()); copy(__first, __mid, _M_start); _M_finish = uninitialized_copy(__mid, __last, _M_finish); } } #endif /* __STL_MEMBER_TEMPLATES */ template void vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x) { if (_M_finish != _M_end_of_storage) { construct(_M_finish, *(_M_finish - 1)); ++_M_finish; _Tp __x_copy = __x; copy_backward(__position, _M_finish - 2, _M_finish - 1); *__position = __x_copy; } else { const size_type __old_size = size(); const size_type __len = __old_size != 0 ? 2 * __old_size : 1; iterator __new_start = _M_allocate(__len); iterator __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, __position, __new_start); construct(__new_finish, __x); ++__new_finish; __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(begin(), end()); _M_deallocate(_M_start, _M_end_of_storage - _M_start); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } } template void vector<_Tp, _Alloc>::_M_insert_aux(iterator __position) { if (_M_finish != _M_end_of_storage) { construct(_M_finish, *(_M_finish - 1)); ++_M_finish; copy_backward(__position, _M_finish - 2, _M_finish - 1); *__position = _Tp(); } else { const size_type __old_size = size(); const size_type __len = __old_size != 0 ? 2 * __old_size : 1; iterator __new_start = _M_allocate(__len); iterator __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, __position, __new_start); construct(__new_finish); ++__new_finish; __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(begin(), end()); _M_deallocate(_M_start, _M_end_of_storage - _M_start); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } } template void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n, const _Tp& __x) { if (__n != 0) { if (size_type(_M_end_of_storage - _M_finish) >= __n) { _Tp __x_copy = __x; const size_type __elems_after = _M_finish - __position; iterator __old_finish = _M_finish; if (__elems_after > __n) { uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); _M_finish += __n; copy_backward(__position, __old_finish - __n, __old_finish); fill(__position, __position + __n, __x_copy); } else { uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy); _M_finish += __n - __elems_after; uninitialized_copy(__position, __old_finish, _M_finish); _M_finish += __elems_after; fill(__position, __old_finish, __x_copy); } } else { const size_type __old_size = size(); const size_type __len = __old_size + max(__old_size, __n); iterator __new_start = _M_allocate(__len); iterator __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, __position, __new_start); __new_finish = uninitialized_fill_n(__new_finish, __n, __x); __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(_M_start, _M_finish); _M_deallocate(_M_start, _M_end_of_storage - _M_start); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } } } #ifdef __STL_MEMBER_TEMPLATES template template void vector<_Tp, _Alloc>::_M_range_insert(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag) { for ( ; __first != __last; ++__first) { __pos = insert(__pos, *__first); ++__pos; } } template template void vector<_Tp, _Alloc>::_M_range_insert(iterator __position, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { if (__first != __last) { size_type __n = 0; distance(__first, __last, __n); if (size_type(_M_end_of_storage - _M_finish) >= __n) { const size_type __elems_after = _M_finish - __position; iterator __old_finish = _M_finish; if (__elems_after > __n) { uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); _M_finish += __n; copy_backward(__position, __old_finish - __n, __old_finish); copy(__first, __last, __position); } else { _ForwardIterator __mid = __first; advance(__mid, __elems_after); uninitialized_copy(__mid, __last, _M_finish); _M_finish += __n - __elems_after; uninitialized_copy(__position, __old_finish, _M_finish); _M_finish += __elems_after; copy(__first, __mid, __position); } } else { const size_type __old_size = size(); const size_type __len = __old_size + max(__old_size, __n); iterator __new_start = _M_allocate(__len); iterator __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, __position, __new_start); __new_finish = uninitialized_copy(__first, __last, __new_finish); __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(_M_start, _M_finish); _M_deallocate(_M_start, _M_end_of_storage - _M_start); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } } } #else /* __STL_MEMBER_TEMPLATES */ template void vector<_Tp, _Alloc>::insert(iterator __position, const_iterator __first, const_iterator __last) { if (__first != __last) { size_type __n = 0; distance(__first, __last, __n); if (size_type(_M_end_of_storage - _M_finish) >= __n) { const size_type __elems_after = _M_finish - __position; iterator __old_finish = _M_finish; if (__elems_after > __n) { uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); _M_finish += __n; copy_backward(__position, __old_finish - __n, __old_finish); copy(__first, __last, __position); } else { uninitialized_copy(__first + __elems_after, __last, _M_finish); _M_finish += __n - __elems_after; uninitialized_copy(__position, __old_finish, _M_finish); _M_finish += __elems_after; copy(__first, __first + __elems_after, __position); } } else { const size_type __old_size = size(); const size_type __len = __old_size + max(__old_size, __n); iterator __new_start = _M_allocate(__len); iterator __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, __position, __new_start); __new_finish = uninitialized_copy(__first, __last, __new_finish); __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(_M_start, _M_finish); _M_deallocate(_M_start, _M_end_of_storage - _M_start); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } } } #endif /* __STL_MEMBER_TEMPLATES */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_VECTOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/string ================================================ /* * 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. */ #ifndef __SGI_STL_STRING #define __SGI_STL_STRING #include #include #include #include #include #include #include #include #include #ifdef __STL_USE_NEW_IOSTREAMS #include #else /* __STL_USE_NEW_IOSTREAMS */ #include #endif /* __STL_USE_NEW_IOSTREAMS */ // Standard C++ string class. This class has performance // characteristics very much like vector<>, meaning, for example, that // it does not perform reference-count or copy-on-write, and that // concatenation of two strings is an O(N) operation. // There are three reasons why basic_string is not identical to // vector. First, basic_string always stores a null character at the // end; this makes it possible for c_str to be a fast operation. // Second, the C++ standard requires basic_string to copy elements // using char_traits<>::assign, char_traits<>::copy, and // char_traits<>::move. This means that all of vector<>'s low-level // operations must be rewritten. Third, basic_string<> has a lot of // extra functions in its interface that are convenient but, strictly // speaking, redundant. // Additionally, the C++ standard imposes a major restriction: according // to the standard, the character type _CharT must be a POD type. This // implementation weakens that restriction, and allows _CharT to be a // a user-defined non-POD type. However, _CharT must still have a // default constructor. __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #pragma set woff 1375 #endif // A helper class to use a char_traits as a function object. template struct _Not_within_traits : public unary_function { typedef const typename _Traits::char_type* _Pointer; const _Pointer _M_first; const _Pointer _M_last; _Not_within_traits(_Pointer __f, _Pointer __l) : _M_first(__f), _M_last(__l) {} bool operator()(const typename _Traits::char_type& __x) const { return find_if(_M_first, _M_last, bind1st(_Eq_traits<_Traits>(), __x)) == _M_last; } }; // ------------------------------------------------------------ // Class _String_base. // _String_base is a helper class that makes it it easier to write an // exception-safe version of basic_string. The constructor allocates, // but does not initialize, a block of memory. The destructor // deallocates, but does not destroy elements within, a block of // memory. The destructor assumes that _M_start either is null, or else // points to a block of memory that was allocated using _String_base's // allocator and whose size is _M_end_of_storage - _M_start. // Additionally, _String_base encapsulates the difference between // old SGI-style allocators and standard-conforming allocators. #ifdef __STL_USE_STD_ALLOCATORS // General base class. template class _String_alloc_base { public: typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_data_allocator; } _String_alloc_base(const allocator_type& __a) : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) {} protected: _Tp* _M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); } void _M_deallocate(_Tp* __p, size_t __n) { if (__p) _M_data_allocator.deallocate(__p, __n); } protected: allocator_type _M_data_allocator; _Tp* _M_start; _Tp* _M_finish; _Tp* _M_end_of_storage; }; // Specialization for instanceless allocators. template class _String_alloc_base<_Tp,_Alloc,true> { public: typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _String_alloc_base(const allocator_type&) : _M_start(0), _M_finish(0), _M_end_of_storage(0) {} protected: typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Alloc_type; _Tp* _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); } void _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n); } protected: _Tp* _M_start; _Tp* _M_finish; _Tp* _M_end_of_storage; }; template class _String_base : public _String_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { protected: typedef _String_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base; typedef typename _Base::allocator_type allocator_type; void _M_allocate_block(size_t __n) { if (__n <= max_size()) { _M_start = _M_allocate(__n); _M_finish = _M_start; _M_end_of_storage = _M_start + __n; } else _M_throw_length_error(); } void _M_deallocate_block() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } size_t max_size() const { return (size_t(-1) / sizeof(_Tp)) - 1; } _String_base(const allocator_type& __a) : _Base(__a) { } _String_base(const allocator_type& __a, size_t __n) : _Base(__a) { _M_allocate_block(__n); } ~_String_base() { _M_deallocate_block(); } void _M_throw_length_error() const; void _M_throw_out_of_range() const; }; #else /* __STL_USE_STD_ALLOCATORS */ template class _String_base { public: typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(); } protected: typedef simple_alloc<_Tp, _Alloc> _Alloc_type; _Tp* _M_start; _Tp* _M_finish; _Tp* _M_end_of_storage; // Precondition: 0 < __n <= max_size(). _Tp* _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); } void _M_deallocate(_Tp* __p, size_t __n) { if (__p) _Alloc_type::deallocate(__p, __n); } void _M_allocate_block(size_t __n) { if (__n <= max_size()) { _M_start = _M_allocate(__n); _M_finish = _M_start; _M_end_of_storage = _M_start + __n; } else _M_throw_length_error(); } void _M_deallocate_block() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } size_t max_size() const { return (size_t(-1) / sizeof(_Tp)) - 1; } _String_base(const allocator_type&) : _M_start(0), _M_finish(0), _M_end_of_storage(0) { } _String_base(const allocator_type&, size_t __n) : _M_start(0), _M_finish(0), _M_end_of_storage(0) { _M_allocate_block(__n); } ~_String_base() { _M_deallocate_block(); } void _M_throw_length_error() const; void _M_throw_out_of_range() const; }; #endif /* __STL_USE_STD_ALLOCATORS */ // Helper functions for exception handling. template void _String_base<_Tp,_Alloc>::_M_throw_length_error() const { __STL_THROW(length_error("basic_string")); } template void _String_base<_Tp, _Alloc>::_M_throw_out_of_range() const { __STL_THROW(out_of_range("basic_string")); } // ------------------------------------------------------------ // Class basic_string. // Class invariants: // (1) [start, finish) is a valid range. // (2) Each iterator in [start, finish) points to a valid object // of type value_type. // (3) *finish is a valid object of type value_type; in particular, // it is value_type(). // (4) [finish + 1, end_of_storage) is a valid range. // (5) Each iterator in [finish + 1, end_of_storage) points to // unininitialized memory. // Note one important consequence: a string of length n must manage // a block of memory whose size is at least n + 1. template class basic_string : private _String_base<_CharT,_Alloc> { public: typedef _CharT value_type; typedef _Traits traits_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 const value_type* const_iterator; typedef value_type* iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #endif /* __STL_PARTIAL_SPECIALIZATION */ static const size_type npos; typedef _String_base<_CharT,_Alloc> _Base; public: // Constructor, destructor, assignment. typedef typename _Base::allocator_type allocator_type; allocator_type get_allocator() const { return _Base::get_allocator(); } explicit basic_string(const allocator_type& __a = allocator_type()) : _Base(__a, 8) { _M_terminate_string(); } struct _Reserve_t {}; basic_string(_Reserve_t, size_t __n, const allocator_type& __a = allocator_type()) : _Base(__a, __n + 1) { _M_terminate_string(); } basic_string(const basic_string& __s) : _Base(__s.get_allocator()) { _M_range_initialize(__s.begin(), __s.end()); } basic_string(const basic_string& __s, size_type __pos, size_type __n = npos, const allocator_type& __a = allocator_type()) : _Base(__a) { if (__pos > __s.size()) _M_throw_out_of_range(); else _M_range_initialize(__s.begin() + __pos, __s.begin() + __pos + min(__n, __s.size() - __pos)); } basic_string(const _CharT* __s, size_type __n, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_range_initialize(__s, __s + __n); } basic_string(const _CharT* __s, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_range_initialize(__s, __s + _Traits::length(__s)); } basic_string(size_type __n, _CharT __c, const allocator_type& __a = allocator_type()) : _Base(__a, __n + 1) { _M_finish = uninitialized_fill_n(_M_start, __n, __c); _M_terminate_string(); } // Check to see if _InputIterator is an integer type. If so, then // it can't be an iterator. #ifdef __STL_MEMBER_TEMPLATES template basic_string(_InputIterator __f, _InputIterator __l, const allocator_type& __a = allocator_type()) : _Base(__a) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_initialize_dispatch(__f, __l, _Integral()); } #else /* __STL_MEMBER_TEMPLATES */ basic_string(const _CharT* __f, const _CharT* __l, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_range_initialize(__f, __l); } #endif ~basic_string() { destroy(_M_start, _M_finish + 1); } basic_string& operator=(const basic_string& __s) { if (&__s != this) assign(__s.begin(), __s.end()); return *this; } basic_string& operator=(const _CharT* __s) { return assign(__s, __s + _Traits::length(__s)); } basic_string& operator=(_CharT __c) { return assign(static_cast(1), __c); } protected: // Protected members inherited from base. #ifdef __STL_HAS_NAMESPACES using _Base::_M_allocate; using _Base::_M_deallocate; using _Base::_M_allocate_block; using _Base::_M_deallocate_block; using _Base::_M_throw_length_error; using _Base::_M_throw_out_of_range; using _Base::_M_start; using _Base::_M_finish; using _Base::_M_end_of_storage; #endif /* __STL_HAS_NAMESPACES */ private: // Helper functions used by constructors // and elsewhere. void _M_construct_null(_CharT* __p) { construct(__p); # ifdef __STL_DEFAULT_CONSTRUCTOR_BUG __STL_TRY { *__p = (_CharT) 0; } __STL_UNWIND(destroy(__p)); # endif } static _CharT _M_null() { # ifndef __STL_DEFAULT_CONSTRUCTOR_BUG return _CharT(); # else return (_CharT) 0; # endif } private: // Helper functions used by constructors. It is a severe error for // any of them to be called anywhere except from within constructors. void _M_terminate_string() { __STL_TRY { _M_construct_null(_M_finish); } __STL_UNWIND(destroy(_M_start, _M_finish)); } #ifdef __STL_MEMBER_TEMPLATES template void _M_range_initialize(_InputIter __f, _InputIter __l, input_iterator_tag) { _M_allocate_block(8); _M_construct_null(_M_finish); __STL_TRY { append(__f, __l); } __STL_UNWIND(destroy(_M_start, _M_finish + 1)); } template void _M_range_initialize(_ForwardIter __f, _ForwardIter __l, forward_iterator_tag) { difference_type __n = 0; distance(__f, __l, __n); _M_allocate_block(__n + 1); _M_finish = uninitialized_copy(__f, __l, _M_start); _M_terminate_string(); } template void _M_range_initialize(_InputIter __f, _InputIter __l) { typedef typename iterator_traits<_InputIter>::iterator_category _Category; _M_range_initialize(__f, __l, _Category()); } template void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { _M_allocate_block(__n + 1); _M_finish = uninitialized_fill_n(_M_start, __n, __x); _M_terminate_string(); } template void _M_initialize_dispatch(_InputIter __f, _InputIter __l, __false_type) { _M_range_initialize(__f, __l); } #else /* __STL_MEMBER_TEMPLATES */ void _M_range_initialize(const _CharT* __f, const _CharT* __l) { ptrdiff_t __n = __l - __f; _M_allocate_block(__n + 1); _M_finish = uninitialized_copy(__f, __l, _M_start); _M_terminate_string(); } #endif /* __STL_MEMBER_TEMPLATES */ public: // Iterators. iterator begin() { return _M_start; } iterator end() { return _M_finish; } const_iterator begin() const { return _M_start; } const_iterator end() const { return _M_finish; } reverse_iterator rbegin() { return reverse_iterator(_M_finish); } reverse_iterator rend() { return reverse_iterator(_M_start); } const_reverse_iterator rbegin() const { return const_reverse_iterator(_M_finish); } const_reverse_iterator rend() const { return const_reverse_iterator(_M_start); } public: // Size, capacity, etc. size_type size() const { return _M_finish - _M_start; } size_type length() const { return size(); } size_t max_size() const { return _Base::max_size(); } void resize(size_type __n, _CharT __c) { if (__n <= size()) erase(begin() + __n, end()); else append(__n - size(), __c); } void resize(size_type __n) { resize(__n, _M_null()); } void reserve(size_type = 0); size_type capacity() const { return (_M_end_of_storage - _M_start) - 1; } void clear() { if (!empty()) { _Traits::assign(*_M_start, _M_null()); destroy(_M_start+1, _M_finish+1); _M_finish = _M_start; } } bool empty() const { return _M_start == _M_finish; } public: // Element access. const_reference operator[](size_type __n) const { return *(_M_start + __n); } reference operator[](size_type __n) { return *(_M_start + __n); } const_reference at(size_type __n) const { if (__n >= size()) _M_throw_out_of_range(); return *(_M_start + __n); } reference at(size_type __n) { if (__n >= size()) _M_throw_out_of_range(); return *(_M_start + __n); } public: // Append, operator+=, push_back. basic_string& operator+=(const basic_string& __s) { return append(__s); } basic_string& operator+=(const _CharT* __s) { return append(__s); } basic_string& operator+=(_CharT __c) { push_back(__c); return *this; } basic_string& append(const basic_string& __s) { return append(__s.begin(), __s.end()); } basic_string& append(const basic_string& __s, size_type __pos, size_type __n) { if (__pos > __s.size()) _M_throw_out_of_range(); return append(__s.begin() + __pos, __s.begin() + __pos + min(__n, __s.size() - __pos)); } basic_string& append(const _CharT* __s, size_type __n) { return append(__s, __s+__n); } basic_string& append(const _CharT* __s) { return append(__s, __s + _Traits::length(__s)); } basic_string& append(size_type __n, _CharT __c); #ifdef __STL_MEMBER_TEMPLATES // Check to see if _InputIterator is an integer type. If so, then // it can't be an iterator. template basic_string& append(_InputIter __first, _InputIter __last) { typedef typename _Is_integer<_InputIter>::_Integral _Integral; return _M_append_dispatch(__first, __last, _Integral()); } #else /* __STL_MEMBER_TEMPLATES */ basic_string& append(const _CharT* __first, const _CharT* __last); #endif /* __STL_MEMBER_TEMPLATES */ void push_back(_CharT __c) { if (_M_finish + 1 == _M_end_of_storage) reserve(size() + max(size(), static_cast(1))); _M_construct_null(_M_finish + 1); _Traits::assign(*_M_finish, __c); ++_M_finish; } void pop_back() { _Traits::assign(*(_M_finish - 1), _M_null()); destroy(_M_finish); --_M_finish; } private: // Helper functions for append. #ifdef __STL_MEMBER_TEMPLATES template basic_string& append(_InputIter __f, _InputIter __l, input_iterator_tag); template basic_string& append(_ForwardIter __f, _ForwardIter __l, forward_iterator_tag); template basic_string& _M_append_dispatch(_Integer __n, _Integer __x, __true_type) { return append((size_type) __n, (_CharT) __x); } template basic_string& _M_append_dispatch(_InputIter __f, _InputIter __l, __false_type) { typedef typename iterator_traits<_InputIter>::iterator_category _Category; return append(__f, __l, _Category()); } #endif /* __STL_MEMBER_TEMPLATES */ public: // Assign basic_string& assign(const basic_string& __s) { return assign(__s.begin(), __s.end()); } basic_string& assign(const basic_string& __s, size_type __pos, size_type __n) { if (__pos > __s.size()) _M_throw_out_of_range(); return assign(__s.begin() + __pos, __s.begin() + __pos + min(__n, __s.size() - __pos)); } basic_string& assign(const _CharT* __s, size_type __n) { return assign(__s, __s + __n); } basic_string& assign(const _CharT* __s) { return assign(__s, __s + _Traits::length(__s)); } basic_string& assign(size_type __n, _CharT __c); #ifdef __STL_MEMBER_TEMPLATES // Check to see if _InputIterator is an integer type. If so, then // it can't be an iterator. template basic_string& assign(_InputIter __first, _InputIter __last) { typedef typename _Is_integer<_InputIter>::_Integral _Integral; return _M_assign_dispatch(__first, __last, _Integral()); } #endif /* __STL_MEMBER_TEMPLATES */ basic_string& assign(const _CharT* __f, const _CharT* __l); private: // Helper functions for assign. #ifdef __STL_MEMBER_TEMPLATES template basic_string& _M_assign_dispatch(_Integer __n, _Integer __x, __true_type) { return assign((size_type) __n, (_CharT) __x); } template basic_string& _M_assign_dispatch(_InputIter __f, _InputIter __l, __false_type); #endif /* __STL_MEMBER_TEMPLATES */ public: // Insert basic_string& insert(size_type __pos, const basic_string& __s) { if (__pos > size()) _M_throw_out_of_range(); if (size() > max_size() - __s.size()) _M_throw_length_error(); insert(_M_start + __pos, __s.begin(), __s.end()); return *this; } basic_string& insert(size_type __pos, const basic_string& __s, size_type __beg, size_type __n) { if (__pos > size() || __beg > __s.size()) _M_throw_out_of_range(); size_type __len = min(__n, __s.size() - __beg); if (size() > max_size() - __len) _M_throw_length_error(); insert(_M_start + __pos, __s.begin() + __beg, __s.begin() + __beg + __len); return *this; } basic_string& insert(size_type __pos, const _CharT* __s, size_type __n) { if (__pos > size()) _M_throw_out_of_range(); if (size() > max_size() - __n) _M_throw_length_error(); insert(_M_start + __pos, __s, __s + __n); return *this; } basic_string& insert(size_type __pos, const _CharT* __s) { if (__pos > size()) _M_throw_out_of_range(); size_type __len = _Traits::length(__s); if (size() > max_size() - __len) _M_throw_length_error(); insert(_M_start + __pos, __s, __s + __len); return *this; } basic_string& insert(size_type __pos, size_type __n, _CharT __c) { if (__pos > size()) _M_throw_out_of_range(); if (size() > max_size() - __n) _M_throw_length_error(); insert(_M_start + __pos, __n, __c); return *this; } iterator insert(iterator __p, _CharT __c) { if (__p == _M_finish) { push_back(__c); return _M_finish - 1; } else return _M_insert_aux(__p, __c); } void insert(iterator __p, size_t __n, _CharT __c); #ifdef __STL_MEMBER_TEMPLATES // Check to see if _InputIterator is an integer type. If so, then // it can't be an iterator. template void insert(iterator __p, _InputIter __first, _InputIter __last) { typedef typename _Is_integer<_InputIter>::_Integral _Integral; _M_insert_dispatch(__p, __first, __last, _Integral()); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator __p, const _CharT* __first, const _CharT* __last); #endif /* __STL_MEMBER_TEMPLATES */ private: // Helper functions for insert. #ifdef __STL_MEMBER_TEMPLATES template void insert(iterator __p, _InputIter, _InputIter, input_iterator_tag); template void insert(iterator __p, _ForwardIter, _ForwardIter, forward_iterator_tag); template void _M_insert_dispatch(iterator __p, _Integer __n, _Integer __x, __true_type) { insert(__p, (size_type) __n, (_CharT) __x); } template void _M_insert_dispatch(iterator __p, _InputIter __first, _InputIter __last, __false_type) { typedef typename iterator_traits<_InputIter>::iterator_category _Category; insert(__p, __first, __last, _Category()); } template void _M_copy(_InputIterator __first, _InputIterator __last, iterator __result) { for ( ; __first != __last; ++__first, ++__result) _Traits::assign(*__result, *__first); } #endif /* __STL_MEMBER_TEMPLATES */ iterator _M_insert_aux(iterator, _CharT); void _M_copy(const _CharT* __first, const _CharT* __last, _CharT* __result) { _Traits::copy(__result, __first, __last - __first); } public: // Erase. basic_string& erase(size_type __pos = 0, size_type __n = npos) { if (__pos > size()) _M_throw_out_of_range(); erase(_M_start + __pos, _M_start + __pos + min(__n, size() - __pos)); return *this; } iterator erase(iterator __position) { // The move includes the terminating null. _Traits::move(__position, __position + 1, _M_finish - __position); destroy(_M_finish); --_M_finish; return __position; } iterator erase(iterator __first, iterator __last) { if (__first != __last) { // The move includes the terminating null. _Traits::move(__first, __last, (_M_finish - __last) + 1); const iterator __new_finish = _M_finish - (__last - __first); destroy(__new_finish + 1, _M_finish + 1); _M_finish = __new_finish; } return __first; } public: // Replace. (Conceptually equivalent // to erase followed by insert.) basic_string& replace(size_type __pos, size_type __n, const basic_string& __s) { if (__pos > size()) _M_throw_out_of_range(); const size_type __len = min(__n, size() - __pos); if (size() - __len >= max_size() - __s.size()) _M_throw_length_error(); return replace(_M_start + __pos, _M_start + __pos + __len, __s.begin(), __s.end()); } basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __s, size_type __pos2, size_type __n2) { if (__pos1 > size() || __pos2 > __s.size()) _M_throw_out_of_range(); const size_type __len1 = min(__n1, size() - __pos1); const size_type __len2 = min(__n2, __s.size() - __pos2); if (size() - __len1 >= max_size() - __len2) _M_throw_length_error(); return replace(_M_start + __pos1, _M_start + __pos1 + __len1, __s._M_start + __pos2, __s._M_start + __pos2 + __len2); } basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) { if (__pos > size()) _M_throw_out_of_range(); const size_type __len = min(__n1, size() - __pos); if (__n2 > max_size() || size() - __len >= max_size() - __n2) _M_throw_length_error(); return replace(_M_start + __pos, _M_start + __pos + __len, __s, __s + __n2); } basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s) { if (__pos > size()) _M_throw_out_of_range(); const size_type __len = min(__n1, size() - __pos); const size_type __n2 = _Traits::length(__s); if (__n2 > max_size() || size() - __len >= max_size() - __n2) _M_throw_length_error(); return replace(_M_start + __pos, _M_start + __pos + __len, __s, __s + _Traits::length(__s)); } basic_string& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) { if (__pos > size()) _M_throw_out_of_range(); const size_type __len = min(__n1, size() - __pos); if (__n2 > max_size() || size() - __len >= max_size() - __n2) _M_throw_length_error(); return replace(_M_start + __pos, _M_start + __pos + __len, __n2, __c); } basic_string& replace(iterator __first, iterator __last, const basic_string& __s) { return replace(__first, __last, __s.begin(), __s.end()); } basic_string& replace(iterator __first, iterator __last, const _CharT* __s, size_type __n) { return replace(__first, __last, __s, __s + __n); } basic_string& replace(iterator __first, iterator __last, const _CharT* __s) { return replace(__first, __last, __s, __s + _Traits::length(__s)); } basic_string& replace(iterator __first, iterator __last, size_type __n, _CharT __c); // Check to see if _InputIterator is an integer type. If so, then // it can't be an iterator. #ifdef __STL_MEMBER_TEMPLATES template basic_string& replace(iterator __first, iterator __last, _InputIter __f, _InputIter __l) { typedef typename _Is_integer<_InputIter>::_Integral _Integral; return _M_replace_dispatch(__first, __last, __f, __l, _Integral()); } #else /* __STL_MEMBER_TEMPLATES */ basic_string& replace(iterator __first, iterator __last, const _CharT* __f, const _CharT* __l); #endif /* __STL_MEMBER_TEMPLATES */ private: // Helper functions for replace. #ifdef __STL_MEMBER_TEMPLATES template basic_string& _M_replace_dispatch(iterator __first, iterator __last, _Integer __n, _Integer __x, __true_type) { return replace(__first, __last, (size_type) __n, (_CharT) __x); } template basic_string& _M_replace_dispatch(iterator __first, iterator __last, _InputIter __f, _InputIter __l, __false_type) { typedef typename iterator_traits<_InputIter>::iterator_category _Category; return replace(__first, __last, __f, __l, _Category()); } template basic_string& replace(iterator __first, iterator __last, _InputIter __f, _InputIter __l, input_iterator_tag); template basic_string& replace(iterator __first, iterator __last, _ForwardIter __f, _ForwardIter __l, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ public: // Other modifier member functions. size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const { if (__pos > size()) _M_throw_out_of_range(); const size_type __len = min(__n, size() - __pos); _Traits::copy(__s, _M_start + __pos, __len); return __len; } void swap(basic_string& __s) { __STD::swap(_M_start, __s._M_start); __STD::swap(_M_finish, __s._M_finish); __STD::swap(_M_end_of_storage, __s._M_end_of_storage); } public: // Conversion to C string. const _CharT* c_str() const { return _M_start; } const _CharT* data() const { return _M_start; } public: // find. size_type find(const basic_string& __s, size_type __pos = 0) const { return find(__s.begin(), __pos, __s.size()); } size_type find(const _CharT* __s, size_type __pos = 0) const { return find(__s, __pos, _Traits::length(__s)); } size_type find(const _CharT* __s, size_type __pos, size_type __n) const; size_type find(_CharT __c, size_type __pos = 0) const; public: // rfind. size_type rfind(const basic_string& __s, size_type __pos = npos) const { return rfind(__s.begin(), __pos, __s.size()); } size_type rfind(const _CharT* __s, size_type __pos = npos) const { return rfind(__s, __pos, _Traits::length(__s)); } size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const; size_type rfind(_CharT __c, size_type __pos = npos) const; public: // find_first_of size_type find_first_of(const basic_string& __s, size_type __pos = 0) const { return find_first_of(__s.begin(), __pos, __s.size()); } size_type find_first_of(const _CharT* __s, size_type __pos = 0) const { return find_first_of(__s, __pos, _Traits::length(__s)); } size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; size_type find_first_of(_CharT __c, size_type __pos = 0) const { return find(__c, __pos); } public: // find_last_of size_type find_last_of(const basic_string& __s, size_type __pos = npos) const { return find_last_of(__s.begin(), __pos, __s.size()); } size_type find_last_of(const _CharT* __s, size_type __pos = npos) const { return find_last_of(__s, __pos, _Traits::length(__s)); } size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; size_type find_last_of(_CharT __c, size_type __pos = npos) const { return rfind(__c, __pos); } public: // find_first_not_of size_type find_first_not_of(const basic_string& __s, size_type __pos = 0) const { return find_first_not_of(__s.begin(), __pos, __s.size()); } size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const { return find_first_not_of(__s, __pos, _Traits::length(__s)); } size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const; size_type find_first_not_of(_CharT __c, size_type __pos = 0) const; public: // find_last_not_of size_type find_last_not_of(const basic_string& __s, size_type __pos = npos) const { return find_last_not_of(__s.begin(), __pos, __s.size()); } size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const { return find_last_not_of(__s, __pos, _Traits::length(__s)); } size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const; size_type find_last_not_of(_CharT __c, size_type __pos = npos) const; public: // Substring. basic_string substr(size_type __pos = 0, size_type __n = npos) const { if (__pos > size()) _M_throw_out_of_range(); return basic_string(_M_start + __pos, _M_start + __pos + min(__n, size() - __pos)); } public: // Compare int compare(const basic_string& __s) const { return _M_compare(_M_start, _M_finish, __s._M_start, __s._M_finish); } int compare(size_type __pos1, size_type __n1, const basic_string& __s) const { if (__pos1 > size()) _M_throw_out_of_range(); return _M_compare(_M_start + __pos1, _M_start + __pos1 + min(__n1, size() - __pos1), __s._M_start, __s._M_finish); } int compare(size_type __pos1, size_type __n1, const basic_string& __s, size_type __pos2, size_type __n2) const { if (__pos1 > size() || __pos2 > __s.size()) _M_throw_out_of_range(); return _M_compare(_M_start + __pos1, _M_start + __pos1 + min(__n1, size() - __pos1), __s._M_start + __pos2, __s._M_start + __pos2 + min(__n2, size() - __pos2)); } int compare(const _CharT* __s) const { return _M_compare(_M_start, _M_finish, __s, __s + _Traits::length(__s)); } int compare(size_type __pos1, size_type __n1, const _CharT* __s) const { if (__pos1 > size()) _M_throw_out_of_range(); return _M_compare(_M_start + __pos1, _M_start + __pos1 + min(__n1, size() - __pos1), __s, __s + _Traits::length(__s)); } int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const { if (__pos1 > size()) _M_throw_out_of_range(); return _M_compare(_M_start + __pos1, _M_start + __pos1 + min(__n1, size() - __pos1), __s, __s + __n2); } public: // Helper function for compare. static int _M_compare(const _CharT* __f1, const _CharT* __l1, const _CharT* __f2, const _CharT* __l2) { const ptrdiff_t __n1 = __l1 - __f1; const ptrdiff_t __n2 = __l2 - __f2; const int cmp = _Traits::compare(__f1, __f2, min(__n1, __n2)); return cmp != 0 ? cmp : (__n1 < __n2 ? -1 : (__n1 > __n2 ? 1 : 0)); } }; // ------------------------------------------------------------ // Non-inline declarations. template const basic_string<_CharT,_Traits,_Alloc>::size_type basic_string<_CharT,_Traits,_Alloc>::npos = (basic_string<_CharT,_Traits,_Alloc>::size_type) -1; // Change the string's capacity so that it is large enough to hold // at least __res_arg elements, plus the terminating null. Note that, // if __res_arg < capacity(), this member function may actually decrease // the string's capacity. template void basic_string<_CharT,_Traits,_Alloc>::reserve(size_type __res_arg) { if (__res_arg > max_size()) _M_throw_length_error(); size_type __n = max(__res_arg, size()) + 1; pointer __new_start = _M_allocate(__n); pointer __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, _M_finish, __new_start); _M_construct_null(__new_finish); } __STL_UNWIND((destroy(__new_start, __new_finish), _M_deallocate(__new_start, __n))); destroy(_M_start, _M_finish + 1); _M_deallocate_block(); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __n; } template basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc>::append(size_type __n, _CharT __c) { if (__n > max_size() || size() > max_size() - __n) _M_throw_length_error(); if (size() + __n > capacity()) reserve(size() + max(size(), __n)); if (__n > 0) { uninitialized_fill_n(_M_finish + 1, __n - 1, __c); __STL_TRY { _M_construct_null(_M_finish + __n); } __STL_UNWIND(destroy(_M_finish + 1, _M_finish + __n)); _Traits::assign(*_M_finish, __c); _M_finish += __n; } return *this; } #ifdef __STL_MEMBER_TEMPLATES template template basic_string<_Tp, _Traits, _Alloc>& basic_string<_Tp, _Traits, _Alloc>::append(_InputIterator __first, _InputIterator __last, input_iterator_tag) { for ( ; __first != __last ; ++__first) push_back(*__first); return *this; } template template basic_string<_Tp, _Traits, _Alloc>& basic_string<_Tp, _Traits, _Alloc>::append(_ForwardIter __first, _ForwardIter __last, forward_iterator_tag) { if (__first != __last) { const size_type __old_size = size(); difference_type __n = 0; distance(__first, __last, __n); if (static_cast(__n) > max_size() || __old_size > max_size() - static_cast(__n)) _M_throw_length_error(); if (__old_size + static_cast(__n) > capacity()) { const size_type __len = __old_size + max(__old_size, static_cast(__n)) + 1; pointer __new_start = _M_allocate(__len); pointer __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, _M_finish, __new_start); __new_finish = uninitialized_copy(__first, __last, __new_finish); _M_construct_null(__new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(_M_start, _M_finish + 1); _M_deallocate_block(); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } else { _ForwardIter __f1 = __first; ++__f1; uninitialized_copy(__f1, __last, _M_finish + 1); __STL_TRY { _M_construct_null(_M_finish + __n); } __STL_UNWIND(destroy(_M_finish + 1, _M_finish + __n)); _Traits::assign(*_M_finish, *__first); _M_finish += __n; } } return *this; } #else /* __STL_MEMBER_TEMPLATES */ template basic_string<_Tp, _Traits, _Alloc>& basic_string<_Tp, _Traits, _Alloc>::append(const _Tp* __first, const _Tp* __last) { if (__first != __last) { const size_type __old_size = size(); ptrdiff_t __n = __last - __first; if (__n > max_size() || __old_size > max_size() - __n) _M_throw_length_error(); if (__old_size + __n > capacity()) { const size_type __len = __old_size + max(__old_size, (size_t) __n) + 1; pointer __new_start = _M_allocate(__len); pointer __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, _M_finish, __new_start); __new_finish = uninitialized_copy(__first, __last, __new_finish); _M_construct_null(__new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(_M_start, _M_finish + 1); _M_deallocate_block(); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } else { const _Tp* __f1 = __first; ++__f1; uninitialized_copy(__f1, __last, _M_finish + 1); __STL_TRY { _M_construct_null(_M_finish + __n); } __STL_UNWIND(destroy(_M_finish + 1, _M_finish + __n)); _Traits::assign(*_M_finish, *__first); _M_finish += __n; } } return *this; } #endif /* __STL_MEMBER_TEMPLATES */ template basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc>::assign(size_type __n, _CharT __c) { if (__n <= size()) { _Traits::assign(_M_start, __n, __c); erase(_M_start + __n, _M_finish); } else { _Traits::assign(_M_start, size(), __c); append(__n - size(), __c); } return *this; } #ifdef __STL_MEMBER_TEMPLATES template template basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc> ::_M_assign_dispatch(_InputIter __f, _InputIter __l, __false_type) { pointer __cur = _M_start; while (__f != __l && __cur != _M_finish) { _Traits::assign(*__cur, *__f); ++__f; ++__cur; } if (__f == __l) erase(__cur, _M_finish); else append(__f, __l); return *this; } #endif /* __STL_MEMBER_TEMPLATES */ template basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc>::assign(const _CharT* __f, const _CharT* __l) { const ptrdiff_t __n = __l - __f; if (static_cast(__n) <= size()) { _Traits::copy(_M_start, __f, __n); erase(_M_start + __n, _M_finish); } else { _Traits::copy(_M_start, __f, size()); append(__f + size(), __l); } return *this; } template basic_string<_CharT,_Traits,_Alloc>::iterator basic_string<_CharT,_Traits,_Alloc> ::_M_insert_aux(basic_string<_CharT,_Traits,_Alloc>::iterator __p, _CharT __c) { iterator __new_pos = __p; if (_M_finish + 1 < _M_end_of_storage) { _M_construct_null(_M_finish + 1); _Traits::move(__p + 1, __p, _M_finish - __p); _Traits::assign(*__p, __c); ++_M_finish; } else { const size_type __old_len = size(); const size_type __len = __old_len + max(__old_len, static_cast(1)) + 1; iterator __new_start = _M_allocate(__len); iterator __new_finish = __new_start; __STL_TRY { __new_pos = uninitialized_copy(_M_start, __p, __new_start); construct(__new_pos, __c); __new_finish = __new_pos + 1; __new_finish = uninitialized_copy(__p, _M_finish, __new_finish); _M_construct_null(__new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(_M_start, _M_finish + 1); _M_deallocate_block(); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } return __new_pos; } template void basic_string<_CharT,_Traits,_Alloc> ::insert(basic_string<_CharT,_Traits,_Alloc>::iterator __position, size_t __n, _CharT __c) { if (__n != 0) { if (size_type(_M_end_of_storage - _M_finish) >= __n + 1) { const size_type __elems_after = _M_finish - __position; iterator __old_finish = _M_finish; if (__elems_after >= __n) { uninitialized_copy((_M_finish - __n) + 1, _M_finish + 1, _M_finish + 1); _M_finish += __n; _Traits::move(__position + __n, __position, (__elems_after - __n) + 1); _Traits::assign(__position, __n, __c); } else { uninitialized_fill_n(_M_finish + 1, __n - __elems_after - 1, __c); _M_finish += __n - __elems_after; __STL_TRY { uninitialized_copy(__position, __old_finish + 1, _M_finish); _M_finish += __elems_after; } __STL_UNWIND((destroy(__old_finish + 1, _M_finish), _M_finish = __old_finish)); _Traits::assign(__position, __elems_after + 1, __c); } } else { const size_type __old_size = size(); const size_type __len = __old_size + max(__old_size, __n) + 1; iterator __new_start = _M_allocate(__len); iterator __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, __position, __new_start); __new_finish = uninitialized_fill_n(__new_finish, __n, __c); __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); _M_construct_null(__new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(_M_start, _M_finish + 1); _M_deallocate_block(); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } } } #ifdef __STL_MEMBER_TEMPLATES template template void basic_string<_Tp, _Traits, _Alloc>::insert(iterator __p, _InputIter __first, _InputIter __last, input_iterator_tag) { for ( ; __first != __last; ++__first) { __p = insert(__p, *__first); ++__p; } } template template void basic_string<_CharT,_Traits,_Alloc>::insert(iterator __position, _ForwardIter __first, _ForwardIter __last, forward_iterator_tag) { if (__first != __last) { difference_type __n = 0; distance(__first, __last, __n); if (_M_end_of_storage - _M_finish >= __n + 1) { const difference_type __elems_after = _M_finish - __position; iterator __old_finish = _M_finish; if (__elems_after >= __n) { uninitialized_copy((_M_finish - __n) + 1, _M_finish + 1, _M_finish + 1); _M_finish += __n; _Traits::move(__position + __n, __position, (__elems_after - __n) + 1); _M_copy(__first, __last, __position); } else { _ForwardIter __mid = __first; advance(__mid, __elems_after + 1); uninitialized_copy(__mid, __last, _M_finish + 1); _M_finish += __n - __elems_after; __STL_TRY { uninitialized_copy(__position, __old_finish + 1, _M_finish); _M_finish += __elems_after; } __STL_UNWIND((destroy(__old_finish + 1, _M_finish), _M_finish = __old_finish)); _M_copy(__first, __mid, __position); } } else { const size_type __old_size = size(); const size_type __len = __old_size + max(__old_size, static_cast(__n)) + 1; pointer __new_start = _M_allocate(__len); pointer __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, __position, __new_start); __new_finish = uninitialized_copy(__first, __last, __new_finish); __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); _M_construct_null(__new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(_M_start, _M_finish + 1); _M_deallocate_block(); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } } } #else /* __STL_MEMBER_TEMPLATES */ template void basic_string<_CharT,_Traits,_Alloc>::insert(iterator __position, const _CharT* __first, const _CharT* __last) { if (__first != __last) { const ptrdiff_t __n = __last - __first; if (_M_end_of_storage - _M_finish >= __n + 1) { const ptrdiff_t __elems_after = _M_finish - __position; iterator __old_finish = _M_finish; if (__elems_after >= __n) { uninitialized_copy((_M_finish - __n) + 1, _M_finish + 1, _M_finish + 1); _M_finish += __n; _Traits::move(__position + __n, __position, (__elems_after - __n) + 1); _M_copy(__first, __last, __position); } else { const _CharT* __mid = __first; advance(__mid, __elems_after + 1); uninitialized_copy(__mid, __last, _M_finish + 1); _M_finish += __n - __elems_after; __STL_TRY { uninitialized_copy(__position, __old_finish + 1, _M_finish); _M_finish += __elems_after; } __STL_UNWIND((destroy(__old_finish + 1, _M_finish), _M_finish = __old_finish)); _M_copy(__first, __mid, __position); } } else { const size_type __old_size = size(); const size_type __len = __old_size + max(__old_size, static_cast(__n)) + 1; pointer __new_start = _M_allocate(__len); pointer __new_finish = __new_start; __STL_TRY { __new_finish = uninitialized_copy(_M_start, __position, __new_start); __new_finish = uninitialized_copy(__first, __last, __new_finish); __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); _M_construct_null(__new_finish); } __STL_UNWIND((destroy(__new_start,__new_finish), _M_deallocate(__new_start,__len))); destroy(_M_start, _M_finish + 1); _M_deallocate_block(); _M_start = __new_start; _M_finish = __new_finish; _M_end_of_storage = __new_start + __len; } } } #endif /* __STL_MEMBER_TEMPLATES */ template basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc> ::replace(iterator __first, iterator __last, size_type __n, _CharT __c) { const size_type __len = static_cast(__last - __first); if (__len >= __n) { _Traits::assign(__first, __n, __c); erase(__first + __n, __last); } else { _Traits::assign(__first, __len, __c); insert(__last, __n - __len, __c); } return *this; } #ifdef __STL_MEMBER_TEMPLATES template template basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc> ::replace(iterator __first, iterator __last, _InputIter __f, _InputIter __l, input_iterator_tag) { for ( ; __first != __last && __f != __l; ++__first, ++__f) _Traits::assign(*__first, *__f); if (__f == __l) erase(__first, __last); else insert(__last, __f, __l); return *this; } template template basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc> ::replace(iterator __first, iterator __last, _ForwardIter __f, _ForwardIter __l, forward_iterator_tag) { difference_type __n = 0; distance(__f, __l, __n); const difference_type __len = __last - __first; if (__len >= __n) { _M_copy(__f, __l, __first); erase(__first + __n, __last); } else { _ForwardIter __m = __f; advance(__m, __len); _M_copy(__f, __m, __first); insert(__last, __m, __l); } return *this; } #else /* __STL_MEMBER_TEMPLATES */ template basic_string<_CharT,_Traits,_Alloc>& basic_string<_CharT,_Traits,_Alloc> ::replace(iterator __first, iterator __last, const _CharT* __f, const _CharT* __l) { const ptrdiff_t __n = __l - __f; const difference_type __len = __last - __first; if (__len >= __n) { _M_copy(__f, __l, __first); erase(__first + __n, __last); } else { const _CharT* __m = __f + __len; _M_copy(__f, __m, __first); insert(__last, __m, __l); } return *this; } #endif /* __STL_MEMBER_TEMPLATES */ template basic_string<_CharT,_Traits,_Alloc>::size_type basic_string<_CharT,_Traits,_Alloc> ::find(const _CharT* __s, size_type __pos, size_type __n) const { if (__pos + __n > size()) return npos; else { const const_iterator __result = search(_M_start + __pos, _M_finish, __s, __s + __n, _Eq_traits<_Traits>()); return __result != _M_finish ? __result - begin() : npos; } } template basic_string<_CharT,_Traits,_Alloc>::size_type basic_string<_CharT,_Traits,_Alloc> ::find(_CharT __c, size_type __pos) const { if (__pos >= size()) return npos; else { const const_iterator __result = find_if(_M_start + __pos, _M_finish, bind2nd(_Eq_traits<_Traits>(), __c)); return __result != _M_finish ? __result - begin() : npos; } } template basic_string<_CharT,_Traits,_Alloc>::size_type basic_string<_CharT,_Traits,_Alloc> ::rfind(const _CharT* __s, size_type __pos, size_type __n) const { const size_t __len = size(); if (__n > __len) return npos; else if (__n == 0) return min(__len, __pos); else { const const_iterator __last = begin() + min(__len - __n, __pos) + __n; const const_iterator __result = find_end(begin(), __last, __s, __s + __n, _Eq_traits<_Traits>()); return __result != __last ? __result - begin() : npos; } } template basic_string<_CharT,_Traits,_Alloc>::size_type basic_string<_CharT,_Traits,_Alloc> ::rfind(_CharT __c, size_type __pos) const { const size_type __len = size(); if (__len < 1) return npos; else { const const_iterator __last = begin() + min(__len - 1, __pos) + 1; const_reverse_iterator __rresult = find_if(const_reverse_iterator(__last), rend(), bind2nd(_Eq_traits<_Traits>(), __c)); return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos; } } template 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 { if (__pos >= size()) return npos; else { const_iterator __result = __STD::find_first_of(begin() + __pos, end(), __s, __s + __n, _Eq_traits<_Traits>()); return __result != _M_finish ? __result - begin() : npos; } } template 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 { const size_type __len = size(); if (__len < 1) return npos; else { const const_iterator __last = _M_start + min(__len - 1, __pos) + 1; const const_reverse_iterator __rresult = __STD::find_first_of(const_reverse_iterator(__last), rend(), __s, __s + __n, _Eq_traits<_Traits>()); return __rresult != rend() ? (__rresult.base() - 1) - _M_start : npos; } } template 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 { if (__pos > size()) return npos; else { const_iterator __result = find_if(_M_start + __pos, _M_finish, _Not_within_traits<_Traits>(__s, __s + __n)); return __result != _M_finish ? __result - _M_start : npos; } } template basic_string<_CharT,_Traits,_Alloc>::size_type basic_string<_CharT,_Traits,_Alloc> ::find_first_not_of(_CharT __c, size_type __pos) const { if (__pos > size()) return npos; else { const_iterator __result = find_if(begin() + __pos, end(), not1(bind2nd(_Eq_traits<_Traits>(), __c))); return __result != _M_finish ? __result - begin() : npos; } } template 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 { const size_type __len = size(); if (__len < 1) return npos; else { const const_iterator __last = begin() + min(__len - 1, __pos) + 1; const const_reverse_iterator __rresult = find_if(const_reverse_iterator(__last), rend(), _Not_within_traits<_Traits>(__s, __s + __n)); return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos; } } template basic_string<_Tp, _Traits, _Alloc>::size_type basic_string<_Tp, _Traits, _Alloc> ::find_last_not_of(_Tp __c, size_type __pos) const { const size_type __len = size(); if (__len < 1) return npos; else { const const_iterator __last = begin() + min(__len - 1, __pos) + 1; const_reverse_iterator __rresult = find_if(const_reverse_iterator(__last), rend(), not1(bind2nd(_Eq_traits<_Traits>(), __c))); return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos; } } // ------------------------------------------------------------ // Non-member functions. // Operator+ template inline basic_string<_CharT,_Traits,_Alloc> operator+(const basic_string<_CharT,_Traits,_Alloc>& __x, const basic_string<_CharT,_Traits,_Alloc>& __y) { typedef basic_string<_CharT,_Traits,_Alloc> _Str; typedef typename _Str::_Reserve_t _Reserve_t; _Reserve_t __reserve; _Str __result(__reserve, __x.size() + __y.size(), __x.get_allocator()); __result.append(__x); __result.append(__y); return __result; } template inline basic_string<_CharT,_Traits,_Alloc> operator+(const _CharT* __s, const basic_string<_CharT,_Traits,_Alloc>& __y) { typedef basic_string<_CharT,_Traits,_Alloc> _Str; typedef typename _Str::_Reserve_t _Reserve_t; _Reserve_t __reserve; const size_t __n = _Traits::length(__s); _Str __result(__reserve, __n + __y.size()); __result.append(__s, __s + __n); __result.append(__y); return __result; } template inline basic_string<_CharT,_Traits,_Alloc> operator+(_CharT __c, const basic_string<_CharT,_Traits,_Alloc>& __y) { typedef basic_string<_CharT,_Traits,_Alloc> _Str; typedef typename _Str::_Reserve_t _Reserve_t; _Reserve_t __reserve; _Str __result(__reserve, 1 + __y.size()); __result.push_back(__c); __result.append(__y); return __result; } template inline basic_string<_CharT,_Traits,_Alloc> operator+(const basic_string<_CharT,_Traits,_Alloc>& __x, const _CharT* __s) { typedef basic_string<_CharT,_Traits,_Alloc> _Str; typedef typename _Str::_Reserve_t _Reserve_t; _Reserve_t __reserve; const size_t __n = _Traits::length(__s); _Str __result(__reserve, __x.size() + __n, __x.get_allocator()); __result.append(__x); __result.append(__s, __s + __n); return __result; } template inline basic_string<_CharT,_Traits,_Alloc> operator+(const basic_string<_CharT,_Traits,_Alloc>& __x, const _CharT __c) { typedef basic_string<_CharT,_Traits,_Alloc> _Str; typedef typename _Str::_Reserve_t _Reserve_t; _Reserve_t __reserve; _Str __result(__reserve, __x.size() + 1, __x.get_allocator()); __result.append(__x); __result.push_back(__c); return __result; } // Operator== and operator!= template inline bool operator==(const basic_string<_CharT,_Traits,_Alloc>& __x, const basic_string<_CharT,_Traits,_Alloc>& __y) { return __x.size() == __y.size() && _Traits::compare(__x.data(), __y.data(), __x.size()) == 0; } template inline bool operator==(const _CharT* __s, const basic_string<_CharT,_Traits,_Alloc>& __y) { size_t __n = _Traits::length(__s); return __n == __y.size() && _Traits::compare(__s, __y.data(), __n) == 0; } template inline bool operator==(const basic_string<_CharT,_Traits,_Alloc>& __x, const _CharT* __s) { size_t __n = _Traits::length(__s); return __x.size() == __n && _Traits::compare(__x.data(), __s, __n) == 0; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator!=(const basic_string<_CharT,_Traits,_Alloc>& __x, const basic_string<_CharT,_Traits,_Alloc>& __y) { return !(__x == __y); } template inline bool operator!=(const _CharT* __s, const basic_string<_CharT,_Traits,_Alloc>& __y) { return !(__s == __y); } template inline bool operator!=(const basic_string<_CharT,_Traits,_Alloc>& __x, const _CharT* __s) { return !(__x == __s); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Operator< (and also >, <=, and >=). template inline bool operator<(const basic_string<_CharT,_Traits,_Alloc>& __x, const basic_string<_CharT,_Traits,_Alloc>& __y) { return basic_string<_CharT,_Traits,_Alloc> ::_M_compare(__x.begin(), __x.end(), __y.begin(), __y.end()) < 0; } template inline bool operator<(const _CharT* __s, const basic_string<_CharT,_Traits,_Alloc>& __y) { size_t __n = _Traits::length(__s); return basic_string<_CharT,_Traits,_Alloc> ::_M_compare(__s, __s + __n, __y.begin(), __y.end()) < 0; } template inline bool operator<(const basic_string<_CharT,_Traits,_Alloc>& __x, const _CharT* __s) { size_t __n = _Traits::length(__s); return basic_string<_CharT,_Traits,_Alloc> ::_M_compare(__x.begin(), __x.end(), __s, __s + __n) < 0; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline bool operator>(const basic_string<_CharT,_Traits,_Alloc>& __x, const basic_string<_CharT,_Traits,_Alloc>& __y) { return __y < __x; } template inline bool operator>(const _CharT* __s, const basic_string<_CharT,_Traits,_Alloc>& __y) { return __y < __s; } template inline bool operator>(const basic_string<_CharT,_Traits,_Alloc>& __x, const _CharT* __s) { return __s < __x; } template inline bool operator<=(const basic_string<_CharT,_Traits,_Alloc>& __x, const basic_string<_CharT,_Traits,_Alloc>& __y) { return !(__y < __x); } template inline bool operator<=(const _CharT* __s, const basic_string<_CharT,_Traits,_Alloc>& __y) { return !(__y < __s); } template inline bool operator<=(const basic_string<_CharT,_Traits,_Alloc>& __x, const _CharT* __s) { return !(__s < __x); } template inline bool operator>=(const basic_string<_CharT,_Traits,_Alloc>& __x, const basic_string<_CharT,_Traits,_Alloc>& __y) { return !(__x < __y); } template inline bool operator>=(const _CharT* __s, const basic_string<_CharT,_Traits,_Alloc>& __y) { return !(__s < __y); } template inline bool operator>=(const basic_string<_CharT,_Traits,_Alloc>& __x, const _CharT* __s) { return !(__x < __s); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Swap. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(basic_string<_CharT,_Traits,_Alloc>& __x, basic_string<_CharT,_Traits,_Alloc>& __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // I/O. #ifndef __STL_USE_NEW_IOSTREAMS __STL_END_NAMESPACE #include __STL_BEGIN_NAMESPACE #endif /* __STL_USE_NEW_IOSTREAMS */ #ifdef __STL_USE_NEW_IOSTREAMS template inline bool __sgi_string_fill(basic_ostream<_CharT, _Traits>& __os, basic_streambuf<_CharT, _Traits>* __buf, size_t __n) { _CharT __f = __os.fill(); size_t __i; bool __ok = true; for (__i = 0; __i < __n; __i++) __ok = __ok && !_Traits::eq_int_type(__buf->sputc(__f), _Traits::eof()); return __ok; } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT,_Traits,_Alloc>& __s) { typename basic_ostream<_CharT, _Traits>::sentry __sentry(__os); bool __ok = false; if (__sentry) { __ok = true; size_t __n = __s.size(); size_t __pad_len = 0; const bool __left = (__os.flags() & ios::left) != 0; const size_t __w = __os.width(0); basic_streambuf<_CharT, _Traits>* __buf = __os.rdbuf(); if (__w != 0 && __n < __w) __pad_len = __w - __n; if (!__left) __ok = __sgi_string_fill(__os, __buf, __pad_len); __ok = __ok && __buf->sputn(__s.data(), streamsize(__n)) == streamsize(__n); if (__left) __ok = __ok && __sgi_string_fill(__os, __buf, __pad_len); } if (!__ok) __os.setstate(ios_base::failbit); return __os; } template basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT,_Traits,_Alloc>& __s) { typename basic_istream<_CharT, _Traits>::sentry __sentry(__is); if (__sentry) { basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); const ctype<_CharT>& __ctype = use_facet >(__is.getloc()); __s.clear(); size_t __n = __is.width(0); if (__n == 0) __n = static_cast(-1); else __s.reserve(__n); while (__n-- > 0) { typename _Traits::int_type __c1 = __buf->sbumpc(); if (_Traits::eq_int_type(__c1, _Traits::eof())) { __is.setstate(ios_base::eofbit); break; } else { _CharT __c = _Traits::to_char_type(__c1); if (__ctype.is(ctype<_CharT>::space, __c)) { if (_Traits::eq_int_type(__buf->sputbackc(__c), _Traits::eof())) __is.setstate(ios_base::failbit); break; } else __s.push_back(__c); } } // If we have read no characters, then set failbit. if (__s.size() == 0) __is.setstate(ios_base::failbit); } else __is.setstate(ios_base::failbit); return __is; } template basic_istream<_CharT, _Traits>& getline(istream& __is, basic_string<_CharT,_Traits,_Alloc>& __s, _CharT __delim) { size_t __nread = 0; typename basic_istream<_CharT, _Traits>::sentry __sentry(__is, true); if (__sentry) { basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); __s.clear(); int __c1; while (__nread < __s.max_size()) { int __c1 = __buf->sbumpc(); if (_Traits::eq_int_type(__c1, _Traits::eof())) { __is.setstate(ios_base::eofbit); break; } else { ++__nread; _CharT __c = _Traits::to_char_type(__c1); if (!_Traits::eq(__c, __delim)) __s.push_back(__c); else break; // Character is extracted but not appended. } } } if (__nread == 0 || __nread >= __s.max_size()) __is.setstate(ios_base::failbit); return __is; } template inline basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT,_Traits,_Alloc>& __s) { return getline(__is, __s, '\n'); } #else /* __STL_USE_NEW_IOSTREAMS */ inline void __sgi_string_fill(ostream& __os, streambuf* __buf, size_t __n) { char __f = __os.fill(); size_t __i; for (__i = 0; __i < __n; __i++) __buf->sputc(__f); } template ostream& operator<<(ostream& __os, const basic_string<_CharT,_Traits,_Alloc>& __s) { streambuf* __buf = __os.rdbuf(); if (__buf) { size_t __n = __s.size(); size_t __pad_len = 0; const bool __left = (__os.flags() & ios::left) != 0; const size_t __w = __os.width(); if (__w > 0) { __n = min(__w, __n); __pad_len = __w - __n; } if (!__left) __sgi_string_fill(__os, __buf, __pad_len); const size_t __nwritten = __buf->sputn(__s.data(), __n); if (__left) __sgi_string_fill(__os, __buf, __pad_len); if (__nwritten != __n) __os.clear(__os.rdstate() | ios::failbit); __os.width(0); } else __os.clear(__os.rdstate() | ios::badbit); return __os; } template istream& operator>>(istream& __is, basic_string<_CharT,_Traits,_Alloc>& __s) { if (!__is) return __is; streambuf* __buf = __is.rdbuf(); if (__buf) { #ifdef __USLC__ /* Jochen Schlick '1999 - operator >> modified. Work-around to get the * output buffer flushed (necessary when using * "cout" (without endl or flushing) followed by * "cin >>" ...) */ if (__is.flags() & ios::skipws) { _CharT __c; do __is.get(__c); while (__is && isspace(__c)); if (__is) __is.putback(__c); } #else if (__is.flags() & ios::skipws) { int __c; do { __c = __buf->sbumpc(); } while (__c != EOF && isspace((unsigned char)__c)); if (__c == EOF) { __is.clear(__is.rdstate() | ios::eofbit | ios::failbit); } else { if (__buf->sputbackc(__c) == EOF) __is.clear(__is.rdstate() | ios::failbit); } } #endif // If we arrive at end of file (or fail for some other reason) while // still discarding whitespace, then we don't try to read the string. if (__is) { __s.clear(); size_t __n = __is.width(); if (__n == 0) __n = static_cast(-1); else __s.reserve(__n); while (__n-- > 0) { int __c1 = __buf->sbumpc(); if (__c1 == EOF) { __is.clear(__is.rdstate() | ios::eofbit); break; } else { _CharT __c = _Traits::to_char_type(__c1); if (isspace((unsigned char) __c)) { if (__buf->sputbackc(__c) == EOF) __is.clear(__is.rdstate() | ios::failbit); break; } else __s.push_back(__c); } } // If we have read no characters, then set failbit. if (__s.size() == 0) __is.clear(__is.rdstate() | ios::failbit); } __is.width(0); } else // We have no streambuf. __is.clear(__is.rdstate() | ios::badbit); return __is; } template istream& getline(istream& __is, basic_string<_CharT,_Traits,_Alloc>& __s, _CharT __delim) { streambuf* __buf = __is.rdbuf(); if (__buf) { size_t __nread = 0; if (__is) { __s.clear(); while (__nread < __s.max_size()) { int __c1 = __buf->sbumpc(); if (__c1 == EOF) { __is.clear(__is.rdstate() | ios::eofbit); break; } else { ++__nread; _CharT __c = _Traits::to_char_type(__c1); if (!_Traits::eq(__c, __delim)) __s.push_back(__c); else break; // Character is extracted but not appended. } } } if (__nread == 0 || __nread >= __s.max_size()) __is.clear(__is.rdstate() | ios::failbit); } else __is.clear(__is.rdstate() | ios::badbit); return __is; } template inline istream& getline(istream& __is, basic_string<_CharT,_Traits,_Alloc>& __s) { return getline(__is, __s, '\n'); } #endif /* __STL_USE_NEW_IOSTREAMS */ template void _S_string_copy(const basic_string<_CharT,_Traits,_Alloc>& __s, _CharT* __buf, size_t __n) { if (__n > 0) { __n = min(__n - 1, __s.size()); copy(__s.begin(), __s.begin() + __n, __buf); _Traits::assign(__buf[__n], basic_string<_CharT,_Traits,_Alloc>::_M_null()); } } inline const char* __get_c_string(const string& __s) { return __s.c_str(); } // ------------------------------------------------------------ // Typedefs #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #pragma reset woff 1375 #endif __STL_END_NAMESPACE #include __STL_BEGIN_NAMESPACE template size_t __stl_string_hash(const basic_string<_CharT,_Traits,_Alloc>& __s) { unsigned long __h = 0; for (basic_string<_CharT,_Traits,_Alloc>::const_iterator __i = __s.begin(); __i != __s.end(); ++__i) __h = 5*__h + *__i; return size_t(__h); } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template struct hash > { size_t operator()(const basic_string<_CharT,_Traits,_Alloc>& __s) const { return __stl_string_hash(__s); } }; #else __STL_TEMPLATE_NULL struct hash { size_t operator()(const string& __s) const { return __stl_string_hash(__s); } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(const wstring& __s) const { return __stl_string_hash(__s); } }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ __STL_END_NAMESPACE #endif /* __SGI_STL_STRING */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/tempbuf.h ================================================ /* * * 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 __SGI_STL_TEMPBUF_H #define __SGI_STL_TEMPBUF_H #ifndef __SGI_STL_PAIR_H #include #endif #include /* XXX should use */ #include /* XXX should use */ #include /* XXX should use */ #ifndef __TYPE_TRAITS_H #include #endif #ifndef __SGI_STL_INTERNAL_CONSTRUCT_H #include #endif #ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H #include #endif #ifndef __SGI_STL_INTERNAL_TEMPBUF_H #include #endif #ifdef __STL_USE_NAMESPACES using __STD::get_temporary_buffer; using __STD::return_temporary_buffer; using __STD::temporary_buffer; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_TEMPBUF_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/tree.h ================================================ /* * * 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. * * */ #ifndef __SGI_STL_TREE_H #define __SGI_STL_TREE_H #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #ifdef __STL_USE_NAMESPACES using __STD::rb_tree; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_TREE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/type_traits.h ================================================ /* * * 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 __TYPE_TRAITS_H #define __TYPE_TRAITS_H #ifndef __STL_CONFIG_H #include #endif /* This header file provides a framework for allowing compile time dispatch based on type attributes. This is useful when writing template code. For example, when making a copy of an array of an unknown type, it helps to know if the type has a trivial copy constructor or not, to help decide if a memcpy can be used. The class template __type_traits provides a series of typedefs each of which is either __true_type or __false_type. The argument to __type_traits can be any type. The typedefs within this template will attain their correct values by one of these means: 1. The general instantiation contain conservative values which work for all types. 2. Specializations may be declared to make distinctions between types. 3. Some compilers (such as the Silicon Graphics N32 and N64 compilers) will automatically provide the appropriate specializations for all types. EXAMPLE: //Copy an array of elements which have non-trivial copy constructors template void copy(T* source, T* destination, int n, __false_type); //Copy an array of elements which have trivial copy constructors. Use memcpy. template void copy(T* source, T* destination, int n, __true_type); //Copy an array of any type by using the most efficient copy mechanism template inline void copy(T* source,T* destination,int n) { copy(source, destination, n, typename __type_traits::has_trivial_copy_constructor()); } */ struct __true_type { }; struct __false_type { }; template struct __type_traits { typedef __true_type this_dummy_member_must_be_first; /* Do not remove this member. It informs a compiler which automatically specializes __type_traits that this __type_traits template is special. It just makes sure that things work if an implementation is using a template called __type_traits for something unrelated. */ /* The following restrictions should be observed for the sake of compilers which automatically produce type specific specializations of this class: - You may reorder the members below if you wish - You may remove any of the members below if you wish - You must not rename members without making the corresponding name change in the compiler - Members you add will be treated like regular members unless you add the appropriate support in the compiler. */ typedef __false_type has_trivial_default_constructor; typedef __false_type has_trivial_copy_constructor; typedef __false_type has_trivial_assignment_operator; typedef __false_type has_trivial_destructor; typedef __false_type is_POD_type; }; // Provide some specializations. This is harmless for compilers that // have built-in __types_traits support, and essential for compilers // that don't. #ifndef __STL_NO_BOOL __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_NO_BOOL */ __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_HAS_WCHAR_T __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_HAS_WCHAR_T */ __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_LONG_LONG __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_LONG_LONG */ __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template struct __type_traits<_Tp*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // The following could be written in terms of numeric_limits. // We're doing it separately to reduce the number of dependencies. template struct _Is_integer { typedef __false_type _Integral; }; #ifndef __STL_NO_BOOL __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; #endif /* __STL_NO_BOOL */ __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; #ifdef __STL_HAS_WCHAR_T __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; #endif /* __STL_HAS_WCHAR_T */ __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; #ifdef __STL_LONG_LONG __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer { typedef __true_type _Integral; }; #endif /* __STL_LONG_LONG */ #endif /* __TYPE_TRAITS_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/utility ================================================ /* * * 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 __SGI_STL_UTILITY #define __SGI_STL_UTILITY #include #include #include #endif /* __SGI_STL_UTILITY */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/valarray ================================================ /* * Copyright (c) 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. */ #ifndef __SGI_STL_VALARRAY #define __SGI_STL_VALARRAY #include #include #include #include #include #include __STL_BEGIN_NAMESPACE class slice; class gslice; template class valarray; template class slice_array; template class gslice_array; template class mask_array; template class indirect_array; //---------------------------------------------------------------------- // class valarray // Base class to handle memory allocation and deallocation. We can't just // use vector<>, because vector would be unsuitable as an internal // representation for valarray. template struct _Valarray_base { _Tp* _M_first; size_t _M_size; _Valarray_base() : _M_first(0), _M_size(0) {} _Valarray_base(size_t __n) : _M_first(0), _M_size(0) { _M_allocate(__n); } ~_Valarray_base() { _M_deallocate(); } void _M_allocate(size_t __n) { if (__n != 0) { _M_first = static_cast<_Tp*>(malloc(__n * sizeof(_Tp))); _M_size = __n; # if !defined(__STL_NO_BAD_ALLOC) && defined(__STL_USE_EXCEPTIONS) if (_M_first == 0) { _M_size = 0; throw std::bad_alloc(); } # endif } else { _M_first = 0; _M_size = 0; } } void _M_deallocate() { free(_M_first); _M_first = 0; _M_size = 0; } }; template class valarray : private _Valarray_base<_Tp> { friend class gslice; public: typedef _Tp value_type; // Basic constructors valarray() : _Valarray_base<_Tp>() {} valarray(size_t __n) : _Valarray_base<_Tp>(__n) { uninitialized_fill_n(this->_M_first, this->_M_size, value_type()); } valarray(const value_type& __x, size_t __n) : _Valarray_base<_Tp>(__n) { uninitialized_fill_n(this->_M_first, this->_M_size, __x); } valarray(const value_type* __p, size_t __n) : _Valarray_base<_Tp>(__n) { uninitialized_copy(__p, __p + __n, this->_M_first); } valarray(const valarray& __x) : _Valarray_base<_Tp>(__x._M_size) { uninitialized_copy(__x._M_first, __x._M_first + __x._M_size, this->_M_first); } // Constructors from auxiliary array types valarray(const slice_array<_Tp>&); valarray(const gslice_array<_Tp>&); valarray(const mask_array<_Tp>&); valarray(const indirect_array<_Tp>&); // Destructor ~valarray() { destroy(this->_M_first, this->_M_first + this->_M_size); } // Extension: constructor that doesn't initialize valarray elements to a // specific value. This is faster for types such as int and double. private: void _M_initialize(__true_type) {} void _M_initialize(__false_type) { uninitialized_fill_n(this->_M_first, this->_M_size, value_type()); } public: struct _NoInit {}; valarray(size_t __n, _NoInit) : _Valarray_base<_Tp>(__n) { typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Is_Trivial; _M_initialize(_Is_Trivial()); } public: // Assignment // Basic assignment. Note that 'x = y' is undefined if x.size() != y.size() valarray& operator=(const valarray& __x) { if (this != &__x) copy(__x._M_first, __x._M_first + __x._M_size, this->_M_first); return *this; } // Scalar assignment valarray& operator=(const value_type& __x) { fill_n(this->_M_first, this->_M_size, __x); return *this; } // Assignment of auxiliary array types valarray& operator=(const slice_array<_Tp>&); valarray& operator=(const gslice_array<_Tp>&); valarray& operator=(const mask_array<_Tp>&); valarray& operator=(const indirect_array<_Tp>&); public: // Element access value_type operator[](size_t __n) const { return this->_M_first[__n]; } value_type& operator[](size_t __n) { return this->_M_first[__n]; } size_t size() const { return this->_M_size; } public: // Subsetting operations with auxiliary type valarray operator[](slice) const; slice_array<_Tp> operator[](slice); valarray operator[](gslice) const; gslice_array<_Tp> operator[](gslice); valarray operator[](const valarray&) const; mask_array<_Tp> operator[](const valarray&); valarray operator[](const valarray&) const; indirect_array<_Tp> operator[](const valarray&); public: // Unary operators. valarray operator+() const { return *this; } valarray operator-() const { valarray __tmp(this->size(), _NoInit()); for (size_t __i = 0; __i < this->size(); ++__i) __tmp[__i] = -(*this)[__i]; return __tmp; } valarray operator~() const { valarray __tmp(this->size(), _NoInit()); for (size_t __i = 0; __i < this->size(); ++__i) __tmp[__i] = ~(*this)[__i]; return __tmp; } valarray operator!() const { valarray __tmp(this->size(), valarray::_NoInit()); for (size_t __i = 0; __i < this->size(); ++__i) __tmp[__i] = !(*this)[__i]; return __tmp; } public: // Scalar computed assignment. valarray& operator*= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] *= __x; return *this; } valarray& operator/= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] /= __x; return *this; } valarray& operator%= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] %= __x; return *this; } valarray& operator+= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] += __x; return *this; } valarray& operator-= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] -= __x; return *this; } valarray& operator^= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] ^= __x; return *this; } valarray& operator&= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] &= __x; return *this; } valarray& operator|= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] |= __x; return *this; } valarray& operator<<= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] <<= __x; return *this; } valarray& operator>>= (const value_type& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] >>= __x; return *this; } public: // Array computed assignment. valarray& operator*= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] *= __x[__i]; return *this; } valarray& operator/= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] /= __x[__i]; return *this; } valarray& operator%= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] %= __x[__i]; return *this; } valarray& operator+= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] += __x[__i]; return *this; } valarray& operator-= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] -= __x[__i]; return *this; } valarray& operator^= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] ^= __x[__i]; return *this; } valarray& operator&= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] &= __x[__i]; return *this; } valarray& operator|= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] |= __x[__i]; return *this; } valarray& operator<<= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] <<= __x[__i]; return *this; } valarray& operator>>= (const valarray& __x) { for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i] >>= __x[__i]; return *this; } public: // Other member functions. // The result is undefined for zero-length arrays value_type sum() const { return accumulate(this->_M_first + 1, this->_M_first + this->_M_size, (*this)[0]); } // The result is undefined for zero-length arrays value_type min() const { return *min_element(this->_M_first + 0, this->_M_first + this->_M_size); } value_type max() const { return *max_element(this->_M_first + 0, this->_M_first + this->_M_size); } valarray shift(int __n) const; valarray cshift(int __n) const; valarray apply(value_type __f(value_type)) const { valarray __tmp(this->size()); transform(this->_M_first, this->_M_first + this->_M_size, __tmp._M_first, __f); return __tmp; } valarray apply(value_type __f(const value_type&)) const { valarray __tmp(this->size()); transform(this->_M_first, this->_M_first + this->_M_size, __tmp._M_first, __f); return __tmp; } void resize(size_t __n, value_type __x = value_type()) { destroy(this->_M_first, this->_M_first + this->_M_size); this->_Valarray_base<_Tp>::_M_deallocate(); this->_Valarray_base<_Tp>::_M_allocate(__n); uninitialized_fill_n(this->_M_first, this->_M_size, __x); } }; //---------------------------------------------------------------------- // valarray non-member functions. // Binary arithmetic operations between two arrays. Behavior is // undefined if the two arrays do not have the same length. template inline valarray<_Tp> operator*(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] * __y[__i]; return __tmp; } template inline valarray<_Tp> operator/(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] / __y[__i]; return __tmp; } template inline valarray<_Tp> operator%(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] % __y[__i]; return __tmp; } template inline valarray<_Tp> operator+(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] + __y[__i]; return __tmp; } template inline valarray<_Tp> operator-(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] - __y[__i]; return __tmp; } template inline valarray<_Tp> operator^(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] ^ __y[__i]; return __tmp; } template inline valarray<_Tp> operator&(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] & __y[__i]; return __tmp; } template inline valarray<_Tp> operator|(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] | __y[__i]; return __tmp; } template inline valarray<_Tp> operator<<(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] << __y[__i]; return __tmp; } template inline valarray<_Tp> operator>>(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] >> __y[__i]; return __tmp; } // Binary arithmetic operations between an array and a scalar. template inline valarray<_Tp> operator*(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] * __c; return __tmp; } template inline valarray<_Tp> operator*(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c * __x[__i]; return __tmp; } template inline valarray<_Tp> operator/(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] / __c; return __tmp; } template inline valarray<_Tp> operator/(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c / __x[__i]; return __tmp; } template inline valarray<_Tp> operator%(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] % __c; return __tmp; } template inline valarray<_Tp> operator%(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c % __x[__i]; return __tmp; } template inline valarray<_Tp> operator+(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] + __c; return __tmp; } template inline valarray<_Tp> operator+(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c + __x[__i]; return __tmp; } template inline valarray<_Tp> operator-(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] - __c; return __tmp; } template inline valarray<_Tp> operator-(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c - __x[__i]; return __tmp; } template inline valarray<_Tp> operator^(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] ^ __c; return __tmp; } template inline valarray<_Tp> operator^(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c ^ __x[__i]; return __tmp; } template inline valarray<_Tp> operator&(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] & __c; return __tmp; } template inline valarray<_Tp> operator&(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c & __x[__i]; return __tmp; } template inline valarray<_Tp> operator|(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] | __c; return __tmp; } template inline valarray<_Tp> operator|(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c | __x[__i]; return __tmp; } template inline valarray<_Tp> operator<<(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] << __c; return __tmp; } template inline valarray<_Tp> operator<<(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c << __x[__i]; return __tmp; } template inline valarray<_Tp> operator>>(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] >> __c; return __tmp; } template inline valarray<_Tp> operator>>(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c >> __x[__i]; return __tmp; } // Binary logical operations between two arrays. Behavior is undefined // if the two arrays have different lengths. Note that operator== does // not do what you might at first expect. template inline valarray operator==(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] == __y[__i]; return __tmp; } template inline valarray operator<(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] < __y[__i]; return __tmp; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline valarray operator!=(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] != __y[__i]; return __tmp; } template inline valarray operator>(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] > __y[__i]; return __tmp; } template inline valarray operator<=(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] <= __y[__i]; return __tmp; } template inline valarray operator>=(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] >= __y[__i]; return __tmp; } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template inline valarray operator&&(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] && __y[__i]; return __tmp; } template inline valarray operator||(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] || __y[__i]; return __tmp; } // Logical operations between an array and a scalar. template inline valarray operator==(const valarray<_Tp>& __x, const _Tp& __c) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] == __c; return __tmp; } template inline valarray operator==(const _Tp& __c, const valarray<_Tp>& __x) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c == __x[__i]; return __tmp; } template inline valarray operator!=(const valarray<_Tp>& __x, const _Tp& __c) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] != __c; return __tmp; } template inline valarray operator!=(const _Tp& __c, const valarray<_Tp>& __x) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c != __x[__i]; return __tmp; } template inline valarray operator<(const valarray<_Tp>& __x, const _Tp& __c) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] < __c; return __tmp; } template inline valarray operator<(const _Tp& __c, const valarray<_Tp>& __x) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c < __x[__i]; return __tmp; } template inline valarray operator>(const valarray<_Tp>& __x, const _Tp& __c) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] > __c; return __tmp; } template inline valarray operator>(const _Tp& __c, const valarray<_Tp>& __x) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c > __x[__i]; return __tmp; } template inline valarray operator<=(const valarray<_Tp>& __x, const _Tp& __c) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] <= __c; return __tmp; } template inline valarray operator<=(const _Tp& __c, const valarray<_Tp>& __x) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c <= __x[__i]; return __tmp; } template inline valarray operator>=(const valarray<_Tp>& __x, const _Tp& __c) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] >= __c; return __tmp; } template inline valarray operator>=(const _Tp& __c, const valarray<_Tp>& __x) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c >= __x[__i]; return __tmp; } template inline valarray operator&&(const valarray<_Tp>& __x, const _Tp& __c) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] && __c; return __tmp; } template inline valarray operator&&(const _Tp& __c, const valarray<_Tp>& __x) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c && __x[__i]; return __tmp; } template inline valarray operator||(const valarray<_Tp>& __x, const _Tp& __c) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __x[__i] || __c; return __tmp; } template inline valarray operator||(const _Tp& __c, const valarray<_Tp>& __x) { valarray __tmp(__x.size(), valarray::_NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = __c || __x[__i]; return __tmp; } // valarray "transcendentals" (the list includes abs and sqrt, which, // of course, are not transcendental). template inline valarray<_Tp> abs(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = abs(__x[__i]); return __tmp; } template inline valarray<_Tp> acos(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = acos(__x[__i]); return __tmp; } template inline valarray<_Tp> asin(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = asin(__x[__i]); return __tmp; } template inline valarray<_Tp> atan(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = atan(__x[__i]); return __tmp; } template inline valarray<_Tp> atan2(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = atan2(__x[__i], __y[__i]); return __tmp; } template inline valarray<_Tp> atan2(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = atan2(__x[__i], __c); return __tmp; } template inline valarray<_Tp> atan2(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = atan2(__c, __x[__i]); return __tmp; } template inline valarray<_Tp> cos(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = cos(__x[__i]); return __tmp; } template inline valarray<_Tp> cosh(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = cosh(__x[__i]); return __tmp; } template inline valarray<_Tp> exp(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = exp(__x[__i]); return __tmp; } template inline valarray<_Tp> log(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = log(__x[__i]); return __tmp; } template inline valarray<_Tp> log10(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = log10(__x[__i]); return __tmp; } template inline valarray<_Tp> pow(const valarray<_Tp>& __x, const valarray<_Tp>& __y) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = pow(__x[__i], __y[__i]); return __tmp; } template inline valarray<_Tp> pow(const valarray<_Tp>& __x, const _Tp& __c) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = pow(__x[__i], __c); return __tmp; } template inline valarray<_Tp> pow(const _Tp& __c, const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = pow(__c, __x[__i]); return __tmp; } template inline valarray<_Tp> sin(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = sin(__x[__i]); return __tmp; } template inline valarray<_Tp> sinh(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = sinh(__x[__i]); return __tmp; } template inline valarray<_Tp> sqrt(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = sqrt(__x[__i]); return __tmp; } template inline valarray<_Tp> tan(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = tan(__x[__i]); return __tmp; } template inline valarray<_Tp> tanh(const valarray<_Tp>& __x) { typedef typename valarray<_Tp>::_NoInit _NoInit; valarray<_Tp> __tmp(__x.size(), _NoInit()); for (size_t __i = 0; __i < __x.size(); ++__i) __tmp[__i] = tanh(__x[__i]); return __tmp; } //---------------------------------------------------------------------- // slice and slice_array class slice { public: slice() : _M_start(0), _M_length(0), _M_stride(0) {} slice(size_t __start, size_t __length, size_t __stride) : _M_start(__start), _M_length(__length), _M_stride(__stride) {} size_t start() const { return _M_start; } size_t size() const { return _M_length; } size_t stride() const { return _M_stride; } private: size_t _M_start; size_t _M_length; size_t _M_stride; }; template class slice_array { friend class valarray<_Tp>; public: typedef _Tp value_type; void operator=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] = __x[__i]; } void operator*=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] *= __x[__i]; } void operator/=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] /= __x[__i]; } void operator%=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] %= __x[__i]; } void operator+=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] += __x[__i]; } void operator-=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] -= __x[__i]; } void operator^=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] ^= __x[__i]; } void operator&=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] &= __x[__i]; } void operator|=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] |= __x[__i]; } void operator<<=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] <<= __x[__i]; } void operator>>=(const valarray& __x) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] >>= __x[__i]; } void operator=(const value_type& __c) const { size_t __index = _M_slice.start(); for (size_t __i = 0; __i < _M_slice.size(); ++__i, __index += _M_slice.stride()) _M_array[__index] = __c; } ~slice_array() {} private: slice_array(const slice& __slice, valarray<_Tp>& __array) : _M_slice(__slice), _M_array(__array) {} slice _M_slice; valarray<_Tp>& _M_array; private: // Disable assignment and default constructor slice_array(); }; // valarray member functions dealing with slice and slice_array template inline valarray<_Tp>::valarray(const slice_array<_Tp>& __x) : _Valarray_base<_Tp>(__x._M_slice.size()) { typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Is_Trivial; _M_initialize(_Is_Trivial()); *this = __x; } // Behavior is undefined if __x and *this have different sizes template valarray<_Tp>& valarray<_Tp>::operator=(const slice_array<_Tp>& __x) { size_t __index = __x._M_slice.start(); for (size_t __i = 0; __i < __x._M_slice.size(); ++__i, __index += __x._M_slice.stride()) (*this)[__i] = __x._M_array[__index]; return *this; } template valarray<_Tp> valarray<_Tp>::operator[](slice __slice) const { valarray<_Tp> __tmp(__slice.size(), _NoInit()); size_t __index = __slice.start(); for (size_t __i = 0; __i < __slice.size(); ++__i, __index += __slice.stride()) __tmp[__i] = (*this)[__index]; return __tmp; } template inline slice_array<_Tp> valarray<_Tp>::operator[](slice __slice) { return slice_array<_Tp>(__slice, *this); } //---------------------------------------------------------------------- // gslice and gslice_array struct _Gslice_Iter; class gslice { friend struct _Gslice_Iter; public: gslice() : _M_start(0), _M_lengths(0), _M_strides(0) {} gslice(size_t __start, const valarray& __lengths, const valarray& __strides) : _M_start(__start), _M_lengths(__lengths), _M_strides(__strides) {} size_t start() const { return _M_start; } valarray size() const { return _M_lengths; } valarray stride() const { return _M_strides; } // Extension: check for an empty gslice. bool _M_empty() const { return _M_lengths.size() == 0; } // Extension: number of indices this gslice represents. (For a degenerate // gslice, they're not necessarily all distinct.) size_t _M_size() const { return !this->_M_empty() ? accumulate(_M_lengths._M_first + 1, _M_lengths._M_first + _M_lengths._M_size, _M_lengths[0], multiplies()) : 0; } private: size_t _M_start; valarray _M_lengths; valarray _M_strides; }; // This is not an STL iterator. It is constructed from a gslice, and it // steps through the gslice indices in sequence. See 23.3.6 of the C++ // standard, paragraphs 2-3, for an explanation of the sequence. At // each step we get two things: the ordinal (i.e. number of steps taken), // and the one-dimensional index. struct _Gslice_Iter { _Gslice_Iter(const gslice& __gslice) : _M_step(0), _M_1d_idx(__gslice.start()), _M_indices(size_t(0), __gslice._M_lengths.size()), _M_gslice(__gslice) {} bool _M_done() const { return _M_indices[0] == _M_gslice._M_lengths[0]; } bool _M_incr() { size_t __dim = _M_indices.size() - 1; ++_M_step; while (true) { _M_1d_idx += _M_gslice._M_strides[__dim]; if (++_M_indices[__dim] != _M_gslice._M_lengths[__dim]) return true; else if (__dim != 0) { _M_1d_idx -= _M_gslice._M_strides[__dim] * _M_gslice._M_lengths[__dim]; _M_indices[__dim] = 0; --__dim; } else return false; } } size_t _M_step; size_t _M_1d_idx; valarray _M_indices; const gslice& _M_gslice; }; template class gslice_array { friend class valarray<_Tp>; public: typedef _Tp value_type; void operator= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] = __x[__i._M_step]; while(__i._M_incr()); } } void operator*= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] *= __x[__i._M_step]; while(__i._M_incr()); } } void operator/= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] /= __x[__i._M_step]; while(__i._M_incr()); } } void operator%= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] %= __x[__i._M_step]; while(__i._M_incr()); } } void operator+= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] += __x[__i._M_step]; while(__i._M_incr()); } } void operator-= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] -= __x[__i._M_step]; while(__i._M_incr()); } } void operator^= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] ^= __x[__i._M_step]; while(__i._M_incr()); } } void operator&= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] &= __x[__i._M_step]; while(__i._M_incr()); } } void operator|= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] |= __x[__i._M_step]; while(__i._M_incr()); } } void operator<<= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] <<= __x[__i._M_step]; while(__i._M_incr()); } } void operator>>= (const valarray& __x) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] >>= __x[__i._M_step]; while(__i._M_incr()); } } void operator= (const value_type& __c) const { if (!_M_gslice._M_empty()) { _Gslice_Iter __i(_M_gslice); do _M_array[__i._M_1d_idx] = __c; while(__i._M_incr()); } } ~gslice_array() {} private: gslice_array(gslice __gslice, valarray<_Tp>& __array) : _M_gslice(__gslice), _M_array(__array) {} gslice _M_gslice; valarray& _M_array; private: // Disable assignment void operator=(const gslice_array&); }; // valarray member functions dealing with gslice and gslice_array. Note // that it is illegal (behavior is undefined) to construct a gslice_array // from a degenerate gslice. template inline valarray<_Tp>::valarray(const gslice_array<_Tp>& __x) : _Valarray_base<_Tp>(__x._M_gslice._M_size()) { typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Is_Trivial; _M_initialize(_Is_Trivial()); *this = __x; } // Behavior is undefined if __x and *this have different sizes, or if // __x was constructed from a degenerate gslice. template valarray<_Tp>& valarray<_Tp>::operator=(const gslice_array<_Tp>& __x) { if (this->size() != 0) { _Gslice_Iter __i(__x._M_gslice); do (*this)[__i._M_step] = __x._M_array[__i._M_1d_idx]; while(__i._M_incr()); } return *this; } template inline gslice_array<_Tp> valarray<_Tp>::operator[](gslice __slice) { return gslice_array<_Tp>(__slice, *this); } template valarray<_Tp> valarray<_Tp>::operator[](gslice __slice) const { valarray __tmp(__slice._M_size(), _NoInit()); if (__tmp.size() != 0) { _Gslice_Iter __i(__slice); do __tmp[__i._M_step] = (*this)[__i._M_1d_idx]; while(__i._M_incr()); } return __tmp; } //---------------------------------------------------------------------- // mask_array template class mask_array { friend class valarray<_Tp>; public: typedef _Tp value_type; void operator=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] = __x[__idx++]; } void operator*=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] *= __x[__idx++]; } void operator/=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] /= __x[__idx++]; } void operator%=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] %= __x[__idx++]; } void operator+=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] += __x[__idx++]; } void operator-=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] -= __x[__idx++]; } void operator^=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] ^= __x[__idx++]; } void operator&=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] &= __x[__idx++]; } void operator|=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] |= __x[__idx++]; } void operator<<=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] <<= __x[__idx++]; } void operator>>=(const valarray& __x) const { size_t __idx = 0; for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] >>= __x[__idx++]; } void operator=(const value_type& __c) const { for (size_t __i = 0; __i < _M_array.size(); ++__i) if (_M_mask[__i]) _M_array[__i] = __c; } ~mask_array() {} // Extension: number of true values in the mask size_t _M_num_true() const { size_t __result = 0; for (size_t __i = 0; __i < _M_mask.size(); ++__i) if (_M_mask[__i]) ++__result; return __result; } private: mask_array(const valarray& __mask, valarray<_Tp>& __array) : _M_mask(__mask), _M_array(__array) {} valarray _M_mask; valarray<_Tp>& _M_array; private: // Disable assignment void operator=(const mask_array&); }; // valarray member functions dealing with mask_array template inline valarray<_Tp>::valarray(const mask_array<_Tp>& __x) : _Valarray_base<_Tp>(__x._M_num_true()) { typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Is_Trivial; _M_initialize(_Is_Trivial()); *this = __x; } // Behavior is undefined if __x._M_num_true() != this->size() template inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __x) { size_t __idx = 0; for (size_t __i = 0; __i < __x._M_array.size(); ++__i) if (__x._M_mask[__i]) (*this)[__idx++] = __x._M_array[__i]; return *this; } template inline mask_array<_Tp> valarray<_Tp>::operator[](const valarray& __mask) { return mask_array<_Tp>(__mask, *this); } template valarray<_Tp> valarray<_Tp>::operator[](const valarray& __mask) const { size_t __size = 0; { for (size_t __i = 0; __i < __mask.size(); ++__i) if (__mask[__i]) ++__size; } valarray __tmp(__size, _NoInit()); size_t __idx = 0; { for (size_t __i = 0; __i < __mask.size(); ++__i) if (__mask[__i]) __tmp[__idx++] = (*this)[__i]; } return __tmp; } //---------------------------------------------------------------------- // indirect_array template class indirect_array { friend class valarray<_Tp>; public: typedef _Tp value_type; void operator=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] = __x[__i]; } void operator*=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] *= __x[__i]; } void operator/=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] /= __x[__i]; } void operator%=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] %= __x[__i]; } void operator+=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] += __x[__i]; } void operator-=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] -= __x[__i]; } void operator^=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] ^= __x[__i]; } void operator&=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] &= __x[__i]; } void operator|=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] |= __x[__i]; } void operator<<=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] <<= __x[__i]; } void operator>>=(const valarray& __x) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] >>= __x[__i]; } void operator=(const value_type& __c) const { for (size_t __i = 0; __i < _M_addr.size(); ++__i) _M_array[_M_addr[__i]] = __c; } ~indirect_array() {} private: indirect_array(const valarray& __addr, valarray<_Tp>& __array) : _M_addr(__addr), _M_array(__array) {} valarray _M_addr; valarray<_Tp>& _M_array; private: // Disable assignment void operator=(const indirect_array&); }; // valarray member functions dealing with indirect_array template inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __x) : _Valarray_base<_Tp>(__x._M_addr.size()) { typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Is_Trivial; _M_initialize(_Is_Trivial()); *this = __x; } template valarray<_Tp>& valarray<_Tp>::operator=(const indirect_array<_Tp>& __x) { for (size_t __i = 0; __i < __x._M_addr.size(); ++__i) (*this)[__i] = __x._M_array[__x._M_addr[__i]]; return *this; } template inline indirect_array<_Tp> valarray<_Tp>::operator[](const valarray& __addr) { return indirect_array<_Tp>(__addr, *this); } template valarray<_Tp> valarray<_Tp>::operator[](const valarray& __addr) const { valarray<_Tp> __tmp(__addr.size(), _NoInit()); for (size_t __i = 0; __i < __addr.size(); ++__i) __tmp[__i] = (*this)[__addr[__i]]; return __tmp; } //---------------------------------------------------------------------- // Other valarray noninline member functions // Shift and cshift template valarray<_Tp> valarray<_Tp>::shift(int __n) const { valarray<_Tp> __tmp(this->size()); if (__n >= 0) { if (__n < this->size()) copy(this->_M_first + __n, this->_M_first + this->size(), __tmp._M_first); } else { if (-__n < this->size()) copy(this->_M_first, this->_M_first + this->size() + __n, __tmp._M_first - __n); } return __tmp; } template valarray<_Tp> valarray<_Tp>::cshift(int __m) const { valarray<_Tp> __tmp(this->size()); // Reduce __m to an equivalent number in the range [0, size()). We // have to be careful with negative numbers, since the sign of a % b // is unspecified when a < 0. long __n = __m; if (this->size() < numeric_limits::max()) __n %= long(this->size()); if (__n < 0) __n += this->size(); copy(this->_M_first, this->_M_first + __n, __tmp._M_first + (this->size() - __n)); copy(this->_M_first + __n, this->_M_first + this->size(), __tmp._M_first); return __tmp; } __STL_END_NAMESPACE #endif /* __SGI_STL_VALARRAY */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/vector ================================================ /* * * 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 __SGI_STL_VECTOR #define __SGI_STL_VECTOR #include #include #include #include #include #include #include #endif /* __SGI_STL_VECTOR */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-3.3-source/vector.h ================================================ /* * * 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 __SGI_STL_VECTOR_H #define __SGI_STL_VECTOR_H #include #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::vector; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_VECTOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-gatieme/1-stl_config/1config-inclass-init.cpp ================================================ //̬ʼ #include using namespace std; template class testClass { public: static const int _datai = 5; static const long _datal = 3L; static const char _datac = 'c'; }; int main() { cout<::_datai<::_datal<::_datac< using namespace std; class INT { friend ostream& operator<<(ostream& os, const INT& i); public: INT(int i) : m_i(i) { }; // prefix : increment and then fetch // ++INT INT& operator++() { ++(this->m_i); return *this; } // postfix : fetch and then increment // INT++ const INT operator++(int) { INT temp = *this; ++(*this); return temp; } // prefix : decrement and then fetch // --INT INT& operator--() { --(this->m_i); return *this; } // prefix : fetch and then decrement const INT operator--(int) { INT temp = *this; --(*this); return temp; } int& operator*() const { return (int&)m_i; } private: int m_i; }; ostream& operator<<(ostream& os, const INT& i) { os <<'[' < using namespace std; template struct hash { void operator()() { cout<<"hash"< struct hash { void operator()() { cout<<"hash"< struct hash { void operator()() { cout<<"hash"< t1; hash t2; hash t3; t1(); t2(); t3(); return 1; } ================================================ FILE: stl-gatieme/1-stl_config/1config-temporary-object.cpp ================================================ //ʱIJ #include #include #include using namespace std; template class print { public: void operator()(const T& elem) { cout< iv(ia, ia+6); for_each(iv.begin(), iv.end(), print()); cout< #include using namespace std; void test(void) { #ifdef _PTHREADS cout<<"define __STL_PTHREADS"<= 721) && defined(_NAMESPACES) cout<<"__STL_USE_NAMESPACES"< # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) cout<<"__STL_STATIC_TEMPLATE_MEMBER_BUG"<= 2 && defined(_G_USING_THUNKS) cout<<"__STL_PTHREADS"< 1000 cout<<"include "<"<"< cout<<"__stl_assert(expr) \ if (!(expr)) { fprintf(stderr, \"%s:%d STL assertion failure: %s\n\", \ __FILE__, __LINE__, # expr); abort(); }"< #include using namespace std; class alloc { }; template class deque { public: deque() { cout<<"deque"< > class stack { public: stack() { cout<<"stack"< x; } ================================================ FILE: stl-gatieme/1-stl_config/1config11.cpp ================================================ //class template ɷӵnon-type template #include #include using namespace std; class alloc { }; inline size_t __deque_buf_size(size_t n, size_t sz) { return n != 0 ? n : (sz < 512 ? size_t(512/sz) : size_t(1)); } template struct __deque_iterator { typedef __deque_iterator iterator; typedef __deque_iterator const_iterator; static size_t buffer_size() { return __deque_buf_size(BufSiz, sizeof(T)); } }; template class deque { public: typedef __deque_iterator iterator; }; int main() { cout<::iterator::buffer_size()<::iterator::buffer_size()< #include using namespace std; int main() { # if defined(__sgi) cout << "__sig" << endl; # endif # if defined(__GNUC__) cout << "_GNUC_" << endl; //cout << _GNUC_ << ' ' << _GNUC_MINOR_ << endl; # endif # ifdef __STL_NO_DRAND48 cout << "__STL_NO_DRAND48 defined" << endl; # else cout << "__STL_NO_DRAND48 undefined" << endl; # endif # ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG cout << "__STL_STATIC_TEMPLATE_MEMBER_BUG defined" << endl; # else cout << "__STL_STATIC_TEMPLATE_MEMBER_BUG undefined" << endl; # endif # ifdef __STL_WIN32THREADS cout << "__STL_WIN32THREADS defined" << endl; # else cout << "__STL_WIN32THREADSk undefined" << endl; # endif # ifdef __STL_ASSERTIONS cout << "__STL_ASSERTIONS defined" << endl; # else cout << "__STL_ASSERTIONS undefined" << endl; # endif # ifdef __STL_NEED_BOOL cout << "__STL_NEED_BOOL defined" << endl; # else cout << "__STL_NEED_BOOL undefined" << endl; # endif } ================================================ FILE: stl-gatieme/1-stl_config/1config3.cpp ================================================ //class templateӵstatic data members. #include using namespace std; template class testclass { public: static int _data; }; template<> int testclass::_data = 1; template<> int testclass::_data = 2; int main() { cout<::_data<::_data< obji1, obji2; testclass objc1, objc2; cout< using namespace std; template struct testClass { testClass() { cout<<"I, O"< struct testClass { testClass() { cout<<"T*,T*"< struct testClass { testClass() { cout<<"const T*, T*"< obj1; testClass obj2; testClass obj3; return 1; } ================================================ FILE: stl-gatieme/1-stl_config/1config8.cpp ================================================ //class template ֮ڿɷtemplate (members) #include using namespace std; class alloc { }; template class vector { public: typedef T value_type; typedef value_type* iterator; template void insert(iterator position, I first, I last) { cout<<"insert()"< x; vector::iterator ite = NULL; x.insert(ite, ia, ia+4); return 1; } ================================================ FILE: stl-gatieme/1-stl_config/1functor.cpp ================================================ //STL采用仿函数排序 #include using namespace std; // 由于将operator()重载了, 因此plus成了一个仿函数 template struct myplus { T operator()(const T& x, const T& y) const { return x + y; } }; // 由于将operator()重载了, 因此minus成了一个仿函数 template struct myminus { T operator()(const T& x, const T& y) const { return x - y; } }; int main() { // 创建仿函数对象 myplus plusobj; myminus minusobj; cout<()(43,50)<()(43,50)< #include using namespace std; int fcmp(const void *elem1, const void *elem2); int main( ) { int ia[] = {32, 92, 67, 58, 10, 4, 25, 52, 59, 54}; for(int i = 0; i < 10; i++) { cout < operator for iterators. // * __STL_DEFAULT_CONSTRUCTOR_BUG: defined if T() does not work properly // when T is a builtin type. // * __STL_USE_EXCEPTIONS: defined if the compiler (in the current compilation // mode) supports exceptions. // * __STL_USE_NAMESPACES: defined if the compiler has the necessary // support for namespaces. // * __STL_NO_EXCEPTION_HEADER: defined if the compiler does not have a // standard-conforming header . // * __STL_NO_BAD_ALLOC: defined if the compiler does not have a // header, or if does not contain a bad_alloc class. If a bad_alloc // class exists, it is assumed to be in namespace std. // * __STL_SGI_THREADS: defined if this is being compiled for an SGI IRIX // system in multithreaded mode, using native SGI threads instead of // pthreads. // * __STL_WIN32THREADS: defined if this is being compiled on a WIN32 // compiler in multithreaded mode. // * __STL_PTHREADS: defined if we should use portable pthreads // synchronization. // * __STL_UITHREADS: defined if we should use UI / solaris / UnixWare threads // synchronization. UIthreads are similar to pthreads, but are based // on an earlier version of the Posix threads standard. // * __STL_LONG_LONG if the compiler has long long and unsigned long long // types. (They're not in the C++ standard, but they are expected to be // included in the forthcoming C9X standard.) // * __STL_THREADS is defined if thread safety is needed. // * __STL_VOLATILE is defined to be "volatile" if threads are being // used, and the empty string otherwise. // * __STL_USE_CONCEPT_CHECKS enables some extra compile-time error // checking to make sure that user-defined template arguments satisfy // all of the appropriate requirements. This may result in more // comprehensible error messages. It incurs no runtime overhead. This // feature requires member templates and partial specialization. // * __STL_NO_USING_CLAUSE_IN_CLASS: The compiler does not handle "using" // clauses inside of class definitions. // * __STL_NO_FRIEND_TEMPLATE_CLASS: The compiler does not handle friend // declaractions where the friend is a template class. // * __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE: The compiler does not // support the use of a function pointer type as the argument // for a template. // * __STL_MEMBER_TEMPLATE_KEYWORD: standard C++ requires the template // keyword in a few new places (14.2.4). This flag is set for // compilers that support (and require) this usage. // User-settable macros that control compilation: // * __STL_USE_SGI_ALLOCATORS: if defined, then the STL will use older // SGI-style allocators, instead of standard-conforming allocators, // even if the compiler supports all of the language features needed // for standard-conforming allocators. // * __STL_NO_NAMESPACES: if defined, don't put the library in namespace // std, even if the compiler supports namespaces. // * __STL_NO_RELOPS_NAMESPACE: if defined, don't put the relational // operator templates (>, <=. >=, !=) in namespace std::rel_ops, even // if the compiler supports namespaces and partial ordering of // function templates. // * __STL_ASSERTIONS: if defined, then enable runtime checking through the // __stl_assert macro. // * _PTHREADS: if defined, use Posix threads for multithreading support. // * _UITHREADS:if defined, use SCO/Solaris/UI threads for multithreading // support // * _NOTHREADS: if defined, don't use any multithreading support. // * _STL_NO_CONCEPT_CHECKS: if defined, disables the error checking that // we get from __STL_USE_CONCEPT_CHECKS. // * __STL_USE_NEW_IOSTREAMS: if defined, then the STL will use new, // standard-conforming iostreams (e.g. the header). If not // defined, the STL will use old cfront-style iostreams (e.g. the // header). // Other macros defined by this file: // * bool, true, and false, if __STL_NO_BOOL is defined. // * typename, as a null macro if it's not already a keyword. // * explicit, as a null macro if it's not already a keyword. // * namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) // * exception-related macros (__STL_TRY, __STL_UNWIND, etc.) // * __stl_assert, either as a test or as a null macro, depending on // whether or not __STL_ASSERTIONS is defined. // ļܱ: // (1) ûжbool, true, false // (2) ֧drand48()__STL_NO_DRAND48 // ע: drand48˫ȵα, Ϊ48bit, drand48 // (3) ֧static members of template classes(ģྲ̬Ա), // __STL_STATIC_TEMPLATE_MEMBER_BUG // (4) ֧'typename'ؼ, 'typename'Ϊ(null macro) // (5) ֧partial specialization of class templates(ģƫػ), // __STL_CLASS_PARTIAL_SPECIALIZATION // ο: http://msdn.microsoft.com/en-us/library/9w7t3kf1(v=VS.71).aspx // (6) ֧partial ordering of function templates(ģ庯ػȼ), // __STL_FUNCTION_TMPL_PARTIAL_ORDER // ο: http://msdn.microsoft.com/zh-cn/library/zaycz069.aspx // (7) ֧calling a function template by providing its template // arguments explicitly(ʽָģ庯ģ) // __STL_EXPLICIT_FUNCTION_TMPL_ARGS // (8) ֧template members of classes(ģԱ), // __STL_MEMBER_TEMPLATES // (9) ֧'explicit'ؼ, 'explicit'Ϊ(null macro) // (10) ܸǰһģ趨Ĭģ, // __STL_LIMITED_DEFAULT_TEMPLATES // (11) ģ庯non-typeģƶ, // __STL_NON_TYPE_TMPL_PARAM_BUG // (12) ֵ֧ʹ'->', // __SGI_STL_NO_ARROW_OPERATOR // (13) (ڵǰģʽ)֧쳣, // __STL_USE_EXCEPTIONS // (14) ǽSTLŽռ, // __STL_USE_NAMESPACES // (15) STLSGIıϱ, ûûѡpthreadsno threads, // Ĭʹ__STL_SGI_THREADS // ע: POSIX thread Ϊpthread, Posix߳һPOSIX׼߳. // (16) STLWin32ƽ̨ıʹö߳ģʽ, // __STL_WIN32THREADS // (17) ʵĶռصĺ(__STD, __STL_BEGIN_NAMESPACE, ) // (18) ʵĶ쳣صĺ(__STL_TRY, __STL_UNWIND, ) // (19) Ƿ__STL_ASSERTIONS, __stl_assertΪԻ߿(null macro) # if defined(_PTHREADS) && !defined(_NOTHREADS) # define __STL_PTHREADS # endif # if defined(_UITHREADS) && !defined(_PTHREADS) && !defined(_NOTHREADS) # define __STL_UITHREADS # endif // ṩSTLҪһЩ,__STL_NEED_XXX // ʹ SGI STL, DzʹGNU C++ # if defined(__sgi) && !defined(__GNUC__) # include # if !defined(_BOOL) # define __STL_NO_BOOL # endif # if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32 # define __STL_STATIC_CONST_INIT_BUG # endif # if defined(_WCHAR_T_IS_KEYWORD) # define __STL_HAS_WCHAR_T # endif # if !defined(_TYPENAME_IS_KEYWORD) # define __STL_NEED_TYPENAME # endif # ifdef _PARTIAL_SPECIALIZATION_OF_CLASS_TEMPLATES # define __STL_CLASS_PARTIAL_SPECIALIZATION # endif # if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # endif # ifdef _MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATES # define __STL_TEMPLATE_FRIENDS # define __STL_MEMBER_TEMPLATE_CLASSES # endif # if defined(_MEMBER_TEMPLATE_KEYWORD) # define __STL_MEMBER_TEMPLATE_KEYWORD # endif # if defined(_STANDARD_C_PLUS_PLUS) # define __STL_EXPLICIT_FUNCTION_TMPL_ARGS # endif # if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 # define __STL_MEMBER_TEMPLATE_KEYWORD # endif # if COMPILER_VERSION < 720 || (defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32) # define __STL_DEFAULT_CONSTRUCTOR_BUG # endif # if !defined(_EXPLICIT_IS_KEYWORD) # define __STL_NEED_EXPLICIT # endif # ifdef __EXCEPTIONS # define __STL_USE_EXCEPTIONS # endif # if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES) # define __STL_HAS_NAMESPACES # endif # if (_COMPILER_VERSION < 721) || \ !defined(__STL_HAS_NAMESPACES) || defined(__STL_NO_NAMESPACES) # define __STL_NO_EXCEPTION_HEADER # endif # if _COMPILER_VERSION < 730 || !defined(_STANDARD_C_PLUS_PLUS) || \ !defined(_NAMESPACES) # define __STL_NO_BAD_ALLOC # endif # if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) # define __STL_SGI_THREADS # endif # if defined(_LONGLONG) && defined(_SGIAPI) && _SGIAPI # define __STL_LONG_LONG # endif # if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) # define __STL_USE_NEW_IOSTREAMS # endif # if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) # define __STL_CAN_THROW_RANGE_ERRORS # endif # if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS) # define __SGI_STL_USE_AUTO_PTR_CONVERSIONS # endif # endif /* * Jochen Schlick '1999 - added new #defines (__STL)_UITHREADS (for * providing SCO / Solaris / UI thread support) * - added the necessary defines for the SCO UDK 7 * compiler (and its template friend behavior) * - all UDK7 specific STL changes are based on the * macro __USLC__ being defined */ // SCO UDK 7 compiler (UnixWare 7x, OSR 5, UnixWare 2x) # if defined(__USLC__) # define __STL_HAS_WCHAR_T # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_PARTIAL_SPECIALIZATION_SYNTAX # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_USE_EXCEPTIONS # define __STL_HAS_NAMESPACES # define __STL_USE_NAMESPACES # define __STL_LONG_LONG # if defined(_REENTRANT) # define _UITHREADS /* if UnixWare < 7.0.1 */ # define __STL_UITHREADS // use the following defines instead of the UI threads defines when // you want to use POSIX threads //# define _PTHREADS /* only if UnixWare >=7.0.1 */ //# define __STL_PTHREADS # endif # endif # ifdef __GNUC__ # if __GNUC__ == 2 && __GNUC_MINOR__ <= 7 # define __STL_STATIC_TEMPLATE_MEMBER_BUG # endif # if __GNUC__ < 2 # define __STL_NEED_TYPENAME # define __STL_NEED_EXPLICIT # endif # if __GNUC__ == 2 && __GNUC_MINOR__ <= 8 # define __STL_NO_EXCEPTION_HEADER # define __STL_NO_BAD_ALLOC # endif # if __GNUC__ == 2 && __GNUC_MINOR__ >= 8 // GNUC 2.8+ ij # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_MEMBER_TEMPLATES # define __STL_CAN_THROW_RANGE_ERRORS // g++ 2.8.1 supports member template functions, but not member // template nested classes. # if __GNUC_MINOR__ >= 9 # define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_TEMPLATE_FRIENDS # define __SGI_STL_USE_AUTO_PTR_CONVERSIONS # define __STL_HAS_NAMESPACES //# define __STL_USE_NEW_IOSTREAMS # endif # endif # define __STL_DEFAULT_CONSTRUCTOR_BUG # ifdef __EXCEPTIONS # define __STL_USE_EXCEPTIONS # endif # ifdef _REENTRANT # define __STL_PTHREADS # endif /* glibc pre 2.0 is very buggy. We have to disable thread for it. It should be upgraded to glibc 2.0 or later. */ # if (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 95) # define __STL_NO_FUNCTION_PTR_IN_CLASS_TEMPLATE # endif # endif // Sun C++ compiler # if defined(__SUNPRO_CC) # define __STL_NO_BOOL # define __STL_NEED_TYPENAME # define __STL_NEED_EXPLICIT # define __STL_USE_EXCEPTIONS # ifdef _REENTRANT # define __STL_PTHREADS # endif # define __SGI_STL_NO_ARROW_OPERATOR # define __STL_PARTIAL_SPECIALIZATION_SYNTAX # define __STL_NO_EXCEPTION_HEADER # define __STL_NO_BAD_ALLOC # endif # if defined(__COMO__) # define __STL_MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_TEMPLATE_FRIENDS # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_USE_EXCEPTIONS # define __STL_HAS_NAMESPACES # endif // Intel compiler, which uses the EDG front end. # if defined(__ICL) # define __STL_LONG_LONG # define __STL_MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_TEMPLATE_FRIENDS # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_NO_DRAND48 # define __STL_HAS_NAMESPACES # define __STL_USE_EXCEPTIONS # define __STL_MEMBER_TEMPLATE_KEYWORD # ifdef _CPPUNWIND # define __STL_USE_EXCEPTIONS # endif # ifdef _MT # define __STL_WIN32THREADS # endif # endif // Mingw32, egcs compiler using the Microsoft C runtime # if defined(__MINGW32__) # define __STL_NO_DRAND48 # ifdef _MT # define __STL_WIN32THREADS # endif # endif // Cygwin32, egcs compiler on MS Windows # if defined(__CYGWIN__) # define __STL_NO_DRAND48 # endif // Microsoft compiler. // _MSC_VER ΢İ汾 # if defined(_MSC_VER) && !defined(__ICL) && !defined(__MWERKS__) # define __STL_NO_DRAND48 # define __STL_STATIC_CONST_INIT_BUG # define __STL_NEED_TYPENAME # define __STL_NO_USING_CLAUSE_IN_CLASS # define __STL_NO_FRIEND_TEMPLATE_CLASS # if _MSC_VER < 1100 /* 1000 is version 4.0, 1100 is 5.0, 1200 is 6.0. */ # define __STL_NEED_EXPLICIT # define __STL_NO_BOOL # define __STL_NO_BAD_ALLOC # endif # if _MSC_VER > 1000 # include # define __STL_DONT_USE_BOOL_TYPEDEF # endif # define __STL_NON_TYPE_TMPL_PARAM_BUG # define __SGI_STL_NO_ARROW_OPERATOR # define __STL_DEFAULT_CONSTRUCTOR_BUG # ifdef _CPPUNWIND # define __STL_USE_EXCEPTIONS # endif # ifdef _MT # define __STL_WIN32THREADS # endif # if _MSC_VER >= 1200 # define __STL_PARTIAL_SPECIALIZATION_SYNTAX # define __STL_HAS_NAMESPACES # define __STL_CAN_THROW_RANGE_ERRORS # define NOMINMAX # undef min # undef max // disable warning 'initializers put in unrecognized initialization area' # pragma warning ( disable : 4075 ) // disable warning 'empty controlled statement found' # pragma warning ( disable : 4390 ) // disable warning 'debug symbol greater than 255 chars' # pragma warning ( disable : 4786 ) # endif # if _MSC_VER < 1100 # define __STL_NO_EXCEPTION_HEADER # define __STL_NO_BAD_ALLOC # endif // Because of a Microsoft front end bug, we must not provide a // namespace qualifier when declaring a friend function. # define __STD_QUALIFIER # endif # if defined(__BORLANDC__) # define __STL_NO_BAD_ALLOC # define __STL_NO_DRAND48 # define __STL_DEFAULT_CONSTRUCTOR_BUG # if __BORLANDC__ >= 0x540 /* C++ Builder 4.0 */ # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_MEMBER_TEMPLATES # define __STL_TEMPLATE_FRIENDS # else # define __STL_NEED_TYPENAME # define __STL_LIMITED_DEFAULT_TEMPLATES # define __SGI_STL_NO_ARROW_OPERATOR # define __STL_NON_TYPE_TMPL_PARAM_BUG # endif # ifdef _CPPUNWIND # define __STL_USE_EXCEPTIONS # endif # ifdef __MT__ # define __STL_WIN32THREADS # endif # endif # if defined(__STL_NO_BOOL) && !defined(__STL_DONT_USE_BOOL_TYPEDEF) typedef int bool; # define true 1 # define false 0 # endif # ifdef __STL_NEED_TYPENAME # define typename # endif # ifdef __STL_LIMITED_DEFAULT_TEMPLATES # define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) # else # define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) = _Tp # endif # ifdef __STL_MEMBER_TEMPLATE_KEYWORD # define __STL_TEMPLATE template # else # define __STL_TEMPLATE # endif # ifdef __STL_NEED_EXPLICIT # define explicit # endif # ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_NULL_TMPL_ARGS <> # else # define __STL_NULL_TMPL_ARGS # endif # if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ || defined (__STL_PARTIAL_SPECIALIZATION_SYNTAX) # define __STL_TEMPLATE_NULL template<> # else # define __STL_TEMPLATE_NULL # endif // Use standard-conforming allocators if we have the necessary language // features. __STL_USE_SGI_ALLOCATORS is a hook so that users can // disable new-style allocators, and continue to use the same kind of // allocators as before, without having to edit library headers. # if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && \ defined(__STL_MEMBER_TEMPLATES) && \ defined(__STL_MEMBER_TEMPLATE_CLASSES) && \ !defined(__STL_NO_BOOL) && \ !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) && \ !defined(__STL_LIMITED_DEFAULT_TEMPLATES) && \ !defined(__STL_USE_SGI_ALLOCATORS) # define __STL_USE_STD_ALLOCATORS # endif # ifndef __STL_DEFAULT_ALLOCATOR # ifdef __STL_USE_STD_ALLOCATORS # define __STL_DEFAULT_ALLOCATOR(T) allocator< T > # else # define __STL_DEFAULT_ALLOCATOR(T) alloc # endif # endif // __STL_NO_NAMESPACES is a hook so that users can disable namespaces // without having to edit library headers. __STL_NO_RELOPS_NAMESPACE is // a hook so that users can disable the std::rel_ops namespace, keeping // the relational operator template in namespace std, without having to // edit library headers. # if defined(__STL_HAS_NAMESPACES) && !defined(__STL_NO_NAMESPACES) # define __STL_USE_NAMESPACES # define __STD std # define __STL_BEGIN_NAMESPACE namespace std { # define __STL_END_NAMESPACE } # if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \ !defined(__STL_NO_RELOPS_NAMESPACE) # define __STL_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE namespace std { namespace rel_ops { # define __STL_END_RELOPS_NAMESPACE } } # define __STD_RELOPS std::rel_ops # else /* Use std::rel_ops namespace */ # define __STL_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE namespace std { # define __STL_END_RELOPS_NAMESPACE } # define __STD_RELOPS std # endif /* Use std::rel_ops namespace */ # else # define __STD # define __STL_BEGIN_NAMESPACE # define __STL_END_NAMESPACE # undef __STL_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE # define __STL_END_RELOPS_NAMESPACE # define __STD_RELOPS # undef __STL_USE_NAMESPACES # endif // Some versions of the EDG front end sometimes require an explicit // namespace spec where they shouldn't. This macro facilitates that. // If the bug becomes irrelevant, then all uses of __STD_QUALIFIER // should be removed. The 7.3 beta SGI compiler has this bug, but the // MR version is not expected to have it. # if defined(__STL_USE_NAMESPACES) && !defined(__STD_QUALIFIER) # define __STD_QUALIFIER std:: # else # define __STD_QUALIFIER # endif # ifdef __STL_USE_EXCEPTIONS # define __STL_TRY try # define __STL_CATCH_ALL catch(...) # define __STL_THROW(x) throw x # define __STL_RETHROW throw # define __STL_NOTHROW throw() # define __STL_UNWIND(action) catch(...) { action; throw; } # else # define __STL_TRY # define __STL_CATCH_ALL if (false) # define __STL_THROW(x) # define __STL_RETHROW # define __STL_NOTHROW # define __STL_UNWIND(action) # endif #ifdef __STL_ASSERTIONS # include # define __stl_assert(expr) \ if (!(expr)) { fprintf(stderr, "%s:%d STL assertion failure: %s\n", \ __FILE__, __LINE__, # expr); abort(); } #else # define __stl_assert(expr) #endif #if defined(__STL_WIN32THREADS) || defined(__STL_SGI_THREADS) \ || defined(__STL_PTHREADS) || defined(__STL_UITHREADS) # define __STL_THREADS # define __STL_VOLATILE volatile #else # define __STL_VOLATILE #endif #if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ && defined(__STL_MEMBER_TEMPLATES) \ && !defined(_STL_NO_CONCEPT_CHECKS) # define __STL_USE_CONCEPT_CHECKS #endif #endif /* __STL_CONFIG_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-gatieme/2-defalloc/2jjalloc.h ================================================ //file: 2jjalloc.h #ifndef _JJALLOC_ #define _JJALLOC_ #include // for placement new #include // for ptrdiff_t,size_t #include // for exit() #include // for UINT_MAX #include // for cerr namespace JJ { template inline T* _allocate(ptrdiff_t size,T*) { set_new_handle(0); //newʧʱиúIJ T* tmp = (T*)(::operator new((size_t)(size*sizeof(T)))); if (tmp == 0) { exit(1); } return tmp; } template inline void _deallocate(T* buffer) { ::operator delete(buffer); } template inline void _construct(T1* p, const T2& value) { new(p) T1(value); } template inline void _destroy(T* ptr) { ptr->!T(); } template class allocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind {typedef allocator other;} pointer allocate(size_type n, const void* hint=0) { return _allocate((difference_type)n,(pointer)0); } void deallocate(pointer p,size_type n) {_deallocate(p);} void construct(pointer p,const t& value) { _construct(p,value); } void destroy(pointer p) {_destroy(p);} pointer address(reference x) {return (pointer)&x;} const_pointer const_address(const_reference x) {return (const_pointer)&x;} size_type max_size() const {return size_type(UINT_MAX/sizeof(T));} } } ================================================ FILE: stl-gatieme/2-defalloc/Makefile ================================================ ROOT=../../.. PLATFORM=$(shell $(ROOT)/systype.sh) include $(ROOT)/Make.defines.$(PLATFORM) target=constructor copyconstructor-onrvo copyconstructor-rvo all:$(target) constructor : constructor $(CXX) $^ -o $@ #echo "单参数构造函数..." copyconstructor-nonrvo: copyconstructor.o $(CXX) $^ -o $@ echo "拷贝构造函数的调用时机-非优化版..." copyconstructor-rvo: copyconstructor.o $(CXX) $^ -o $@ echo "拷贝构造函数的调用时机-RVO优化版..." copyconstructexplicit : copyconstructexplicit.o $(CXX) -c $^ -o $@ echo "explicit限制下的拷贝构造函数..." clean : rm $(target) ================================================ FILE: stl-gatieme/2-defalloc/README.md ================================================ [ ռSTLԴ](http://blog.csdn.net/chinajane163/article/details/50148073) ================================================ FILE: stl-gatieme/2-defalloc/defalloc.h ================================================ /* * * 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 . #ifndef DEFALLOC_H #define DEFALLOC_H // ļṩԭʼHPĬallocator, Ϊ // // Ҫʹļ,ʹһҪHP-style allocatorľ // SGI STLʹһͬallocatorӿ // SGI-styleallocatorԶͽв, ʹvoid *ָ #include #include #include #include #include #include // ڴʧ, ֱ˳ template inline T* allocate(ptrdiff_t size, T*) { set_new_handler(0); T* tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); if (tmp == 0) { cerr << "out of memory" << endl; exit(1); } return tmp; } template inline void deallocate(T* buffer) { ::operator delete(buffer); } template class allocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& 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(T))); } size_type max_size() const { return max(size_type(1), size_type(UINT_MAX/sizeof(T))); } }; class allocator { public: typedef void* pointer; }; #endif ================================================ FILE: stl-gatieme/2-defalloc/simple_jjallocator.h ================================================ #ifndef SIMPLE_JJALLOC_H #define SIMPLE_JJALLOC_H #include //for placement new #include //for ptrdiff_t,size_t #include //for exit() #include //for UINT_MAX十进制的最大值 #include //for cerr namespace JJ { /*****************ptrdiff_t与size_t类型*****size_type与difference_type类型******************** ****ptrdiff_t:signed类型,通常用于两指针减法操作的结果,它可以是负数。(因为指针相减有正有负) ****size_t:unsigned类型,用于指明数组长度,它是非负整数。 ****size_type:unsigned类型,容器中元素长度或下表,vector::size_type i=0; ****difference_type:signed类型,表示迭代器差距,vector::difference_type=iter1-iter2 ****前两者位于标准类库std内,后两者为stl对象所有 *********************************************************************************************/ template inline T* _allocate(ptrdiff_t size, T*) { std::cout<<"I'm _allocate in simple_jjalloc!"< inline void _deallocate(T* buffer) { ::operator delete(buffer); } /************************************new的三种形态******************************************* ****new operator:就是平常用的new,通常做三件事,1.用operator new分配内存给对象,2.调用构造函数初始化那块内存,3.将地址转给对象指针 如果仅仅是在堆上建立对象,那么应该使用new operator,它会提供周全的服务 ****operator new:在默认情况下首先会调用分配内存的代码,尝试从堆上得到一段空间,成功就返回,失败就调用new_hander,重复前面过程,直到抛出异常 如果仅仅是分配内存,那么应该调用operator new,但初始化不在它的职责之内。若对默认的内存分配过程不满意,那就重载它 ****placement new:用来实现定位构造,可以通过它来选择合适的构造函数。 如果想在一块已获得的内存里建立一个对象,那就改用placement new ********************************************************************************************/ template inline void _construct(T1* p,const T2& val) { new(p) T1(val);//p为那块内存地址,T1()为指定构造函数;此句为p->T1::T1(val); std::cout<<"I'm _construct!"< inline void _destroy(T* ptr) { std::cout<<"I'm _destroy!"<~T(); } template class mallocator { public: typedef T value_type;//为什么要重新定义,原因在章三 typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind//干吗用?见下 { typedef mallocator mother; }; pointer allocate(size_type n,const void* hint=0) { return _allocate((difference_type)n,(pointer)0); } void deallocate(pointer p,size_type n) { _deallocate(p); } void construct(pointer p,const_reference val) { _construct(p,val); } void destroy(pointer p) { _destroy(p); } pointer address(reference x) { return (pointer)&x; } const pointer const_address(const_reference x) { return (const pointer)&x; } size_type max_size()const { return size_type(UINT_MAX/sizeof(value_type)); } }; } #endif ================================================ FILE: stl-gatieme/2-defalloc/stl_alloc.h ================================================ // Filename: stl_alloc.h // ر˵: SGI STLallocatorҵı뻷²ʹڴ // ڴزڴͷŲ, ͷʱΪ˳stack unwinding // ɲϵͳ֤ڴĻ /* * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ALLOC_H #define __SGI_STL_INTERNAL_ALLOC_H #ifdef __SUNPRO_CC # define __PRIVATE public // SUNprivateƹ, ҪȨ #else # define __PRIVATE private #endif // Ϊ˱֤, ڲ֧ģྲ̬Ա, ʹmalloc()ڴ #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG # define __USE_MALLOC #endif // ʵһЩ׼node allocator // DzͬC++׼STLԭʼSTL׼ // Щallocatorûзװָͬ // ʵǼٶֻһָ // allocation primitivesڷ䲻ԭʼSTL allocatorĶĶ #if 0 # include # define __THROW_BAD_ALLOC throw bad_alloc #elif !defined(__THROW_BAD_ALLOC) # include # define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1) #endif #ifndef __ALLOC # define __ALLOC alloc #endif #ifdef __STL_WIN32THREADS # include #endif #include #include #include #include #ifndef __RESTRICT # define __RESTRICT #endif // ֧߳ // __STL_PTHREADS // GCC // _NOTHREADS // ֶ֧߳ // __STL_SGI_THREADS // SGIר // __STL_WIN32THREADS // MSVC #if !defined(__STL_PTHREADS) && !defined(_NOTHREADS) \ && !defined(__STL_SGI_THREADS) && !defined(__STL_WIN32THREADS) # define _NOTHREADS #endif # ifdef __STL_PTHREADS // POSIX Threads // This is dubious, since this is likely to be a high contention // lock. Performance may not be adequate. # include # define __NODE_ALLOCATOR_LOCK \ if (threads) pthread_mutex_lock(&__node_allocator_lock) # define __NODE_ALLOCATOR_UNLOCK \ if (threads) pthread_mutex_unlock(&__node_allocator_lock) # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // Needed at -O3 on SGI # endif # ifdef __STL_WIN32THREADS // The lock needs to be initialized by constructing an allocator // objects of the right type. We do that here explicitly for alloc. # define __NODE_ALLOCATOR_LOCK \ EnterCriticalSection(&__node_allocator_lock) # define __NODE_ALLOCATOR_UNLOCK \ LeaveCriticalSection(&__node_allocator_lock) # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // may not be needed # endif /* WIN32THREADS */ # ifdef __STL_SGI_THREADS // This should work without threads, with sproc threads, or with // pthreads. It is suboptimal in all cases. // It is unlikely to even compile on nonSGI machines. extern "C" { extern int __us_rsthread_malloc; } // The above is copied from malloc.h. Including // would be cleaner but fails with certain levels of standard // conformance. # define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \ { __lock(&__node_allocator_lock); } # define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \ { __unlock(&__node_allocator_lock); } # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // Needed at -O3 on SGI # endif # ifdef _NOTHREADS // Thread-unsafe # define __NODE_ALLOCATOR_LOCK # define __NODE_ALLOCATOR_UNLOCK # define __NODE_ALLOCATOR_THREADS false # define __VOLATILE # endif __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif // Malloc-based allocator. Typically slower than default alloc below. // Typically thread-safe and more storage efficient. #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG # ifdef __DECLARE_GLOBALS_HERE void (* __malloc_alloc_oom_handler)() = 0; // g++ 2.7.2 does not handle static template data members. # else extern void (* __malloc_alloc_oom_handler)(); # endif #endif // һ template class __malloc_alloc_template { private: // __malloc_alloc_oom_handlerѭڴ, // ֱɹ static void *oom_malloc(size_t); static void *oom_realloc(void *, size_t); // ֧ģྲ̬Ա, ʹô, C++set_new_handler() // ĬֵΪ0, , ڴʧʱֱ__THROW_BAD_ALLOC #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG static void (* __malloc_alloc_oom_handler)(); #endif public: // ָСڴ(size_t n) ʧ, ѭ׶ // ѭǰҪ֤ȷ__malloc_alloc_oom_handler static void * allocate(size_t n) { void *result = malloc(n); if (0 == result) result = oom_malloc(n); return result; } // size_tΪ˼operator delele static void deallocate(void *p, size_t /* n */) { free(p); } // ·ڴС, ڶΪ˼operator new static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz) { void * result = realloc(p, new_sz); if (0 == result) result = oom_realloc(p, new_sz); return result; } // ô, ԭĺָ // C++׼涨Ľӿ static void (* set_malloc_handler(void (*f)()))() { void (* old)() = __malloc_alloc_oom_handler; __malloc_alloc_oom_handler = f; return(old); } }; // malloc_alloc out-of-memory handling #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG template void (* __malloc_alloc_template::__malloc_alloc_oom_handler)() = 0; #endif // __malloc_alloc_oom_handler, ִд, Ȼѭֱɹ // δ__malloc_alloc_oom_handler, __THROW_BAD_ALLOC template void * __malloc_alloc_template::oom_malloc(size_t n) { void (* my_malloc_handler)(); void *result; for (;;) { my_malloc_handler = __malloc_alloc_oom_handler; if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } (*my_malloc_handler)(); result = malloc(n); if (result) return(result); } } template void * __malloc_alloc_template::oom_realloc(void *p, size_t n) { void (* my_malloc_handler)(); void *result; for (;;) { my_malloc_handler = __malloc_alloc_oom_handler; if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } (*my_malloc_handler)(); result = realloc(p, n); if (result) return(result); } } // 汾STLûʹnon-typeģ typedef __malloc_alloc_template<0> malloc_alloc; // еĽӿʵSTL׼еallocatorĽӿ // ʵеSGI STLʹڴ // : stl_vector.h // template // class vector // { // ... // protected: // typedef simple_alloc data_allocator; // ... //}; template class simple_alloc { public: static T *allocate(size_t n) { return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); } static T *allocate(void) { return (T*) Alloc::allocate(sizeof (T)); } static void deallocate(T *p, size_t n) { if (0 != n) Alloc::deallocate(p, n * sizeof (T)); } static void deallocate(T *p) { Alloc::deallocate(p, sizeof (T)); } }; // Allocator adaptor to check size arguments for debugging. // Reports errors using assert. Checking can be disabled with // NDEBUG, but it's far better to just use the underlying allocator // instead when no checking is desired. // There is some evidence that this can confuse Purify. template class debug_alloc { private: enum {extra = 8}; // Size of space used to store size. Note // that this must be large enough to preserve // alignment. public: // extra ֤Ϊ0ڴռ, Ҫ֤ڴ // ѷڴǰónĴС, ںУ // ڴþDZǰextraСݲ޸ static void * allocate(size_t n) { char *result = (char *)Alloc::allocate(n + extra); *(size_t *)result = n; return result + extra; } // *(size_t *)real_p != n϶ǰԽ static void deallocate(void *p, size_t n) { char * real_p = (char *)p - extra; assert(*(size_t *)real_p == n); Alloc::deallocate(real_p, n + extra); } static void * reallocate(void *p, size_t old_sz, size_t new_sz) { char * real_p = (char *)p - extra; assert(*(size_t *)real_p == old_sz); char * result = (char *) Alloc::reallocate(real_p, old_sz + extra, new_sz + extra); *(size_t *)result = new_sz; return result + extra; } }; # ifdef __USE_MALLOC typedef malloc_alloc alloc; typedef malloc_alloc single_client_alloc; # else // Ĭϵnode allocator // кʵı, ٶԭʼSTL class-specific allocatorsµȼ // ǾвڴƬŵ // Default_alloc_templateʵʵ, δܻʧ // ͻֻڵʹalloc // // Ҫʵ: // 1. ͻһsize > __MAX_BYTEĶ, ֱʹmalloc() // 2. , ǽĴСڴROUND_UP(requested_size) // TODO: // 2. In all other cases, we allocate an object of size exactly // 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. // // һģָǷжһ߳ʹñallocator // һdefault_allocʵз, һdeallocateʵͷŶ, ǰȫ // ЧתȨһ // ܵ¶õӰ // ڶģڴdefault_allocʵ // ͬʹòͬallocatorʵnodeӵвͬ, ˴˷ͨ // Sun C++ compilerҪⶨЩö #ifdef __SUNPRO_CC // breaks if we make these template class members: enum {__ALIGN = 8}; enum {__MAX_BYTES = 128}; enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; #endif template class __default_alloc_template { private: // Really we should use static const int x = N // instead of enum { x = N }, but few compilers accept the former. # ifndef __SUNPRO_CC enum {__ALIGN = 8}; enum {__MAX_BYTES = 128}; enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; # endif // // һ, __ALIGN - 1ָʵڴ // __ALIGN = 8ʱ, ֻҪ7Ϳʵʱʾ8(0~7) // ô~(__ALIGN - 1)ǽ // ǽ(bytes) + __ALIGN-1)Ƚнλ, Ȼض // ͱ֤ // byte = 100, __ALIGN = 8 // ~(__ALIGN - 1) = (1 000)B // ((bytes) + __ALIGN-1) = (1 101 011)B // (((bytes) + __ALIGN-1) & ~(__ALIGN - 1)) = (1 101 000 )B = (104)D // 104 / 8 = 13, ʵ // byteպڴ, byteС // ǵáHacker's Delightصļ // ʽĵȼ // ((((bytes) + _ALIGN - 1) * _ALIGN) / _ALIGN) // SGI STLʹõķЧʷdz static size_t ROUND_UP(size_t bytes) { return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1)); } __PRIVATE: // ڴ // Ϊ˾ܼڴʹ, ʹһunion // ʹõһԱ, ָһͬunion obj // ʹõڶԱ, ָʵʵڴ // ʵֻʹһָĴСռ, ȴͬʱָڴ // Էdzǿ, ֵѧϰ union obj { union obj * free_list_link; char client_data[1]; /* The client sees this. */ }; private: # ifdef __SUNPRO_CC static obj * __VOLATILE free_list[]; // Specifying a size results in duplicate def for 4.1 # else // free_listΪ16 // ӦڴֱΪ8, 16, 32 ... 128 static obj * __VOLATILE free_list[__NFREELISTS]; # endif // ݴĿռС, free_listѡʵĴС static size_t FREELIST_INDEX(size_t bytes) { return (((bytes) + __ALIGN-1)/__ALIGN - 1); } // Returns an object of size n, and optionally adds to size n free list. static void *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. static char *chunk_alloc(size_t size, int &nobjs); // ڴ static char *start_free; // ڴʼ static char *end_free; // ڴؽ static size_t heap_size; // ѾڶϷĿռС // ߳ʹõṩҪ֧ # ifdef __STL_SGI_THREADS static volatile unsigned long __node_allocator_lock; static void __lock(volatile unsigned long *); static inline void __unlock(volatile unsigned long *); # endif # ifdef __STL_PTHREADS static pthread_mutex_t __node_allocator_lock; # endif # ifdef __STL_WIN32THREADS static CRITICAL_SECTION __node_allocator_lock; static bool __node_allocator_lock_initialized; public: __default_alloc_template() { // This assumes the first constructor is called before threads // are started. if (!__node_allocator_lock_initialized) { InitializeCriticalSection(&__node_allocator_lock); __node_allocator_lock_initialized = true; } } private: # endif // ڶ̻߳ class lock { public: lock() { __NODE_ALLOCATOR_LOCK; } ~lock() { __NODE_ALLOCATOR_UNLOCK; } }; friend class lock; public: /* n must be > 0 */ static void * allocate(size_t n) { obj * __VOLATILE * my_free_list; obj * __RESTRICT result; // __MAX_BYTES, ʹһ if (n > (size_t) __MAX_BYTES) { return(malloc_alloc::allocate(n)); } my_free_list = free_list + FREELIST_INDEX(n); // Acquire the lock here with a constructor call. // This ensures that it is released in exit or during stack // unwinding. # ifndef _NOTHREADS /*REFERENCED*/ lock lock_instance; # endif result = *my_free_list; // ǵһʹ, Ҫڴ // , жڴ, if (result == 0) { void *r = refill(ROUND_UP(n)); return r; } *my_free_list = result -> free_list_link; return (result); }; /* p may not be 0 */ static void deallocate(void *p, size_t n) { obj *q = (obj *)p; obj * __VOLATILE * my_free_list; // ڴ__MAX_BYTESĶ, Ϊõһ, ͬʹһͷ if (n > (size_t) __MAX_BYTES) { malloc_alloc::deallocate(p, n); return; } my_free_list = free_list + FREELIST_INDEX(n); // acquire lock # ifndef _NOTHREADS /*REFERENCED*/ lock lock_instance; # endif /* _NOTHREADS */ q -> free_list_link = *my_free_list; *my_free_list = q; // lock is released here } static void * reallocate(void *p, size_t old_sz, size_t new_sz); } ; typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc; typedef __default_alloc_template single_client_alloc; // ÿηһڴ, ֹηСڴڴƬ // зʱ, ݾ廷Ƿ // ǼٶҪڴڴҪ template char* __default_alloc_template::chunk_alloc(size_t size, int& nobjs) { char * result; size_t total_bytes = size * nobjs; size_t bytes_left = end_free - start_free; // ڴʣ // ڴʣڴ>=Ҫڴ, start_freeָڴ, // ڴʼ if (bytes_left >= total_bytes) { result = start_free; start_free += total_bytes; return(result); } // ڴʣ, ٷһڵʱ, // ܷĽڵ, start_freeָڴ // ڴʼ else if (bytes_left >= size) { nobjs = bytes_left/size; total_bytes = size * nobjs; result = start_free; start_free += total_bytes; return(result); } // ڴʣڴһڵҲ else { size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); // ʣڴָfree_list[FREELIST_INDEX(bytes_left)] if (bytes_left > 0) { obj * __VOLATILE * my_free_list = free_list + FREELIST_INDEX(bytes_left); ((obj *)start_free) -> free_list_link = *my_free_list; *my_free_list = (obj *)start_free; } start_free = (char *)malloc(bytes_to_get); // ʧ, ԭѾڴ, Ƿдڵڵǰڴ if (0 == start_free) { int i; obj * __VOLATILE * my_free_list, *p; // Try to make do with what we have. That can't // hurt. We do not try smaller requests, since that tends // to result in disaster on multi-process machines. for (i = size; i <= __MAX_BYTES; i += __ALIGN) { my_free_list = free_list + FREELIST_INDEX(i); p = *my_free_list; // ҵһ, ڴ if (0 != p) { *my_free_list = p -> free_list_link; start_free = (char *)p; end_free = start_free + i; // ڴظ, ·Ҫڴ return(chunk_alloc(size, nobjs)); // Any leftover piece will eventually make it to the // right free list. } } // ٴʧ, ֱӵһ, ڴ쳣ṩ // ҿ, ڴʧܽѾûʲô, // ֱlog, Ȼó end_free = 0; // In case of exception. start_free = (char *)malloc_alloc::allocate(bytes_to_get); } heap_size += bytes_to_get; end_free = start_free + bytes_to_get; // ڴظ, ·Ҫڴ return(chunk_alloc(size, nobjs)); } } // һСΪnĶ, Ҽ뵽free_list[FREELIST_INDEX(n)] // зʱ, ݾ廷Ƿ // ǼٶҪڴڴҪ template void* __default_alloc_template::refill(size_t n) { int nobjs = 20; char * chunk = chunk_alloc(n, nobjs); obj * __VOLATILE * my_free_list; obj * result; obj * current_obj, * next_obj; int i; // ڴؽֻһĿռ, ֱӷؼ if (1 == nobjs) return(chunk); // ڴܷĿռ my_free_list = free_list + FREELIST_INDEX(n); // chunkĿռнfree_list result = (obj *)chunk; *my_free_list = next_obj = (obj *)(chunk + n); for (i = 1; ; i++) { current_obj = next_obj; next_obj = (obj *)((char *)next_obj + n); if (nobjs - 1 == i) { current_obj -> free_list_link = 0; break; } else { current_obj -> free_list_link = next_obj; } } return(result); } template void* __default_alloc_template::reallocate(void *p, size_t old_sz, size_t new_sz) { void * result; size_t copy_sz; // old_sizenew_size__MAX_BYTES, ֱӵrealloc() // Ϊⲿڴ治Ǿڴط if (old_sz > (size_t) __MAX_BYTES && new_sz > (size_t) __MAX_BYTES) { return(realloc(p, new_sz)); } // ROUND_UP(old_sz) == ROUND_UP(new_sz), ڴСû仯, · if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p); // ·䲢 result = allocate(new_sz); copy_sz = new_sz > old_sz? old_sz : new_sz; memcpy(result, p, copy_sz); deallocate(p, old_sz); return(result); } #ifdef __STL_PTHREADS template pthread_mutex_t __default_alloc_template::__node_allocator_lock = PTHREAD_MUTEX_INITIALIZER; #endif #ifdef __STL_WIN32THREADS template CRITICAL_SECTION __default_alloc_template::__node_allocator_lock; template bool __default_alloc_template::__node_allocator_lock_initialized = false; #endif #ifdef __STL_SGI_THREADS __STL_END_NAMESPACE #include #include __STL_BEGIN_NAMESPACE // Somewhat generic lock implementations. We need only test-and-set // and some way to sleep. These should work with both SGI pthreads // and sproc threads. They may be useful on other systems. template volatile unsigned long __default_alloc_template::__node_allocator_lock = 0; #if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) || defined(__GNUC__) # define __test_and_set(l,v) test_and_set(l,v) #endif template void __default_alloc_template::__lock(volatile unsigned long *lock) { const unsigned low_spin_max = 30; // spin cycles if we suspect uniprocessor const unsigned high_spin_max = 1000; // spin cycles for multiprocessor static unsigned spin_max = low_spin_max; unsigned my_spin_max; static unsigned last_spins = 0; unsigned my_last_spins; static struct timespec ts = {0, 1000}; unsigned junk; # define __ALLOC_PAUSE junk *= junk; junk *= junk; junk *= junk; junk *= junk int i; if (!__test_and_set((unsigned long *)lock, 1)) { return; } my_spin_max = spin_max; my_last_spins = last_spins; for (i = 0; i < my_spin_max; i++) { if (i < my_last_spins/2 || *lock) { __ALLOC_PAUSE; continue; } if (!__test_and_set((unsigned long *)lock, 1)) { // got it! // Spinning worked. Thus we're probably not being scheduled // against the other process with which we were contending. // Thus it makes sense to spin longer the next time. last_spins = i; spin_max = high_spin_max; return; } } // We are probably being scheduled against the other process. Sleep. spin_max = low_spin_max; for (;;) { if (!__test_and_set((unsigned long *)lock, 1)) { return; } nanosleep(&ts, 0); } } template inline void __default_alloc_template::__unlock(volatile unsigned long *lock) { # if defined(__GNUC__) && __mips >= 3 asm("sync"); *lock = 0; # elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) __lock_release(lock); # else *lock = 0; // This is not sufficient on many multiprocessors, since // writes to protected variables and the lock may be reordered. # endif } #endif // ڴʼλ template char *__default_alloc_template::start_free = 0; // ڴؽλ template char *__default_alloc_template::end_free = 0; template size_t __default_alloc_template::heap_size = 0; // ڴ template __default_alloc_template::obj * __VOLATILE __default_alloc_template ::free_list[ # ifdef __SUNPRO_CC __NFREELISTS # else __default_alloc_template::__NFREELISTS # endif ] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; // The 16 zeros are necessary to make version 4.1 of the SunPro // compiler happy. Otherwise it appears to allocate too little // space for the array. # ifdef __STL_WIN32THREADS // Create one to get critical section initialized. // We do this onece per file, but only the first constructor // does anything. static alloc __node_allocator_dummy_instance; # endif #endif /* ! __USE_MALLOC */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #undef __PRIVATE #endif /* __SGI_STL_INTERNAL_ALLOC_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: stl-gatieme/2-defalloc/test.cpp ================================================ #include "simple_jjalloc.h" #include #include using namespace std; int main() { { int ia[5]={0,1,2,3,4}; unsigned int i; vector > iv(ia,ia+5);//使用了JJ::mallocator的alloc来分配内存 for(int i=0;i #include #include using namespace std; #if defined(__SGI_STL_USE_AutoPtr_CONVERSIONS) && \ defined(__STL_MEMBER_TEMPLATES) template struct AutoPtrRef { U* m_pointee; AutoPtrRef(U* p) :m_pointee(p) { } }; #endif /* auto ptr conversions && member templates */ template class AutoPtr { public : /// constructor explicit AutoPtr(T *p = NULL) :m_pointee(p) { /// NOP } /// copy constructor template AutoPtr(AutoPtr &rhs) // Ҫͷrhsָָ ˲Ϊconst :m_pointee(rhs.release()) { /// NOP } /// ~AutoPtr() { delete this->m_pointee; } /// /// ȡget, releaseͷ, reset /// /// ȡָָ T* get( ) const { return m_pointee; } /// ͷָָ T* release( ) { T *temp = this->m_pointee; // ԭַָ this->m_pointee = NULL; // ָָ /// ڴͷ return temp; } /// ָָ void reset(T *p) { if(m_pointee != p) { delete m_pointee; // ͷԭĿռ this->m_pointee = p; // ޸ָ } } /// /// ز /// /// *ptrȡַ T& operator*( ) const { if(m_pointee == NULL) { std::cout <<"pointee is NULL..." < T* operator->( ) const { return m_pointee; } template AutoPtr& operator=(AutoPtr &ptr) { /// auto_pstrռԵĹؼ if(this->m_pointee != ptr.m_pointee) { // Ҫ޸ֵָ delete this->m_pointee; this->m_pointee = ptr.m_pointee; ptr.release( ); // ͷֵָָ } return *this; } /// /// ӵýӿ /// #if defined(__SGI_STL_USE_AutoPtr_CONVERSIONS) && \ defined(__STL_MEMBER_TEMPLATES) /// 캯 AutoPtr(AutoPtrRef ref) : m_pointee(ref.m_pointee) { } // AutoPtr& operator=(AutoPtrRef ref) { if (ref.m_pointee != this->get()) { delete m_pointee; m_pointee = ref.m_pointee; } return *this; } template operator AutoPtrRef( ) { return AutoPtrRef(this->release()); } template operator AutoPtr( ) { return AutoPtr(this->release()); } #endif /* auto ptr conversions && member templates */ private : T *m_pointee; }; int main(void) { AutoPtr pstr1(new string("jeancheng")); AutoPtr pstr2(new string("gatieme")); std::cout <<*pstr1 < becase return 0; } ================================================ FILE: stl-gatieme/3-iterator/3find.cpp ================================================ #include #include #include #include #include using namespace std; int main() { const int arraySize = 7; int ia[arraySize] = {0, 1, 2, 3, 4, 5, 6}; vector ivect(ia, ia + arraySize); list ilist(ia, ia + arraySize); deque ideque(ia, ia + arraySize); vector::iterator it1 = find(ivect.begin(), ivect.end(), 4); if(it1 == ivect.end()) { cout <<"4 not found..." <::iterator it2 = find(ilist.begin(), ilist.end(), 4); if(it2 == ilist.end()) { cout <<"4 not found..." <::iterator it3 = find(ideque.begin(), ideque.end(), 4); if(it3 == ideque.end()) { cout <<"4 not found..." < template void func_impl(Iter iter, T t) { T tmp; // , Tǵָ֮, Ϊint /// ... ԭfuncӦȫ } template inline func(Iter iter) { func_impl(iter, *iter); } int main( ) { int i; func(&i); } ================================================ FILE: stl-gatieme/3-iterator/3function_template2.cpp ================================================ ///c++11 1ģƵ ///http://blog.csdn.net/coolmeme/article/details/43986163 ///http://blog.csdn.net/shinehoo/article/details/5722362 /// STLԴ PDF-119/534 #include template struct MyIter { MyIter(T *p = NULL) :m_ptr(p) { /// NOP... } T& operator*( ) const { return *m_ptr; } typedef T value_type; // Ƕͱ{nested type} T *m_ptr; }; template typename Iter::value_type /// һfuncķֵ func(Iter iter) { /// return *iter; } int main(void) { MyIter ite(new int(8)); std::cout < #include #include template struct MyIter { MyIter(T *p = NULL) :m_ptr(p) { /// NOP... } T& operator*( ) const { return *m_ptr; } typedef T value_type; // Ƕͱ{nested type} T *m_ptr; }; ///// C //template //class C // 汾TΪ //{ // // NOP... //}; // // ///// ػCԭָΪ //template //class C // 汾"TΪԭָ" //{ // // TΪԭָTΪκͱһһ // // NOP... //}; // iterator_traits template struct iterator_traits { typedef typename Iter::value_type value_type; }; // ػiterator_traits, ȡһT template struct iterator_traits { typedef T value_type; }; // ػiterator_traits, ȡһT template struct iterator_traits { typedef T value_type; }; template //typename Iter::value_type /// һfuncķֵ typename iterator_traits::value_type func(Iter iter) { /// return *iter; } int main(void) { MyIter ite(new int(8)); std::cout < >::value_type).name(); std::cout <::value_type).name(); std::cout <::value_type).name(); return 0; } ================================================ FILE: stl-gatieme/3-iterator/3mylist.h ================================================ #ifndef __MYLIST_H__ #define __MYLIST_H__ #include #include #include #include #include #include template class ListItem { public : T value( ) const { return this->m_value; } ListItem *next( ) const { return this->m_next; } protected: T m_value; ListItem *m_next; }; using namespace std; template class List { public : void insert_front(T value) { } void insert_end(T value) { } void display(std::ostream &os = std::cout) const; protected : ListItem *m_end; ListItem *m_front; long m_size; }; #endif // __MYLIST_H__ ================================================ FILE: stl-gatieme/3-iterator/3mylist_iter.h ================================================ #ifndef __MYLIST_ITER_H__ #define __MYLIST_ITER_H__ #include #include #include #include #include #include "3mylist.h" template // itemǵ˫бڵ class ListIter { public : /// /// 캯 /// ListIter(Item *p = NULL) :m_ptr(p) { /// NOP... } /// ʵcopy ctor, ΪṩȱʡΪ㹻 /// ʵoperator= ΪṩȱʡΪ㹻 /// /// ָ /// Item& operator*( ) const { return *m_ptr; } Item* operator->( ) const { return m_ptr; } /// /// operator++ѭ׼, /// //(1) pre-increment operator... // it meens ++i == iter.operator++( ) Item& operator++( ) { m_ptr = m_ptr->m_next; return (*this); } //(2) post-increment operator... // it meens i++ == iter.operator++(int) Item& operator++(int) { Item temp = *this; ++*this; // ǰ++ return temp; } bool operator==(const Item &i) const { return m_ptr == i.m_ptr; } bool operator!=(const Item &i) const { return m_ptr != i.m_ptr; } protected : Item *m_ptr; // ֮ϵ }; #endif // #define __MYLIST_ITER_H__ ================================================ FILE: stl-gatieme/3-iterator/3mylist_iter_stl.h ================================================ #ifndef __MYLIST_ITER_H__ #define __MYLIST_ITER_H__ #include #include _ #include #include #include #include "3mylist.h" template // itemǵ˫бڵ class ListIter : public std::iterator { }; #endif // #define __MYLIST_ITER_H__ ================================================ FILE: stl-gatieme/3-iterator/3mylist_iter_test.cpp ================================================ /************************************************************************* > File Name: 3mylist-iter-test.cpp > Author: gatieme > Created Time: 2016年03月21日 星期一 15时13分39秒 ************************************************************************/ #include #include using namespace std; #include "3mylist.h" #include "3mylist_iter.h" int main( ) { List mylist; for(int i = 0; i < 5; i++) { mylist.insert_front(i); mylist.insert_end(i + 2); } mylist.display( ); ListIter< ListItem > begin(mylist.front); ListIter< Listitem > end; // default 0, null ListIter< Listitem > iter; // default 0, null iter = find(begin, end, 3); if(iter == end) { cout <<"not found" <m_value() <m_value() < using namespace std; struct B /// B ɱΪInputIterator { }; struct D1 : public B /// D1 ɱΪForwardIteraor { }; struct D2 : public D1 // D2 ɱΪBidirectionalIterator { }; template func(I &p, B) { std::cout <<"B version..." < func(I &p, D2) { std::cout <<"D2 version..." < #include #include // general version template class Compare { public: static bool IsEqual(const T& lh, const T& rh) { std::cout <<"in the general class..." < class Compare { public: static bool IsEqual(const float& lh, const float& rh) { std::cout <<"in the float special class..." < class Compare { public: static bool IsEqual(const double& lh, const double& rh) { std::cout <<"in the double special class..." < comp1; std::cout < comp2; std::cout < comp3; std::cout < #include /// ģػ template int compare(const T left, const T right) { std::cout <<"in template..." < int compare(const char* left, const char* right) { std::cout <<"in special template< >..." < //int compare(const char* left, const char* right) //{ // std::cout <<"in special template< >..." < File Name: 3typeif.cpp > Author: gatieme > Created Time: 2016年03月21日 星期一 16时31分59秒 ************************************************************************/ #include #include using namespace std; class A { }; int main( ) { int ia = 10; cout <<"typeid(int) = " < #include using namespace std; class A { public: A( ) { id = ++count; cout <<"create A" < a) { cout << "Enter sink()\n"; } /* øúᴴ󣬲ȡȨ */ auto_ptr create() { cout << "Enter create()\n"; auto_ptr a(new A()); return a; } int main(int argc, char *argv[]) { //auto_ptr pstr(new string("abcd")); //auto_ptr pstr = new string("abcd"); auto_ptr a1 = create(); cout << "Exit create()\n"; auto_ptr a2 = a1; /* ֵתȨʱa1Ч*/ auto_ptr a3(new A()); sink(a2); /* λᶪʧȨᷢa2ͷsinkн*/ cout << "Exit sink()\n"; return 0; } ================================================ FILE: stl-gatieme/3-iterator/test_bad_typeid.cpp ================================================ // expre_bad_typeid.cpp #include #include using namespace std; class A { public: // object for class needs vtable virtual ~A( ); }; int main() { A* a = NULL; try { cout << typeid(*a).name() << endl; // Error condition } catch (bad_typeid) { cout << "Object is NULL" << endl; } return 0; } ================================================ FILE: stl-gatieme/3-iterator/typeinfo.h ================================================ // cp /usr/include/c++/4.4.4/typeinfo ./typeinfo.h // RTTI support for -*- C++ -*- // Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, // 2003, 2004, 2005, 2006, 2007, 2009 // 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 3, 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. // // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file typeinfo * This is a Standard C++ Library header. */ #ifndef _TYPEINFO #define _TYPEINFO #include #pragma GCC visibility push(default) extern "C++" { namespace __cxxabiv1 { class __class_type_info; } // namespace __cxxabiv1 // Determine whether typeinfo names for the same type are merged (in which // case comparison can just compare pointers) or not (in which case strings // must be compared), and whether comparison is to be implemented inline or // not. We used to do inline pointer comparison by default if weak symbols // are available, but even with weak symbols sometimes names are not merged // when objects are loaded with RTLD_LOCAL, so now we always use strcmp by // default. For ABI compatibility, we do the strcmp inline if weak symbols // are available, and out-of-line if not. Out-of-line pointer comparison // is used where the object files are to be portable to multiple systems, // some of which may not be able to use pointer comparison, but the // particular system for which libstdc++ is being built can use pointer // comparison; in particular for most ARM EABI systems, where the ABI // specifies out-of-line comparison. The compiler's target configuration // can override the defaults by defining __GXX_TYPEINFO_EQUALITY_INLINE to // 1 or 0 to indicate whether or not comparison is inline, and // __GXX_MERGED_TYPEINFO_NAMES to 1 or 0 to indicate whether or not pointer // comparison can be used. #ifndef __GXX_MERGED_TYPEINFO_NAMES // By default, typeinfo names are not merged. #define __GXX_MERGED_TYPEINFO_NAMES 0 #endif // By default follow the old inline rules to avoid ABI changes. #ifndef __GXX_TYPEINFO_EQUALITY_INLINE #if !__GXX_WEAK__ #define __GXX_TYPEINFO_EQUALITY_INLINE 0 #else #define __GXX_TYPEINFO_EQUALITY_INLINE 1 #endif #endif namespace std { /** * @brief Part of RTTI. * * The @c type_info class describes type information generated by * an implementation. */ class type_info { public: /** Destructor first. Being the first non-inline virtual function, this * controls in which translation unit the vtable is emitted. The * compiler makes use of that information to know where to emit * the runtime-mandated type_info structures in the new-abi. */ virtual ~type_info(); /** Returns an @e implementation-defined byte string; this is not * portable between compilers! */ const char* name() const { return __name[0] == '*' ? __name + 1 : __name; } #if !__GXX_TYPEINFO_EQUALITY_INLINE // In old abi, or when weak symbols are not supported, there can // be multiple instances of a type_info object for one // type. Uniqueness must use the _name value, not object address. bool before(const type_info& __arg) const; bool operator==(const type_info& __arg) const; #else #if !__GXX_MERGED_TYPEINFO_NAMES /** Returns true if @c *this precedes @c __arg in the implementation's * collation order. */ // Even with the new abi, on systems that support dlopen // we can run into cases where type_info names aren't merged, // so we still need to do string comparison. bool before(const type_info& __arg) const { return (__name[0] == '*' && __arg.__name[0] == '*') ? __name < __arg.__name : __builtin_strcmp (__name, __arg.__name) < 0; } bool operator==(const type_info& __arg) const { return ((__name == __arg.__name) || (__name[0] != '*' && __builtin_strcmp (__name, __arg.__name) == 0)); } #else // On some targets we can rely on type_info's NTBS being unique, // and therefore address comparisons are sufficient. bool before(const type_info& __arg) const { return __name < __arg.__name; } bool operator==(const type_info& __arg) const { return __name == __arg.__name; } #endif #endif bool operator!=(const type_info& __arg) const { return !operator==(__arg); } // Return true if this is a pointer type of some kind virtual bool __is_pointer_p() const; // Return true if this is a function type virtual bool __is_function_p() const; // Try and catch a thrown type. Store an adjusted pointer to the // caught type in THR_OBJ. If THR_TYPE is not a pointer type, then // THR_OBJ points to the thrown object. If THR_TYPE is a pointer // type, then THR_OBJ is the pointer itself. OUTER indicates the // number of outer pointers, and whether they were const // qualified. virtual bool __do_catch(const type_info *__thr_type, void **__thr_obj, unsigned __outer) const; // Internally used during catch matching virtual bool __do_upcast(const __cxxabiv1::__class_type_info *__target, void **__obj_ptr) const; protected: const char *__name; explicit type_info(const char *__n): __name(__n) { } private: /// Assigning type_info is not supported. type_info& operator=(const type_info&); type_info(const type_info&); }; /** * @brief Thrown during incorrect typecasting. * @ingroup exceptions * * If you attempt an invalid @c dynamic_cast expression, an instance of * this class (or something derived from this class) is thrown. */ class bad_cast : public exception { public: bad_cast() throw() { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_cast() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); }; /** * @brief Thrown when a NULL pointer in a @c typeid expression is used. * @ingroup exceptions */ class bad_typeid : public exception { public: bad_typeid () throw() { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_typeid() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); }; } // namespace std #pragma GCC visibility pop } // extern "C++" #endif ================================================ FILE: stl-gatieme/4-sequence-containers/4deque_test.cpp ================================================ #include #include #include #include #include using namespace std; void Print(int a) { cout < ideq(20, 9); // allocֻG++ cout <<"size = " < #include #include #include using namespace std; void Print(int a) { cout < ivec(ia, ia + 9); make_heap(ivec.begin( ), ivec.end( )); for(vector::iterator iter = ivec.begin( ); iter != ivec.end( ); iter++) { cout <::iterator iter = ivec.begin( ); iter != ivec.end( ); iter++) { cout <::iterator iter = ivec.begin( ); iter != ivec.end( ); iter++) { cout < #include #include #include #include #include using namespace std; int main( ) { queue< int, list > iqueue; iqueue.push(1); iqueue.push(3); iqueue.push(5); iqueue.push(7); cout <<"size = " <&2 exit 1 esac echo $PLATFORM exit 0 ================================================ FILE: stl侯杰源码/Makefile ================================================ include Makefile.h all:: CODE_DIRS = util stl cont iter fo algo string num io i18n memory all:: @for DIR in $(CODE_DIRS); \ do \ (cd $$DIR; make all) \ done clean:: @for DIR in $(CODE_DIRS); \ do \ (cd $$DIR; make clean) \ done ================================================ FILE: stl侯杰源码/Makefile.h ================================================ ################################################################## # Makefile with general settings for the book "The C++ Standard Library" # - is included by each individual Makefile # - please send updates and suggestions to libbook@josuttis.com ################################################################## ############################ # GCC settings (general) ############################ GCCFLAGS=-g -ansi -W -Wall -Wwrite-strings -pedantic CXX = g++ CXXFLAGS = $(GCCFLAGS) LDFLAGS = -lm ############################ # GCC settings (special) ############################ #GCCFLAGS=-g -ansi -W -Wall -Wwrite-strings -pedantic #GCCDIR=/local/gcc/rundir #CXX = $(GCCDIR)/bin/g++ #CXXFLAGS = $(GCCFLAGS) #LIBCPPDIR = $(GCCDIR)/lib #LDFLAGS = -L$(LIBCPPDIR) -Wl,--rpath -Wl,$(LIBCPPDIR) -lm ############################ # EDG (and my personal std headers) ############################ #CXX = /local/edg/bin/eccp --exceptions --strict #CXXFLAGS = -Imystd -I../mystd #LDFLAGS = -lm ################################################################## help:: @echo "all: progs" all:: progs .SUFFIXES: .ctt .htt .cpp .hpp .cpp.o: $(CXX) $(CXXFLAGS) -c $*.cpp .o: $(CXX) $*.o $(LDFLAGS) -o $* help:: @echo 'progs: create all in $$(CPPPROGS) and in $$(OUTPROGS)' @echo " (failed progs in MAKE.LOG)" progs:: @cat /dev/null > MAKE.LOG @if test "$(CPPPROGS)" != "" ; \ then \ for PROG in $(CPPPROGS)""; \ do \ echo "MAKE $$PROG"; \ make $$PROG || echo " + make $$PROG failed !!!" >> MAKE.LOG; \ done; \ fi @if test "$(OUTPROGS)" != "" ; \ then \ for PROG in $(OUTPROGS)""; \ do \ echo "MAKE $$PROG"; \ make $$PROG || echo " + make $$PROG failed !!!" >> MAKE.LOG; \ done; \ fi @if test -s MAKE.LOG ; \ then \ echo "failures:"; \ cat MAKE.LOG; \ else \ echo "no failure"; \ fi help:: @echo 'clean: clean all generated' clean:: rm -rf MAKE.LOG *.o *.exe *.ii *.ti *~ rm -rf $(CPPPROGS) $(OUTPROGS) @for DATEI in *.ctt; \ do \ BASE=`basename $$DATEI .ctt`; \ if test -r $$BASE.cpp; \ then \ echo " remove $$BASE.cpp"; \ rm $$BASE.cpp; \ fi; \ if test -x $$BASE; \ then \ echo " remove $$BASE"; \ rm $$BASE; \ fi; \ done @for DATEI in *.cpp; \ do \ BASE=`basename $$DATEI .cpp`; \ if test -x $$BASE; \ then \ echo " remove $$BASE"; \ rm $$BASE; \ fi; \ done @for DATEI in *.htt; \ do \ BASE=`basename $$DATEI .htt`; \ if test -r $$BASE.hpp; \ then \ echo " remove $$BASE.hpp"; \ rm $$BASE.hpp; \ fi; \ done ================================================ FILE: stl侯杰源码/README ================================================ These are the examples from the following book: Nicolai M. Josuttis The C++ Standard Library - A Tutorial and Reference Addison Wesley Longman, 1999 ISBN 0-201-37926-0 For further informations see: http://www.josuttis.com/libbook/ I welcome your feedback. The best way to reach me is by Email: libbook@josuttis.com Copyright 1999 by Addison Wesley Longman, Inc. and Nicolai M. Josuttis. All rights reserved. Permission to use, copy, modify and distribute this software for personal and educational use is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Addison Wesley Longman or the author are not used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Addison Wesley Longman and the author make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ADDISON WESLEY LONGMAN AND THE AUTHOR DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ADDISON WESLEY LONGMAN OR THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ================================================ FILE: stl侯杰源码/algo/Makefile ================================================ OUTPROGS = \ foreach1 foreach2 foreach3 \ count1 minmax1 \ find1 find2 \ searchn1 search1 search2 \ findend1 findof1 adjfind1 \ equal1 misma1 lexico1 \ copy1 copy2 \ transf1 transf2 \ swap1 fill1 generate \ replace1 replace2 \ remove1 remove2 \ unique1 unique2 unique3 \ reverse1 rotate1 rotate2 \ perm1 random1 \ part1 sort1 sort2 psort1 psort2 nth1 \ heap1 \ bsearch1 includes bounds1 eqrange1 \ merge1 setalgos imerge1 \ accu1 inner1 partsum1 adjdiff1 relabs CPPPROGS = copy3 HEADERS = algostuff.hpp include ../Makefile.h ================================================ FILE: stl侯杰源码/algo/accu1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll); // process sum of elements cout << "sum: " << accumulate (coll.begin(), coll.end(), // range 0) // initial value << endl; // process sum of elements less 100 cout << "sum: " << accumulate (coll.begin(), coll.end(), // range -100) // initial value << endl; // process product of elements cout << "product: " << accumulate (coll.begin(), coll.end(), // range 1, // initial value multiplies()) // operation << endl; // process product of elements (use 0 as initial value) cout << "product: " << accumulate (coll.begin(), coll.end(), // range 0, // initial value multiplies()) // operation << endl; } ================================================ FILE: stl侯杰源码/algo/adjdiff1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { deque coll; INSERT_ELEMENTS(coll,1,6); PRINT_ELEMENTS(coll); // print all differences between elements adjacent_difference (coll.begin(), coll.end(), // source ostream_iterator(cout," ")); // dest. cout << endl; // print all sums with the predecessors adjacent_difference (coll.begin(), coll.end(), // source ostream_iterator(cout," "), // dest. plus()); // operation cout << endl; // print all products between elements adjacent_difference (coll.begin(), coll.end(), // source ostream_iterator(cout," "), // dest. multiplies()); // operation cout << endl; } ================================================ FILE: stl侯杰源码/algo/adjfind1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; // return whether the second object has double the value of the first bool doubled (int elem1, int elem2) { return elem1 * 2 == elem2; } int main() { vector coll; coll.push_back(1); coll.push_back(3); coll.push_back(2); coll.push_back(4); coll.push_back(5); coll.push_back(5); coll.push_back(0); PRINT_ELEMENTS(coll,"coll: "); // search first two elements with equal value vector::iterator pos; pos = adjacent_find (coll.begin(), coll.end()); if (pos != coll.end()) { cout << "first two elements with equal value have position " << distance(coll.begin(),pos) + 1 << endl; } // search first two elements for which the second has double the value of the first pos = adjacent_find (coll.begin(), coll.end(), // range doubled); // criterion if (pos != coll.end()) { cout << "first two elements with second value twice the " << "first have pos. " << distance(coll.begin(),pos) + 1 << endl; } } ================================================ FILE: stl侯杰源码/algo/algostuff.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #ifndef ALGOSTUFF_HPP #define ALGOSTUFF_HPP #include #include #include #include #include #include #include #include #include #include #include /* PRINT_ELEMENTS() * - prints optional C-string optcstr followed by * - all elements of the collection coll * - separated by spaces */ template inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") { typename T::const_iterator pos; std::cout << optcstr; for (pos=coll.begin(); pos!=coll.end(); ++pos) { std::cout << *pos << ' '; } std::cout << std::endl; } /* INSERT_ELEMENTS (collection, first, last) * - fill values from first to last into the collection * - NOTE: NO half-open range */ template inline void INSERT_ELEMENTS (T& coll, int first, int last) { for (int i=first; i<=last; ++i) { coll.insert(coll.end(),i); } } #endif /*ALGOSTUFF_HPP*/ ================================================ FILE: stl侯杰源码/algo/bounds1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll; INSERT_ELEMENTS(coll,1,9); INSERT_ELEMENTS(coll,1,9); coll.sort (); PRINT_ELEMENTS(coll); // print first and last position 5 could get inserted list::iterator pos1, pos2; pos1 = lower_bound (coll.begin(), coll.end(), 5); pos2 = upper_bound (coll.begin(), coll.end(), 5); cout << "5 could get position " << distance(coll.begin(),pos1) + 1 << " up to " << distance(coll.begin(),pos2) + 1 << " without breaking the sorting" << endl; // insert 3 at the first possible position without breaking the sorting coll.insert (lower_bound(coll.begin(),coll.end(), 3), 3); // insert 7 at the last possible position without breaking the sorting coll.insert (upper_bound(coll.begin(),coll.end(), 7), 7); PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/algo/bsearch1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll); // check existence of element with value 5 if (binary_search(coll.begin(), coll.end(), 5)) { cout << "5 is present" << endl; } else { cout << "5 is not present" << endl; } // check existence of element with value 42 if (binary_search(coll.begin(), coll.end(), 42)) { cout << "42 is present" << endl; } else { cout << "42 is not present" << endl; } } ================================================ FILE: stl侯杰源码/algo/copy1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll1; list coll2; INSERT_ELEMENTS(coll1,1,9); /* copy elements of coll1 into coll2 * - use back inserter to insert instead of overwrite */ copy (coll1.begin(), coll1.end(), // source range back_inserter(coll2)); // destination range /* print elements of coll2 * - copy elements to cout using an ostream iterator */ copy (coll2.begin(), coll2.end(), // source range ostream_iterator(cout," ")); // destination range cout << endl; /* copy elements of coll1 into coll2 in reverse order * - now overwriting */ copy (coll1.rbegin(), coll1.rend(), // source range coll2.begin()); // destination range // print elements of coll2 again copy (coll2.begin(), coll2.end(), // source range ostream_iterator(cout," ")); // destination range cout << endl; } ================================================ FILE: stl侯杰源码/algo/copy2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { /* initialize source collection with ``..........abcdef..........'' */ vector source(10,'.'); for (int c='a'; c<='f'; c++) { source.push_back(c); } source.insert(source.end(),10,'.'); PRINT_ELEMENTS(source,"source: "); // copy all letters three elements in front of the 'a' vector c1(source.begin(),source.end()); copy (c1.begin()+10, c1.begin()+16, // source range c1.begin()+7); // destination range PRINT_ELEMENTS(c1,"c1: "); // copy all letters three elements behind the 'f' vector c2(source.begin(),source.end()); copy_backward (c2.begin()+10, c2.begin()+16, // source range c2.begin()+19); // destination range PRINT_ELEMENTS(c2,"c2: "); } ================================================ FILE: stl侯杰源码/algo/copy3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { copy (istream_iterator(cin), // beginning of source istream_iterator(), // end of source ostream_iterator(cout,"\n")); // destination } ================================================ FILE: stl侯杰源码/algo/count1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; bool isEven (int elem) { return elem % 2 == 0; } int main() { vector coll; int num; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); // count and print elements with value 4 num = count (coll.begin(), coll.end(), // range 4); // value cout << "number of elements equal to 4: " << num << endl; // count elements with even value num = count_if (coll.begin(), coll.end(), // range isEven); // criterion cout << "number of elements with even value: " << num << endl; // count elements that are greater than value 4 num = count_if (coll.begin(), coll.end(), // range bind2nd(greater(),4)); // criterion cout << "number of elements greater than 4: " << num << endl; } ================================================ FILE: stl侯杰源码/algo/eqrange1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll; INSERT_ELEMENTS(coll,1,9); INSERT_ELEMENTS(coll,1,9); coll.sort (); PRINT_ELEMENTS(coll); // print first and last position 5 could get inserted pair::iterator,list::iterator> range; range = equal_range (coll.begin(), coll.end(), 5); cout << "5 could get position " << distance(coll.begin(),range.first) + 1 << " up to " << distance(coll.begin(),range.second) + 1 << " without breaking the sorting" << endl; } ================================================ FILE: stl侯杰源码/algo/equal1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; bool bothEvenOrOdd (int elem1, int elem2) { return elem1 % 2 == elem2 % 2; } int main() { vector coll1; list coll2; INSERT_ELEMENTS(coll1,1,7); INSERT_ELEMENTS(coll2,3,9); PRINT_ELEMENTS(coll1,"coll1: "); PRINT_ELEMENTS(coll2,"coll2: "); // check whether both collections are equal if (equal (coll1.begin(), coll1.end(), // first range coll2.begin())) { // second range cout << "coll1 == coll2" << endl; } else { cout << "coll1 != coll2" << endl; } // check for corresponding even and odd elements if (equal (coll1.begin(), coll1.end(), // first range coll2.begin(), // second range bothEvenOrOdd)) { // comparison criterion cout << "even and odd elements correspond" << endl; } else { cout << "even and odd elements do not correspond" << endl; } } ================================================ FILE: stl侯杰源码/algo/fill1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { // print ten times 7.7 fill_n(ostream_iterator(cout, " "), // beginning of destination 10, // count 7.7); // new value cout << endl; list coll; // insert "hello" nine times fill_n(back_inserter(coll), // beginning of destination 9, // count "hello"); // new value PRINT_ELEMENTS(coll,"coll: "); // overwrite all elements with "again" fill(coll.begin(), coll.end(), // destination "again"); // new value PRINT_ELEMENTS(coll,"coll: "); // replace all but two elements with "hi" fill_n(coll.begin(), // beginning of destination coll.size()-2, // count "hi"); // new value PRINT_ELEMENTS(coll,"coll: "); // replace the second and up to the last element but one with "hmmm" list::iterator pos1, pos2; pos1 = coll.begin(); pos2 = coll.end(); fill (++pos1, --pos2, // destination "hmmm"); // new value PRINT_ELEMENTS(coll,"coll: "); } ================================================ FILE: stl侯杰源码/algo/find1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll; INSERT_ELEMENTS(coll,1,9); INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); // find first element with value 4 list::iterator pos1; pos1 = find (coll.begin(), coll.end(), // range 4); // value /* find second element with value 4 * - note: continue the search behind the first 4 (if any) */ list::iterator pos2; if (pos1 != coll.end()) { pos2 = find (++pos1, coll.end(), // range 4); // value } /* print all elements from first to second 4 (both included) * - note: now we need the position of the first 4 again (if any) * - note: we have to pass the position behind the second 4 (if any) */ if (pos1!=coll.end() && pos2!=coll.end()) { copy (--pos1, ++pos2, ostream_iterator(cout," ")); cout << endl; } } ================================================ FILE: stl侯杰源码/algo/find2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; vector::iterator pos; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); // find first element greater than 3 pos = find_if (coll.begin(), coll.end(), // range bind2nd(greater(),3)); // criterion // print its position cout << "the " << distance(coll.begin(),pos) + 1 << ". element is the first greater than 3" << endl; // find first element divisible by 3 pos = find_if (coll.begin(), coll.end(), not1(bind2nd(modulus(),3))); // print its position cout << "the " << distance(coll.begin(),pos) + 1 << ". element is the first divisible by 3" << endl; } ================================================ FILE: stl侯杰源码/algo/findend1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { deque coll; list subcoll; INSERT_ELEMENTS(coll,1,7); INSERT_ELEMENTS(coll,1,7); INSERT_ELEMENTS(subcoll,3,6); PRINT_ELEMENTS(coll, "coll: "); PRINT_ELEMENTS(subcoll,"subcoll: "); // search last occurrence of subcoll in coll deque::iterator pos; pos = find_end (coll.begin(), coll.end(), // range subcoll.begin(), subcoll.end()); // subrange // loop while subcoll found as subrange of coll deque::iterator end(coll.end()); while (pos != end) { // print position of first element cout << "subcoll found starting with element " << distance(coll.begin(),pos) + 1 << endl; // search next occurrence of subcoll end = pos; pos = find_end (coll.begin(), end, // range subcoll.begin(), subcoll.end()); // subrange } } ================================================ FILE: stl侯杰源码/algo/findof1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; list searchcoll; INSERT_ELEMENTS(coll,1,11); INSERT_ELEMENTS(searchcoll,3,5); PRINT_ELEMENTS(coll, "coll: "); PRINT_ELEMENTS(searchcoll,"searchcoll: "); // search first occurrence of an element of searchcoll in coll vector::iterator pos; pos = find_first_of (coll.begin(), coll.end(), // range searchcoll.begin(), // beginning of search set searchcoll.end()); // end of search set cout << "first element of searchcoll in coll is element " << distance(coll.begin(),pos) + 1 << endl; // search last occurrence of an element of searchcoll in coll vector::reverse_iterator rpos; rpos = find_first_of (coll.rbegin(), coll.rend(), // range searchcoll.begin(), // beginning of search set searchcoll.end()); // end of search set cout << "last element of searchcoll in coll is element " << distance(coll.begin(),rpos.base()) << endl; } ================================================ FILE: stl侯杰源码/algo/foreach1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; // function called for each element void print (int elem) { cout << elem << ' '; } int main() { vector coll; INSERT_ELEMENTS(coll,1,9); // call print() for each element for_each (coll.begin(), coll.end(), // range print); // operation cout << endl; } ================================================ FILE: stl侯杰源码/algo/foreach2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; // function object that adds the value with which it is initialized template class AddValue { private: T theValue; // value to add public: // constructor initializes the value to add AddValue (const T& v) : theValue(v) { } // the function call for the element adds the value void operator() (T& elem) const { elem += theValue; } }; int main() { vector coll; INSERT_ELEMENTS(coll,1,9); // add ten to each element for_each (coll.begin(), coll.end(), // range AddValue(10)); // operation PRINT_ELEMENTS(coll); // add value of first element to each element for_each (coll.begin(), coll.end(), // range AddValue(*coll.begin())); // operation PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/algo/foreach3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; // function object to process the mean value class MeanValue { private: long num; // number of elements long sum; // sum of all element values public: // constructor MeanValue () : num(0), sum(0) { } // function call // - process one more element of the sequence void operator() (int elem) { num++; // increment count sum += elem; // add value } // return mean value (implicit type conversion) operator double() { return static_cast(sum) / static_cast(num); } }; int main() { vector coll; INSERT_ELEMENTS(coll,1,8); // process and print mean value double mv = for_each (coll.begin(), coll.end(), // range MeanValue()); // operation cout << "mean value: " << mv << endl; } ================================================ FILE: stl侯杰源码/algo/generate.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "algostuff.hpp" using namespace std; int main() { list coll; // insert five random numbers generate_n (back_inserter(coll), // beginning of destination range 5, // count rand); // new value generator PRINT_ELEMENTS(coll); // overwrite with five new random numbers generate (coll.begin(), coll.end(), // destination range rand); // new value generator PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/algo/heap1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; INSERT_ELEMENTS(coll,3,7); INSERT_ELEMENTS(coll,5,9); INSERT_ELEMENTS(coll,1,4); PRINT_ELEMENTS (coll, "on entry: "); // convert collection into a heap make_heap (coll.begin(), coll.end()); PRINT_ELEMENTS (coll, "after make_heap(): "); // pop next element out of the heap pop_heap (coll.begin(), coll.end()); coll.pop_back(); PRINT_ELEMENTS (coll, "after pop_heap(): "); // push new element into the heap coll.push_back (17); push_heap (coll.begin(), coll.end()); PRINT_ELEMENTS (coll, "after push_heap(): "); /* convert heap into a sorted collection * - NOTE: after the call it is no longer a heap */ sort_heap (coll.begin(), coll.end()); PRINT_ELEMENTS (coll, "after sort_heap(): "); } ================================================ FILE: stl侯杰源码/algo/imerge1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll; // insert two sorted sequences INSERT_ELEMENTS(coll,1,7); INSERT_ELEMENTS(coll,1,8); PRINT_ELEMENTS(coll); // find beginning of second part (element after 7) list::iterator pos; pos = find (coll.begin(), coll.end(), // range 7); // value ++pos; // merge into one sorted range inplace_merge (coll.begin(), pos, coll.end()); PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/algo/includes.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll; vector search; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); search.push_back(3); search.push_back(4); search.push_back(7); PRINT_ELEMENTS(search,"search: "); // check whether all elements in search are also in coll if (includes (coll.begin(), coll.end(), search.begin(), search.end())) { cout << "all elements of search are also in coll" << endl; } else { cout << "not all elements of search are also in coll" << endl; } } ================================================ FILE: stl侯杰源码/algo/inner1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll; INSERT_ELEMENTS(coll,1,6); PRINT_ELEMENTS(coll); /* process sum of all products * (0 + 1*1 + 2*2 + 3*3 + 4*4 + 5*5 + 6*6) */ cout << "inner product: " << inner_product (coll.begin(), coll.end(), // first range coll.begin(), // second range 0) // initial value << endl; /* process sum of 1*6 ... 6*1 * (0 + 1*6 + 2*5 + 3*4 + 4*3 + 5*2 + 6*1) */ cout << "inner reverse product: " << inner_product (coll.begin(), coll.end(), // first range coll.rbegin(), // second range 0) // initial value << endl; /* process product of all sums * (1 * 1+1 * 2+2 * 3+3 * 4+4 * 5+5 * 6+6) */ cout << "product of sums: " << inner_product (coll.begin(), coll.end(), // first range coll.begin(), // second range 1, // initial value multiplies(), // outer operation plus()) // inner operation << endl; } ================================================ FILE: stl侯杰源码/algo/lexico1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; void printCollection (const list& l) { PRINT_ELEMENTS(l); } bool lessForCollection (const list& l1, const list& l2) { return lexicographical_compare (l1.begin(), l1.end(), // first range l2.begin(), l2.end()); // second range } int main() { list c1, c2, c3, c4; // fill all collections with the same starting values INSERT_ELEMENTS(c1,1,5); c4 = c3 = c2 = c1; // and now some differences c1.push_back(7); c3.push_back(2); c3.push_back(0); c4.push_back(2); // create collection of collections vector > cc; cc.push_back(c1); cc.push_back(c2); cc.push_back(c3); cc.push_back(c4); cc.push_back(c3); cc.push_back(c1); cc.push_back(c4); cc.push_back(c2); // print all collections for_each (cc.begin(), cc.end(), printCollection); cout << endl; // sort collection lexicographically sort (cc.begin(), cc.end(), // range lessForCollection); // sorting criterion // print all collections again for_each (cc.begin(), cc.end(), printCollection); } ================================================ FILE: stl侯杰源码/algo/merge1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll1; set coll2; // fill both collections with some sorted elements INSERT_ELEMENTS(coll1,1,6); INSERT_ELEMENTS(coll2,3,8); PRINT_ELEMENTS(coll1,"coll1: "); PRINT_ELEMENTS(coll2,"coll2: "); // print merged sequence cout << "merged: "; merge (coll1.begin(), coll1.end(), coll2.begin(), coll2.end(), ostream_iterator(cout," ")); cout << endl; } ================================================ FILE: stl侯杰源码/algo/minmax1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "algostuff.hpp" using namespace std; bool absLess (int elem1, int elem2) { return abs(elem1) < abs(elem2); } int main() { deque coll; INSERT_ELEMENTS(coll,2,8); INSERT_ELEMENTS(coll,-3,5); PRINT_ELEMENTS(coll); // process and print minimum and maximum cout << "minimum: " << *min_element(coll.begin(),coll.end()) << endl; cout << "maximum: " << *max_element(coll.begin(),coll.end()) << endl; // process and print minimum and maximum of absolute values cout << "minimum of absolute values: " << *min_element(coll.begin(),coll.end(), absLess) << endl; cout << "maximum of absolute values: " << *max_element(coll.begin(),coll.end(), absLess) << endl; } ================================================ FILE: stl侯杰源码/algo/misma1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll1; list coll2; INSERT_ELEMENTS(coll1,1,6); for (int i=1; i<=16; i*=2) { coll2.push_back(i); } coll2.push_back(3); PRINT_ELEMENTS(coll1,"coll1: "); PRINT_ELEMENTS(coll2,"coll2: "); // find first mismatch pair::iterator,list::iterator> values; values = mismatch (coll1.begin(), coll1.end(), // first range coll2.begin()); // second range if (values.first == coll1.end()) { cout << "no mismatch" << endl; } else { cout << "first mismatch: " << *values.first << " and " << *values.second << endl; } /* find first position where the element of coll1 is not * less than the corresponding element of coll2 */ values = mismatch (coll1.begin(), coll1.end(), // first range coll2.begin(), // second range less_equal()); // criterion if (values.first == coll1.end()) { cout << "always less-or-equal" << endl; } else { cout << "not less-or-equal: " << *values.first << " and " << *values.second << endl; } } ================================================ FILE: stl侯杰源码/algo/nth1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { deque coll; INSERT_ELEMENTS(coll,3,7); INSERT_ELEMENTS(coll,2,6); INSERT_ELEMENTS(coll,1,5); PRINT_ELEMENTS(coll); // extract the four lowest elements nth_element (coll.begin(), // beginning of range coll.begin()+3, // element that should be sorted correctly coll.end()); // end of range // print them cout << "the four lowest elements are: "; copy (coll.begin(), coll.begin()+4, ostream_iterator(cout," ")); cout << endl; // extract the four highest elements nth_element (coll.begin(), // beginning of range coll.end()-4, // element that should be sorted correctly coll.end()); // end of range // print them cout << "the four highest elements are: "; copy (coll.end()-4, coll.end(), ostream_iterator(cout," ")); cout << endl; // extract the four highest elements (second version) nth_element (coll.begin(), // beginning of range coll.begin()+3, // element that should be sorted correctly coll.end(), // end of range greater()); // sorting criterion // print them cout << "the four highest elements are: "; copy (coll.begin(), coll.begin()+4, ostream_iterator(cout," ")); cout << endl; } ================================================ FILE: stl侯杰源码/algo/part1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll1; vector coll2; INSERT_ELEMENTS(coll1,1,9); INSERT_ELEMENTS(coll2,1,9); PRINT_ELEMENTS(coll1,"coll1: "); PRINT_ELEMENTS(coll2,"coll2: "); cout << endl; // move all even elements to the front vector::iterator pos1, pos2; pos1 = partition(coll1.begin(), coll1.end(), // range not1(bind2nd(modulus(),2))); // criterion pos2 = stable_partition(coll2.begin(), coll2.end(), // range not1(bind2nd(modulus(),2))); // crit. // print collections and first odd element PRINT_ELEMENTS(coll1,"coll1: "); cout << "first odd element: " << *pos1 << endl; PRINT_ELEMENTS(coll2,"coll2: "); cout << "first odd element: " << *pos2 << endl; } ================================================ FILE: stl侯杰源码/algo/partsum1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; INSERT_ELEMENTS(coll,1,6); PRINT_ELEMENTS(coll); // print all partial sums partial_sum (coll.begin(), coll.end(), // source range ostream_iterator(cout," ")); // destination cout << endl; // print all partial products partial_sum (coll.begin(), coll.end(), // source range ostream_iterator(cout," "), // destination multiplies()); // operation cout << endl; } ================================================ FILE: stl侯杰源码/algo/perm1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; INSERT_ELEMENTS(coll,1,3); PRINT_ELEMENTS(coll,"on entry: "); /* permute elements until they are sorted * - runs through all permutations because the elements are sorted now */ while (next_permutation(coll.begin(),coll.end())) { PRINT_ELEMENTS(coll," "); } PRINT_ELEMENTS(coll,"afterward: "); /* permute until descending sorted * - this is the next permutation after ascending sorting * - so the loop ends immediately */ while (prev_permutation(coll.begin(),coll.end())) { PRINT_ELEMENTS(coll," "); } PRINT_ELEMENTS(coll,"now: "); /* permute elements until they are sorted in descending order * - runs through all permutations because the elements are sorted * in descending order now */ while (prev_permutation(coll.begin(),coll.end())) { PRINT_ELEMENTS(coll," "); } PRINT_ELEMENTS(coll,"afterward: "); } ================================================ FILE: stl侯杰源码/algo/psort1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { deque coll; INSERT_ELEMENTS(coll,3,7); INSERT_ELEMENTS(coll,2,6); INSERT_ELEMENTS(coll,1,5); PRINT_ELEMENTS(coll); // sort until the first five elements are sorted partial_sort (coll.begin(), // beginning of the range coll.begin()+5, // end of sorted range coll.end()); // end of full range PRINT_ELEMENTS(coll); // sort inversely until the first five elements are sorted partial_sort (coll.begin(), // beginning of the range coll.begin()+5, // end of sorted range coll.end(), // end of full range greater()); // sorting criterion PRINT_ELEMENTS(coll); // sort all elements partial_sort (coll.begin(), // beginning of the range coll.end(), // end of sorted range coll.end()); // end of full range PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/algo/psort2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { deque coll1; vector coll6(6); // initialize with 6 elements vector coll30(30); // initialize with 30 elements INSERT_ELEMENTS(coll1,3,7); INSERT_ELEMENTS(coll1,2,6); INSERT_ELEMENTS(coll1,1,5); PRINT_ELEMENTS(coll1); // copy elements of coll1 sorted into coll6 vector::iterator pos6; pos6 = partial_sort_copy (coll1.begin(), coll1.end(), coll6.begin(), coll6.end()); // print all copied elements copy (coll6.begin(), pos6, ostream_iterator(cout," ")); cout << endl; // copy elements of coll1 sorted into coll30 vector::iterator pos30; pos30 = partial_sort_copy (coll1.begin(), coll1.end(), coll30.begin(), coll30.end(), greater()); // print all copied elements copy (coll30.begin(), pos30, ostream_iterator(cout," ")); cout << endl; } ================================================ FILE: stl侯杰源码/algo/random1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "algostuff.hpp" using namespace std; class MyRandom { public: ptrdiff_t operator() (ptrdiff_t max) { double tmp; tmp = static_cast(rand()) / static_cast(RAND_MAX); return static_cast(tmp * max); } }; int main() { vector coll; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); // shuffle all elements randomly random_shuffle (coll.begin(), coll.end()); PRINT_ELEMENTS(coll,"shuffled: "); // sort them again sort (coll.begin(), coll.end()); PRINT_ELEMENTS(coll,"sorted: "); /* shuffle elements with self-written random number generator * - to pass an lvalue we have to use a temporary object */ MyRandom rd; random_shuffle (coll.begin(), coll.end(), // range rd); // random number generator PRINT_ELEMENTS(coll,"shuffled: "); } ================================================ FILE: stl侯杰源码/algo/relabs.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; coll.push_back(17); coll.push_back(-3); coll.push_back(22); coll.push_back(13); coll.push_back(13); coll.push_back(-9); PRINT_ELEMENTS(coll,"coll: "); // convert into relative values adjacent_difference (coll.begin(), coll.end(), // source coll.begin()); // destination PRINT_ELEMENTS(coll,"relative: "); // convert into absolute values partial_sum (coll.begin(), coll.end(), // source coll.begin()); // destination PRINT_ELEMENTS(coll,"absolute: "); } ================================================ FILE: stl侯杰源码/algo/remove1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; INSERT_ELEMENTS(coll,2,6); INSERT_ELEMENTS(coll,4,9); INSERT_ELEMENTS(coll,1,7); PRINT_ELEMENTS(coll,"coll: "); // remove all elements with value 5 vector::iterator pos; pos = remove(coll.begin(), coll.end(), // range 5); // value to remove PRINT_ELEMENTS(coll,"size not changed: "); // erase the ``removed'' elements in the container coll.erase(pos, coll.end()); PRINT_ELEMENTS(coll,"size changed: "); // remove all elements less than 4 coll.erase(remove_if(coll.begin(), coll.end(), // range bind2nd(less(),4)), // remove criterion coll.end()); PRINT_ELEMENTS(coll,"<4 removed: "); } ================================================ FILE: stl侯杰源码/algo/remove2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll1; INSERT_ELEMENTS(coll1,1,6); INSERT_ELEMENTS(coll1,1,9); PRINT_ELEMENTS(coll1); // print elements without those having the value 3 remove_copy(coll1.begin(), coll1.end(), // source ostream_iterator(cout," "), // destination 3); // removed value cout << endl; // print elements without those having a value greater than 4 remove_copy_if(coll1.begin(), coll1.end(), // source ostream_iterator(cout," "), // destination bind2nd(greater(),4)); // removed elements cout << endl; // copy all elements greater than 3 into a multiset multiset coll2; remove_copy_if(coll1.begin(), coll1.end(), // source inserter(coll2,coll2.end()), // destination bind2nd(less(),4)); // elements not copied PRINT_ELEMENTS(coll2); } ================================================ FILE: stl侯杰源码/algo/replace1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll; INSERT_ELEMENTS(coll,2,7); INSERT_ELEMENTS(coll,4,9); PRINT_ELEMENTS(coll,"coll: "); // replace all elements with value 6 with 42 replace (coll.begin(), coll.end(), // range 6, // old value 42); // new value PRINT_ELEMENTS(coll,"coll: "); // replace all elements with value less than 5 with 0 replace_if (coll.begin(), coll.end(), // range bind2nd(less(),5), // criterion for replacement 0); // new value PRINT_ELEMENTS(coll,"coll: "); } ================================================ FILE: stl侯杰源码/algo/replace2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { list coll; INSERT_ELEMENTS(coll,2,6); INSERT_ELEMENTS(coll,4,9); PRINT_ELEMENTS(coll); // print all elements with value 5 replaced with 55 replace_copy(coll.begin(), coll.end(), // source ostream_iterator(cout," "), // destination 5, // old value 55); // new value cout << endl; // print all elements with a value less than 5 replaced with 42 replace_copy_if(coll.begin(), coll.end(), // source ostream_iterator(cout," "), // destination bind2nd(less(),5), // replacement criterion 42); // new value cout << endl; // print each element while each odd element is replaced with 0 replace_copy_if(coll.begin(), coll.end(), // source ostream_iterator(cout," "), // destination bind2nd(modulus(),2), // replacement criterion 0); // new value cout << endl; } ================================================ FILE: stl侯杰源码/algo/reverse1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); // reverse order of elements reverse (coll.begin(), coll.end()); PRINT_ELEMENTS(coll,"coll: "); // reverse order from second to last element but one reverse (coll.begin()+1, coll.end()-1); PRINT_ELEMENTS(coll,"coll: "); // print all of them in reverse order reverse_copy (coll.begin(), coll.end(), // source ostream_iterator(cout," ")); // destination cout << endl; } ================================================ FILE: stl侯杰源码/algo/rotate1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); // rotate one element to the left rotate (coll.begin(), // beginning of range coll.begin() + 1, // new first element coll.end()); // end of range PRINT_ELEMENTS(coll,"one left: "); // rotate two elements to the right rotate (coll.begin(), // beginning of range coll.end() - 2, // new first element coll.end()); // end of range PRINT_ELEMENTS(coll,"two right: "); // rotate so that element with value 4 is the beginning rotate (coll.begin(), // beginning of range find(coll.begin(),coll.end(),4), // new first element coll.end()); // end of range PRINT_ELEMENTS(coll,"4 first: "); } ================================================ FILE: stl侯杰源码/algo/rotate2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { set coll; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll); // print elements rotated one element to the left set::iterator pos = coll.begin(); advance(pos,1); rotate_copy(coll.begin(), // beginning of source pos, // new first element coll.end(), // end of source ostream_iterator(cout," ")); // destination cout << endl; // print elements rotated two elements to the right pos = coll.end(); advance(pos,-2); rotate_copy(coll.begin(), // beginning of source pos, // new first element coll.end(), // end of source ostream_iterator(cout," ")); // destination cout << endl; // print elements rotated so that element with value 4 is the beginning rotate_copy(coll.begin(), // beginning of source coll.find(4), // new first element coll.end(), // end of source ostream_iterator(cout," ")); // destination cout << endl; } ================================================ FILE: stl侯杰源码/algo/search1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { deque coll; list subcoll; INSERT_ELEMENTS(coll,1,7); INSERT_ELEMENTS(coll,1,7); INSERT_ELEMENTS(subcoll,3,6); PRINT_ELEMENTS(coll, "coll: "); PRINT_ELEMENTS(subcoll,"subcoll: "); // search first occurrence of subcoll in coll deque::iterator pos; pos = search (coll.begin(), coll.end(), // range subcoll.begin(), subcoll.end()); // subrange // loop while subcoll found as subrange of coll while (pos != coll.end()) { // print position of first element cout << "subcoll found starting with element " << distance(coll.begin(),pos) + 1 << endl; // search next occurrence of subcoll ++pos; pos = search (pos, coll.end(), // range subcoll.begin(), subcoll.end()); // subrange } } ================================================ FILE: stl侯杰源码/algo/search2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; // checks whether an element is even or odd bool checkEven (int elem, bool even) { if (even) { return elem % 2 == 0; } else { return elem % 2 == 1; } } int main() { vector coll; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); /* arguments for checkEven() * - check for: ``even odd even'' */ bool checkEvenArgs[3] = { true, false, true }; // search first subrange in coll vector::iterator pos; pos = search (coll.begin(), coll.end(), // range checkEvenArgs, checkEvenArgs+3, // subrange values checkEven); // subrange criterion // loop while subrange found while (pos != coll.end()) { // print position of first element cout << "subrange found starting with element " << distance(coll.begin(),pos) + 1 << endl; // search next subrange in coll pos = search (++pos, coll.end(), // range checkEvenArgs, checkEvenArgs+3, // subr. values checkEven); // subr. criterion } } ================================================ FILE: stl侯杰源码/algo/searchn1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { deque coll; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll); // find four consecutive elements with value 3 deque::iterator pos; pos = search_n (coll.begin(), coll.end(), // range 4, // count 3); // value // print result if (pos != coll.end()) { cout << "four consecutive elements with value 3 " << "start with " << distance(coll.begin(),pos) +1 << ". element" << endl; } else { cout << "no four consecutive elements with value 3 found" << endl; } // find four consecutive elements with value greater than 3 pos = search_n (coll.begin(), coll.end(), // range 4, // count 3, // value greater()); // criterion // print result if (pos != coll.end()) { cout << "four consecutive elements with value > 3 " << "start with " << distance(coll.begin(),pos) +1 << ". element" << endl; } else { cout << "no four consecutive elements with value > 3 found" << endl; } } ================================================ FILE: stl侯杰源码/algo/setalgos.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { int c1[] = { 1, 2, 2, 4, 6, 7, 7, 9 }; int num1 = sizeof(c1) / sizeof(int); int c2[] = { 2, 2, 2, 3, 6, 6, 8, 9 }; int num2 = sizeof(c2) / sizeof(int); // print source ranges cout << "c1: " ; copy (c1, c1+num1, ostream_iterator(cout," ")); cout << endl; cout << "c2: " ; copy (c2, c2+num2, ostream_iterator(cout," ")); cout << '\n' << endl; // sum the ranges by using merge() cout << "merge(): "; merge (c1, c1+num1, c2, c2+num2, ostream_iterator(cout," ")); cout << endl; // unite the ranges by using set_union() cout << "set_union(): "; set_union (c1, c1+num1, c2, c2+num2, ostream_iterator(cout," ")); cout << endl; // intersect the ranges by using set_intersection() cout << "set_intersection(): "; set_intersection (c1, c1+num1, c2, c2+num2, ostream_iterator(cout," ")); cout << endl; // determine elements of first range without elements of second range // by using set_difference() cout << "set_difference(): "; set_difference (c1, c1+num1, c2, c2+num2, ostream_iterator(cout," ")); cout << endl; // determine difference the ranges with set_symmetric_difference() cout << "set_symmetric_difference(): "; set_symmetric_difference (c1, c1+num1, c2, c2+num2, ostream_iterator(cout," ")); cout << endl; } ================================================ FILE: stl侯杰源码/algo/sort1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { deque coll; INSERT_ELEMENTS(coll,1,9); INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"on entry: "); // sort elements sort (coll.begin(), coll.end()); PRINT_ELEMENTS(coll,"sorted: "); // sorted reverse sort (coll.begin(), coll.end(), // range greater()); // sorting criterion PRINT_ELEMENTS(coll,"sorted >: "); } ================================================ FILE: stl侯杰源码/algo/sort2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; bool lessLength (const string& s1, const string& s2) { return s1.length() < s2.length(); } int main() { vector coll1; vector coll2; // fill both collections with the same elements coll1.push_back ("1xxx"); coll1.push_back ("2x"); coll1.push_back ("3x"); coll1.push_back ("4x"); coll1.push_back ("5xx"); coll1.push_back ("6xxxx"); coll1.push_back ("7xx"); coll1.push_back ("8xxx"); coll1.push_back ("9xx"); coll1.push_back ("10xxx"); coll1.push_back ("11"); coll1.push_back ("12"); coll1.push_back ("13"); coll1.push_back ("14xx"); coll1.push_back ("15"); coll1.push_back ("16"); coll1.push_back ("17"); coll2 = coll1; PRINT_ELEMENTS(coll1,"on entry:\n "); // sort (according to the length of the strings) sort (coll1.begin(), coll1.end(), // range lessLength); // criterion stable_sort (coll2.begin(), coll2.end(), // range lessLength); // criterion PRINT_ELEMENTS(coll1,"\nwith sort():\n "); PRINT_ELEMENTS(coll2,"\nwith stable_sort():\n "); } ================================================ FILE: stl侯杰源码/algo/swap1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll1; deque coll2; INSERT_ELEMENTS(coll1,1,9); INSERT_ELEMENTS(coll2,11,23); PRINT_ELEMENTS(coll1,"coll1: "); PRINT_ELEMENTS(coll2,"coll2: "); // swap elements of coll1 with corresponding elements of coll2 deque::iterator pos; pos = swap_ranges (coll1.begin(), coll1.end(), // first range coll2.begin()); // second range PRINT_ELEMENTS(coll1,"\ncoll1: "); PRINT_ELEMENTS(coll2,"coll2: "); if (pos != coll2.end()) { cout << "first element not modified: " << *pos << endl; } // mirror first three with last three elements in coll2 swap_ranges (coll2.begin(), coll2.begin()+3, // first range coll2.rbegin()); // second range PRINT_ELEMENTS(coll2,"\ncoll2: "); } ================================================ FILE: stl侯杰源码/algo/transf1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll1; list coll2; INSERT_ELEMENTS(coll1,1,9); PRINT_ELEMENTS(coll1,"coll1: "); // negate all elements in coll1 transform (coll1.begin(), coll1.end(), // source range coll1.begin(), // destination range negate()); // operation PRINT_ELEMENTS(coll1,"negated: "); // transform elements of coll1 into coll2 with ten times their value transform (coll1.begin(), coll1.end(), // source range back_inserter(coll2), // destination range bind2nd(multiplies(),10)); // operation PRINT_ELEMENTS(coll2,"coll2: "); // print coll2 negatively and in reverse order transform (coll2.rbegin(), coll2.rend(), // source range ostream_iterator(cout," "), // destination range negate()); // operation cout << endl; } ================================================ FILE: stl侯杰源码/algo/transf2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { vector coll1; list coll2; INSERT_ELEMENTS(coll1,1,9); PRINT_ELEMENTS(coll1,"coll1: "); // square each element transform (coll1.begin(), coll1.end(), // first source range coll1.begin(), // second source range coll1.begin(), // destination range multiplies()); // operation PRINT_ELEMENTS(coll1,"squared: "); /* add each element traversed forward with each element traversed backward * and insert result into coll2 */ transform (coll1.begin(), coll1.end(), // first source range coll1.rbegin(), // second source range back_inserter(coll2), // destination range plus()); // operation PRINT_ELEMENTS(coll2,"coll2: "); // print differences of two corresponding elements cout << "diff: "; transform (coll1.begin(), coll1.end(), // first source range coll2.begin(), // second source range ostream_iterator(cout, " "), // destination range minus()); // operation cout << endl; } ================================================ FILE: stl侯杰源码/algo/unique1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; int main() { // source data int source[] = { 1, 4, 4, 6, 1, 2, 2, 3, 1, 6, 6, 6, 5, 7, 5, 4, 4 }; int sourceNum = sizeof(source)/sizeof(source[0]); list coll; // initialize coll with elements from source copy (source, source+sourceNum, // source back_inserter(coll)); // destination PRINT_ELEMENTS(coll); // remove consecutive duplicates list::iterator pos; pos = unique (coll.begin(), coll.end()); /* print elements not removed * - use new logical end */ copy (coll.begin(), pos, // source ostream_iterator(cout," ")); // destination cout << "\n\n"; // reinitialize coll with elements from source copy (source, source+sourceNum, // source coll.begin()); // destination PRINT_ELEMENTS(coll); // remove elements if there was a previous greater element coll.erase (unique (coll.begin(), coll.end(), greater()), coll.end()); PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/algo/unique2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "algostuff.hpp" using namespace std; bool differenceOne (int elem1, int elem2) { return elem1 + 1 == elem2 || elem1 - 1 == elem2; } int main() { // source data int source[] = { 1, 4, 4, 6, 1, 2, 2, 3, 1, 6, 6, 6, 5, 7, 5, 4, 4 }; int sourceNum = sizeof(source)/sizeof(source[0]); // initialize coll with elements from source list coll; copy(source, source+sourceNum, // source back_inserter(coll)); // destination PRINT_ELEMENTS(coll); // print elements with consecutive duplicates removed unique_copy(coll.begin(), coll.end(), // source ostream_iterator(cout," ")); // destination cout << endl; // print elements without consecutive entries that differ by one unique_copy(coll.begin(), coll.end(), // source ostream_iterator(cout," "), // destination differenceOne); // duplicates criterion cout << endl; } ================================================ FILE: stl侯杰源码/algo/unique3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; bool bothSpaces (char elem1, char elem2) { return elem1 == ' ' && elem2 == ' '; } int main() { // don't skip leading whitespaces by default cin.unsetf(ios::skipws); /* copy standard input to standard output * - while compressing spaces */ unique_copy(istream_iterator(cin), // beginning of source: cin istream_iterator(), // end of source: end-of-file ostream_iterator(cout), // destination: cout bothSpaces); // duplicate criterion } ================================================ FILE: stl侯杰源码/cont/Makefile ================================================ OUTPROGS = vector1 deque1 list1 \ set2 set1 mset1 setcmp \ map1 mmap1 mapfind mapcmp \ array1 carray1 refsem1 \ stack1 stack2 queue1 queue2 pqueue1 \ bitset2 CPPPROGS = sortset sortvec bitset1 HEADERS = newkey.hpp carray.hpp countptr.hpp Stack.hpp Queue.hpp print.hpp include ../Makefile.h refsem1: countptr.hpp refsem1.cpp $(CXX) $(CXXFLAGS) $(LDFLAGS) $@.cpp -o $@ carray1: carray.hpp carray1.cpp $(CXX) $(CXXFLAGS) $(LDFLAGS) $@.cpp -o $@ stack2: Stack.hpp stack2.cpp $(CXX) $(CXXFLAGS) $(LDFLAGS) $@.cpp -o $@ queue2: Queue.hpp queue2.cpp $(CXX) $(CXXFLAGS) $(LDFLAGS) $@.cpp -o $@ ================================================ FILE: stl侯杰源码/cont/Queue.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ /* ************************************************************ * Queue.hpp * - safer and more convenient queue class * ************************************************************/ #ifndef QUEUE_HPP #define QUEUE_HPP #include #include template class Queue { protected: std::deque c; // container for the elements public: /* exception class for pop() and top() with empty queue */ class ReadEmptyQueue : public std::exception { public: virtual const char* what() const throw() { return "read empty queue"; } }; // number of elements typename std::deque::size_type size() const { return c.size(); } // is queue empty? bool empty() const { return c.empty(); } // insert element into the queue void push (const T& elem) { c.push_back(elem); } // read element from the queue and return its value T pop () { if (c.empty()) { throw ReadEmptyQueue(); } T elem(c.front()); c.pop_front(); return elem; } // return value of next element T& front () { if (c.empty()) { throw ReadEmptyQueue(); } return c.front(); } }; #endif /* QUEUE_HPP */ ================================================ FILE: stl侯杰源码/cont/Stack.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ /* ************************************************************ * Stack.hpp * - safer and more convenient stack class * ************************************************************/ #ifndef STACK_HPP #define STACK_HPP #include #include template class Stack { protected: std::deque c; // container for the elements public: /* exception class for pop() and top() with empty stack */ class ReadEmptyStack : public std::exception { public: virtual const char* what() const throw() { return "read empty stack"; } }; // number of elements typename std::deque::size_type size() const { return c.size(); } // is stack empty? bool empty() const { return c.empty(); } // push element into the stack void push (const T& elem) { c.push_back(elem); } // pop element out of the stack and return its value T pop () { if (c.empty()) { throw ReadEmptyStack(); } T elem(c.back()); c.pop_back(); return elem; } // return value of next element T& top () { if (c.empty()) { throw ReadEmptyStack(); } return c.back(); } }; #endif /* STACK_HPP */ ================================================ FILE: stl侯杰源码/cont/array1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { int coll[] = { 5, 6, 2, 4, 1, 3 }; // square all elements transform (coll, coll+6, // first source coll, // second source coll, // destination multiplies()); // operation // sort beginning with the second element sort (coll+1, coll+6); // print all elements copy (coll, coll+6, ostream_iterator(cout," ")); cout << endl; } ================================================ FILE: stl侯杰源码/cont/bitset1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { /* enumeration type for the bits * - each bit represents a color */ enum Color { red, yellow, green, blue, white, black, //..., numColors }; // create bitset for all bits/colors bitset usedColors; // set bits for two colors usedColors.set(red); usedColors.set(blue); // print some bitset data cout << "bitfield of used colors: " << usedColors << endl; cout << "number of used colors: " << usedColors.count() << endl; cout << "bitfield of unused colors: " << ~usedColors << endl; // if any color is used if (usedColors.any()) { // loop over all colors for (int c = 0; c < numColors; ++c) { // if the actual color is used if (usedColors[(Color)c]) { //... } } } } ================================================ FILE: stl侯杰源码/cont/bitset2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { /* print some numbers in binary representation */ cout << "267 as binary short: " << bitset::digits>(267) << endl; cout << "267 as binary long: " << bitset::digits>(267) << endl; cout << "10,000,000 with 24 bits: " << bitset<24>(1e7) << endl; /* transform binary representation into integral number */ cout << "\"1000101011\" as number: " << bitset<100>(string("1000101011")).to_ulong() << endl; } ================================================ FILE: stl侯杰源码/cont/carray.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include template class carray { private: T v[thesize]; // fixed-size array of elements of type T public: // type definitions typedef T value_type; typedef T* iterator; typedef const T* const_iterator; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; // iterator support iterator begin() { return v; } const_iterator begin() const { return v; } iterator end() { return v+thesize; } const_iterator end() const { return v+thesize; } // direct element access reference operator[](std::size_t i) { return v[i]; } const_reference operator[](std::size_t i) const { return v[i]; } // size is constant size_type size() const { return thesize; } size_type max_size() const { return thesize; } // conversion to ordinary array T* as_array() { return v; } }; ================================================ FILE: stl侯杰源码/cont/carray1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include "carray.hpp" #include "print.hpp" using namespace std; int main() { carray a; for (unsigned i=0; i()); // operation PRINT_ELEMENTS(a); } ================================================ FILE: stl侯杰源码/cont/countptr.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #ifndef COUNTED_PTR_HPP #define COUNTED_PTR_HPP /* class for counted reference semantics * - deletes the object to which it refers when the last CountedPtr * that refers to it is destroyed */ template class CountedPtr { private: T* ptr; // pointer to the value long* count; // shared number of owners public: // initialize pointer with existing pointer // - requires that the pointer p is a return value of new explicit CountedPtr (T* p=0) : ptr(p), count(new long(1)) { } // copy pointer (one more owner) CountedPtr (const CountedPtr& p) throw() : ptr(p.ptr), count(p.count) { ++*count; } // destructor (delete value if this was the last owner) ~CountedPtr () throw() { dispose(); } // assignment (unshare old and share new value) CountedPtr& operator= (const CountedPtr& p) throw() { if (this != &p) { dispose(); ptr = p.ptr; count = p.count; ++*count; } return *this; } // access the value to which the pointer refers T& operator*() const throw() { return *ptr; } T* operator->() const throw() { return ptr; } private: void dispose() { if (--*count == 0) { delete count; delete ptr; } } }; #endif /*COUNTED_PTR_HPP*/ ================================================ FILE: stl侯杰源码/cont/deque1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; int main() { // create empty deque of strings deque coll; // insert several elements coll.assign (3, string("string")); coll.push_back ("last string"); coll.push_front ("first string"); // print elements separated by newlines copy (coll.begin(), coll.end(), ostream_iterator(cout,"\n")); cout << endl; // remove first and last element coll.pop_front(); coll.pop_back(); // insert ``another'' into every element but the first for (unsigned i=1; i(cout,"\n")); } ================================================ FILE: stl侯杰源码/cont/list1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; void printLists (const list& l1, const list& l2) { cout << "list1: "; copy (l1.begin(), l1.end(), ostream_iterator(cout," ")); cout << endl << "list2: "; copy (l2.begin(), l2.end(), ostream_iterator(cout," ")); cout << endl << endl; } int main() { // create two empty lists list list1, list2; // fill both lists with elements for (int i=0; i<6; ++i) { list1.push_back(i); list2.push_front(i); } printLists(list1, list2); // insert all elements of list1 before the first element with value 3 of list2 // - find() returns an iterator to the first element with value 3 list2.splice(find(list2.begin(),list2.end(), // destination position 3), list1); // source list printLists(list1, list2); // move first element to the end list2.splice(list2.end(), // destination position list2, // source list list2.begin()); // source position printLists(list1, list2); // sort second list, assign to list1 and remove duplicates list2.sort(); list1 = list2; list2.unique(); printLists(list1, list2); // merge both sorted lists into the first list list1.merge(list2); printLists(list1, list2); } ================================================ FILE: stl侯杰源码/cont/map1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { /* create map / associative array * - keys are strings * - values are floats */ typedef map StringFloatMap; StringFloatMap stocks; // create empty container // insert some elements stocks["BASF"] = 369.50; stocks["VW"] = 413.50; stocks["Daimler"] = 819.00; stocks["BMW"] = 834.00; stocks["Siemens"] = 842.20; // print all elements StringFloatMap::iterator pos; for (pos = stocks.begin(); pos != stocks.end(); ++pos) { cout << "stock: " << pos->first << "\t" << "price: " << pos->second << endl; } cout << endl; // boom (all prices doubled) for (pos = stocks.begin(); pos != stocks.end(); ++pos) { pos->second *= 2; } // print all elements for (pos = stocks.begin(); pos != stocks.end(); ++pos) { cout << "stock: " << pos->first << "\t" << "price: " << pos->second << endl; } cout << endl; /* rename key from "VW" to "Volkswagen" * - only provided by exchanging element */ stocks["Volkswagen"] = stocks["VW"]; stocks.erase("VW"); // print all elements for (pos = stocks.begin(); pos != stocks.end(); ++pos) { cout << "stock: " << pos->first << "\t" << "price: " << pos->second << endl; } } ================================================ FILE: stl侯杰源码/cont/mapcmp.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; /* function object to compare strings * - allows you to set the comparison criterion at runtime * - allows you to compare case insensitive */ class RuntimeStringCmp { public: // constants for the comparison criterion enum cmp_mode {normal, nocase}; private: // actual comparison mode const cmp_mode mode; // auxiliary function to compare case insensitive static bool nocase_compare (char c1, char c2) { return toupper(c1) < toupper(c2); } public: // constructor: initializes the comparison criterion RuntimeStringCmp (cmp_mode m=normal) : mode(m) { } // the comparison bool operator() (const string& s1, const string& s2) const { if (mode == normal) { return s1 StringStringMap; // function that fills and prints such containers void fillAndPrint(StringStringMap& coll); int main() { // create a container with the default comparison criterion StringStringMap coll1; fillAndPrint(coll1); // create an object for case-insensitive comparisons RuntimeStringCmp ignorecase(RuntimeStringCmp::nocase); // create a container with the case-insensitive comparisons criterion StringStringMap coll2(ignorecase); fillAndPrint(coll2); } void fillAndPrint(StringStringMap& coll) { // fill insert elements in random order coll["Deutschland"] = "Germany"; coll["deutsch"] = "German"; coll["Haken"] = "snag"; coll["arbeiten"] = "work"; coll["Hund"] = "dog"; coll["gehen"] = "go"; coll["Unternehmen"] = "enterprise"; coll["unternehmen"] = "undertake"; coll["gehen"] = "walk"; coll["Bestatter"] = "undertaker"; // print elements StringStringMap::iterator pos; cout.setf(ios::left, ios::adjustfield); for (pos=coll.begin(); pos!=coll.end(); ++pos) { cout << setw(15) << pos->first.c_str() << " " << pos->second << endl; } cout << endl; } ================================================ FILE: stl侯杰源码/cont/mapfind.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; /* function object to check the value of a map element */ template class value_equals { private: V value; public: // constructor (initialize value to compare with) value_equals (const V& v) : value(v) { } // comparison bool operator() (pair elem) { return elem.second == value; } }; int main() { typedef map FloatFloatMap; FloatFloatMap coll; FloatFloatMap::iterator pos; // fill container coll[1]=7; coll[2]=4; coll[3]=2; coll[4]=3; coll[5]=6; coll[6]=1; coll[7]=3; // search an element with key 3.0 pos = coll.find(3.0); // logarithmic complexity if (pos != coll.end()) { cout << pos->first << ": " << pos->second << endl; } // search an element with value 3.0 pos = find_if(coll.begin(),coll.end(), // linear complexity value_equals(3.0)); if (pos != coll.end()) { cout << pos->first << ": " << pos->second << endl; } } ================================================ FILE: stl侯杰源码/cont/mmap1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { // define multimap type as string/string dictionary typedef multimap StrStrMMap; // create empty dictionary StrStrMMap dict; // insert some elements in random order dict.insert(make_pair("day","Tag")); dict.insert(make_pair("strange","fremd")); dict.insert(make_pair("car","Auto")); dict.insert(make_pair("smart","elegant")); dict.insert(make_pair("trait","Merkmal")); dict.insert(make_pair("strange","seltsam")); dict.insert(make_pair("smart","raffiniert")); dict.insert(make_pair("smart","klug")); dict.insert(make_pair("clever","raffiniert")); // print all elements StrStrMMap::iterator pos; cout.setf (ios::left, ios::adjustfield); cout << ' ' << setw(10) << "english " << "german " << endl; cout << setfill('-') << setw(20) << "" << setfill(' ') << endl; for (pos = dict.begin(); pos != dict.end(); ++pos) { cout << ' ' << setw(10) << pos->first.c_str() << pos->second << endl; } cout << endl; // print all values for key "smart" string word("smart"); cout << word << ": " << endl; for (pos = dict.lower_bound(word); pos != dict.upper_bound(word); ++pos) { cout << " " << pos->second << endl; } // print all keys for value "raffiniert" word = ("raffiniert"); cout << word << ": " << endl; for (pos = dict.begin(); pos != dict.end(); ++pos) { if (pos->second == word) { cout << " " << pos->first << endl; } } } ================================================ FILE: stl侯杰源码/cont/mset1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { /* type of the collection: * - duplicates allowed * - elements are integral values * - descending order */ typedef multiset > IntSet; IntSet coll1; // empty multiset container // insert elements in random order coll1.insert(4); coll1.insert(3); coll1.insert(5); coll1.insert(1); coll1.insert(6); coll1.insert(2); coll1.insert(5); // iterate over all elements and print them IntSet::iterator pos; for (pos = coll1.begin(); pos != coll1.end(); ++pos) { cout << *pos << ' '; } cout << endl; // insert 4 again and process return value IntSet::iterator ipos = coll1.insert(4); cout << "4 inserted as element " << distance(coll1.begin(),ipos) + 1 << endl; // assign elements to another multiset with ascending order multiset coll2(coll1.begin(), coll1.end()); // print all elements of the copy copy (coll2.begin(), coll2.end(), ostream_iterator(cout," ")); cout << endl; // remove all elements up to element with value 3 coll2.erase (coll2.begin(), coll2.find(3)); // remove all elements with value 5 int num; num = coll2.erase (5); cout << num << " element(s) removed" << endl; // print all elements copy (coll2.begin(), coll2.end(), ostream_iterator(cout," ")); cout << endl; } ================================================ FILE: stl侯杰源码/cont/newkey.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ namespace MyLib { template inline bool replace_key (Cont& c, const typename Cont::key_type& old_key, const typename Cont::key_type& new_key) { typename Cont::iterator pos; pos = c.find(old_key); if (pos != c.end()) { // insert new element with value of old element c.insert(typename Cont::value_type(new_key, pos->second)); // remove old element c.erase(pos); return true; } else { // key not found return false; } } } ================================================ FILE: stl侯杰源码/cont/pqueue1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { priority_queue q; // insert three elements into the priority queue q.push(66.6); q.push(22.2); q.push(44.4); // read and print two elements cout << q.top() << ' '; q.pop(); cout << q.top() << endl; q.pop(); // insert three more elements q.push(11.1); q.push(55.5); q.push(33.3); // skip one element q.pop(); // pop and print remaining elements while (!q.empty()) { cout << q.top() << ' '; q.pop(); } cout << endl; } ================================================ FILE: stl侯杰源码/cont/print.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include /* PRINT_ELEMENTS() * - prints optional C-string optcstr followed by * - all elements of the collection coll * - separated by spaces */ template inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") { typename T::const_iterator pos; std::cout << optcstr; for (pos=coll.begin(); pos!=coll.end(); ++pos) { std::cout << *pos << ' '; } std::cout << std::endl; } ================================================ FILE: stl侯杰源码/cont/queue1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { queue q; // insert three elements into the queue q.push("These "); q.push("are "); q.push("more than "); // read and print two elements from the queue cout << q.front(); q.pop(); cout << q.front(); q.pop(); // insert two new elements q.push("four "); q.push("words!"); // skip one element q.pop(); // read and print two elements cout << q.front(); q.pop(); cout << q.front() << endl; q.pop(); // print number of elements in the queue cout << "number of elements in the queue: " << q.size() << endl; } ================================================ FILE: stl侯杰源码/cont/queue2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include "Queue.hpp" // use special queue class using namespace std; int main() { try { Queue q; // insert three elements into the queue q.push("These "); q.push("are "); q.push("more than "); // read and print two elements from the queue cout << q.pop(); cout << q.pop(); // push two new elements q.push("four "); q.push("words!"); // skip one element q.pop(); // read and print two elements from the queue cout << q.pop(); cout << q.pop() << endl; // print number of remaining elements cout << "number of elements in the queue: " << q.size() << endl; // read and print one element cout << q.pop() << endl; } catch (const exception& e) { cerr << "EXCEPTION: " << e.what() << endl; } } ================================================ FILE: stl侯杰源码/cont/refsem1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include "countptr.hpp" using namespace std; void printCountedPtr (CountedPtr elem) { cout << *elem << ' '; } int main() { // array of integers (to share in different containers) static int values[] = { 3, 5, 9, 1, 6, 4 }; // two different collections typedef CountedPtr IntPtr; deque coll1; list coll2; /* insert shared objects into the collections * - same order in coll1 * - reverse order in coll2 */ for (int i=0; i #include #include #include using namespace std; int main() { /* type of the collection: * - no duplicates * - elements are integral values * - descending order */ typedef set > IntSet; IntSet coll1; // empty set container // insert elements in random order coll1.insert(4); coll1.insert(3); coll1.insert(5); coll1.insert(1); coll1.insert(6); coll1.insert(2); coll1.insert(5); // iterate over all elements and print them IntSet::iterator pos; for (pos = coll1.begin(); pos != coll1.end(); ++pos) { cout << *pos << ' '; } cout << endl; // insert 4 again and process return value pair status = coll1.insert(4); if (status.second) { cout << "4 inserted as element " << distance(coll1.begin(),status.first) + 1 << endl; } else { cout << "4 already exists" << endl; } // assign elements to another set with ascending order set coll2(coll1.begin(), coll1.end()); // print all elements of the copy copy (coll2.begin(), coll2.end(), ostream_iterator(cout," ")); cout << endl; // remove all elements up to element with value 3 coll2.erase (coll2.begin(), coll2.find(3)); // remove all elements with value 5 int num; num = coll2.erase (5); cout << num << " element(s) removed" << endl; // print all elements copy (coll2.begin(), coll2.end(), ostream_iterator(cout," ")); cout << endl; } ================================================ FILE: stl侯杰源码/cont/set2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main () { set c; c.insert(1); c.insert(2); c.insert(4); c.insert(5); c.insert(6); cout << "lower_bound(3): " << *c.lower_bound(3) << endl; cout << "upper_bound(3): " << *c.upper_bound(3) << endl; cout << "equal_range(3): " << *c.equal_range(3).first << " " << *c.equal_range(3).second << endl; cout << endl; cout << "lower_bound(5): " << *c.lower_bound(5) << endl; cout << "upper_bound(5): " << *c.upper_bound(5) << endl; cout << "equal_range(5): " << *c.equal_range(5).first << " " << *c.equal_range(5).second << endl; } ================================================ FILE: stl侯杰源码/cont/setcmp.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include "print.hpp" using namespace std; // type for sorting criterion template class RuntimeCmp { public: enum cmp_mode {normal, reverse}; private: cmp_mode mode; public: // constructor for sorting criterion // - default criterion uses value normal RuntimeCmp (cmp_mode m=normal) : mode(m) { } // comparison of elements bool operator() (const T& t1, const T& t2) const { return mode == normal ? t1 < t2 : t2 < t1; } // comparison of sorting criteria bool operator== (const RuntimeCmp& rc) { return mode == rc.mode; } }; // type of a set that uses this sorting criterion typedef set > IntSet; // forward declaration void fill (IntSet& set); int main() { // create, fill, and print set with normal element order // - uses default sorting criterion IntSet coll1; fill(coll1); PRINT_ELEMENTS (coll1, "coll1: "); // create sorting criterion with reverse element order RuntimeCmp reverse_order(RuntimeCmp::reverse); // create, fill, and print set with reverse element order IntSet coll2(reverse_order); fill(coll2); PRINT_ELEMENTS (coll2, "coll2: "); // assign elements AND sorting criterion coll1 = coll2; coll1.insert(3); PRINT_ELEMENTS (coll1, "coll1: "); // just to make sure... if (coll1.value_comp() == coll2.value_comp()) { cout << "coll1 and coll2 have same sorting criterion" << endl; } else { cout << "coll1 and coll2 have different sorting criterion" << endl; } } void fill (IntSet& set) { // fill insert elements in random order set.insert(4); set.insert(7); set.insert(5); set.insert(1); set.insert(6); set.insert(2); set.insert(5); } ================================================ FILE: stl侯杰源码/cont/sortset.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; int main() { /* create a string set * - initialized by all words from standard input */ set coll((istream_iterator(cin)), istream_iterator()); // print all elements copy (coll.begin(), coll.end(), ostream_iterator(cout, "\n")); } ================================================ FILE: stl侯杰源码/cont/sortvec.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; int main() { /* create a string vector * - initialized by all words from standard input */ vector coll((istream_iterator(cin)), istream_iterator()); // sort elements sort (coll.begin(), coll.end()); // print all elements ignoring subsequent duplicates unique_copy (coll.begin(), coll.end(), ostream_iterator(cout, "\n")); } ================================================ FILE: stl侯杰源码/cont/stack1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { stack st; // push three elements into the stack st.push(1); st.push(2); st.push(3); // pop and print two elements from the stack cout << st.top() << ' '; st.pop(); cout << st.top() << ' '; st.pop(); // modify top element st.top() = 77; // push two new elements st.push(4); st.push(5); // pop one element without processing it st.pop(); // pop and print remaining elements while (!st.empty()) { cout << st.top() << ' '; st.pop(); } cout << endl; } ================================================ FILE: stl侯杰源码/cont/stack2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "Stack.hpp" // use special stack class using namespace std; int main() { try { Stack st; // push three elements into the stack st.push(1); st.push(2); st.push(3); // pop and print two elements from the stack cout << st.pop() << ' '; cout << st.pop() << ' '; // modify top element st.top() = 77; // push two new elements st.push(4); st.push(5); // pop one element without processing it st.pop(); /* pop and print three elements * - ERROR: one element too many */ cout << st.pop() << ' '; cout << st.pop() << endl; cout << st.pop() << endl; } catch (const exception& e) { cerr << "EXCEPTION: " << e.what() << endl; } } ================================================ FILE: stl侯杰源码/cont/vector1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; int main() { // create empty vector for strings vector sentence; // reserve memory for five elements to avoid reallocation sentence.reserve(5); // append some elements sentence.push_back("Hello,"); sentence.push_back("how"); sentence.push_back("are"); sentence.push_back("you"); sentence.push_back("?"); // print elements separated with spaces copy (sentence.begin(), sentence.end(), ostream_iterator(cout," ")); cout << endl; // print ``technical data'' cout << " max_size(): " << sentence.max_size() << endl; cout << " size(): " << sentence.size() << endl; cout << " capacity(): " << sentence.capacity() << endl; // swap second and fourth element swap (sentence[1], sentence[3]); // insert element "always" before element "?" sentence.insert (find(sentence.begin(),sentence.end(),"?"), "always"); // assign "!" to the last element sentence.back() = "!"; // print elements separated with spaces copy (sentence.begin(), sentence.end(), ostream_iterator(cout," ")); cout << endl; // print ``technical data'' again cout << " max_size(): " << sentence.max_size() << endl; cout << " size(): " << sentence.size() << endl; cout << " capacity(): " << sentence.capacity() << endl; } ================================================ FILE: stl侯杰源码/fo/Makefile ================================================ include ../Makefile.h OUTPROGS = sort1 genera1 genera2 foreach3 removeif \ fopow1 \ compose1 compose2 compose3 compose4 CPPPROGS = memfun1 HEADERS = fopow.hpp compose11.hpp compose12.hpp compose21.hpp \ compose22.hpp compose10.hpp nullary.hpp print.hpp fopow1: fopow.hpp fopow1.cpp $(CXX) $(CXXFLAGS) $(LDFLAGS) $@.cpp -o $@ compose1: print.hpp compose11.hpp compose1.cpp $(CXX) $(CXXFLAGS) $(LDFLAGS) $@.cpp -o $@ compose2: compose21.hpp print.hpp compose2.cpp $(CXX) $(CXXFLAGS) $(LDFLAGS) $@.cpp -o $@ compose3: compose3.cpp compose22.hpp $(CXX) $(CXXFLAGS) $(LDFLAGS) $@.cpp -o $@ ================================================ FILE: stl侯杰源码/fo/compose1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include #include "print.hpp" #include "compose11.hpp" using namespace std; int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll); // for each element add 10 and multiply by 5 transform (coll.begin(),coll.end(), ostream_iterator(cout," "), compose_f_gx(bind2nd(multiplies(),5), bind2nd(plus(),10))); cout << endl; } ================================================ FILE: stl侯杰源码/fo/compose10.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "nullary.hpp" /* class for the compose_f_g adapter */ template class compose_f_g_t : public boost::nullary_function { private: OP1 op1; // process: op1(op2()) OP2 op2; public: // constructor compose_f_g_t(const OP1& o1, const OP2& o2) : op1(o1), op2(o2) { } // function call typename OP1::result_type operator()() const { return op1(op2()); } }; /* convenience function for the compose_f_g adapter */ template inline compose_f_g_t compose_f_g (const OP1& o1, const OP2& o2) { return compose_f_g_t(o1,o2); } ================================================ FILE: stl侯杰源码/fo/compose11.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include /* class for the compose_f_gx adapter */ template class compose_f_gx_t : public std::unary_function { private: OP1 op1; // process: op1(op2(x)) OP2 op2; public: // constructor compose_f_gx_t(const OP1& o1, const OP2& o2) : op1(o1), op2(o2) { } // function call typename OP1::result_type operator()(const typename OP2::argument_type& x) const { return op1(op2(x)); } }; /* convenience function for the compose_f_gx adapter */ template inline compose_f_gx_t compose_f_gx (const OP1& o1, const OP2& o2) { return compose_f_gx_t(o1,o2); } ================================================ FILE: stl侯杰源码/fo/compose12.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include /* class for the compose_f_gxy adapter */ template class compose_f_gxy_t : public std::binary_function { private: OP1 op1; // process: op1(op2(x,y)) OP2 op2; public: // constructor compose_f_gxy_t (const OP1& o1, const OP2& o2) : op1(o1), op2(o2) { } // function call typename OP1::result_type operator()(const typename OP2::first_argument_type& x, const typename OP2::second_argument_type& y) const { return op1(op2(x,y)); } }; /* convenience function for the compose_f_gxy adapter */ template inline compose_f_gxy_t compose_f_gxy (const OP1& o1, const OP2& o2) { return compose_f_gxy_t(o1,o2); } ================================================ FILE: stl侯杰源码/fo/compose2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include "print.hpp" #include "compose21.hpp" using namespace std; int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll); // remove all elements that are greater than four and less than seven // - retain new end vector::iterator pos; pos = remove_if (coll.begin(),coll.end(), compose_f_gx_hx(logical_and(), bind2nd(greater(),4), bind2nd(less(),7))); // remove ``removed'' elements in coll coll.erase(pos,coll.end()); PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/fo/compose21.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include /* class for the compose_f_gx_hx adapter */ template class compose_f_gx_hx_t : public std::unary_function { private: OP1 op1; // process: op1(op2(x),op3(x)) OP2 op2; OP3 op3; public: // constructor compose_f_gx_hx_t (const OP1& o1, const OP2& o2, const OP3& o3) : op1(o1), op2(o2), op3(o3) { } // function call typename OP1::result_type operator()(const typename OP2::argument_type& x) const { return op1(op2(x),op3(x)); } }; /* convenience function for the compose_f_gx_hx adapter */ template inline compose_f_gx_hx_t compose_f_gx_hx (const OP1& o1, const OP2& o2, const OP3& o3) { return compose_f_gx_hx_t(o1,o2,o3); } ================================================ FILE: stl侯杰源码/fo/compose22.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include /* class for the compose_f_gx_hy adapter */ template class compose_f_gx_hy_t : public std::binary_function { private: OP1 op1; // process: op1(op2(x),op3(y)) OP2 op2; OP3 op3; public: // constructor compose_f_gx_hy_t (const OP1& o1, const OP2& o2, const OP3& o3) : op1(o1), op2(o2), op3(o3) { } // function call typename OP1::result_type operator()(const typename OP2::argument_type& x, const typename OP3::argument_type& y) const { return op1(op2(x),op3(y)); } }; /* convenience function for the compose_f_gx_hy adapter */ template inline compose_f_gx_hy_t compose_f_gx_hy (const OP1& o1, const OP2& o2, const OP3& o3) { return compose_f_gx_hy_t(o1,o2,o3); } ================================================ FILE: stl侯杰源码/fo/compose3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include #include "compose22.hpp" using namespace std; int main() { string s("Internationalization"); string sub("Nation"); // search substring case insensitive string::iterator pos; pos = search (s.begin(),s.end(), // string to search in sub.begin(),sub.end(), // substring to search compose_f_gx_hy(equal_to(), // compar. criterion ptr_fun(::toupper), ptr_fun(::toupper))); if (pos != s.end()) { cout << "\"" << sub << "\" is part of \"" << s << "\"" << endl; } } ================================================ FILE: stl侯杰源码/fo/compose4.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include "print.hpp" #include "compose10.hpp" using namespace std; using namespace boost; int main() { list coll; // insert five random numbers generate_n (back_inserter(coll), // beginning of destination range 5, // count rand); // new value generator PRINT_ELEMENTS(coll); // overwrite with five new random numbers // in the range between 0 (including) and 10 (excluding) generate (coll.begin(), coll.end(), // destination range compose_f_g(bind2nd(modulus(),10), ptr_fun(rand))); PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/fo/fopow.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include template struct fopow : public std::binary_function { T1 operator() (T1 base, T2 exp) const { return std::pow(base,exp); } }; ================================================ FILE: stl侯杰源码/fo/fopow1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; // include self-defined fopow<> #include "fopow.hpp" int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // print 3 raised to the power of all elements transform (coll.begin(), coll.end(), // source ostream_iterator(cout," "), // destination bind1st(fopow(),3)); // operation cout << endl; // print all elements raised to the power of 3 transform (coll.begin(), coll.end(), // source ostream_iterator(cout," "), // destination bind2nd(fopow(),3)); // operation cout << endl; } ================================================ FILE: stl侯杰源码/fo/foreach3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; // function object to process the mean value class MeanValue { private: long num; // number of elements long sum; // sum of all element values public: // constructor MeanValue () : num(0), sum(0) { } // ``function call'' // - process one more element of the sequence void operator() (int elem) { num++; // increment count sum += elem; // add value } // return mean value double value () { return static_cast(sum) / static_cast(num); } }; int main() { vector coll; // insert elments from 1 to 8 for (int i=1; i<=8; ++i) { coll.push_back(i); } // process and print mean value MeanValue mv = for_each (coll.begin(), coll.end(), // range MeanValue()); // operation cout << "mean value: " << mv.value() << endl; } ================================================ FILE: stl侯杰源码/fo/genera1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include "print.hpp" using namespace std; class IntSequence { private: int value; public: // constructor IntSequence (int initialValue) : value(initialValue) { } // ``function call'' int operator() () { return value++; } }; int main() { list coll; // insert values from 1 to 9 generate_n (back_inserter(coll), // start 9, // number of elements IntSequence(1)); // generates values PRINT_ELEMENTS(coll); // replace second to last element but one with values starting at 42 generate (++coll.begin(), // start --coll.end(), // end IntSequence(42)); // generates values PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/fo/genera2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include "print.hpp" using namespace std; class IntSequence { private: int value; public: // constructor IntSequence (int initialValue) : value(initialValue) { } // ``function call'' int operator() () { return value++; } }; int main() { list coll; IntSequence seq(1); // integral sequence starting with 1 // insert values from 1 to 4 // - pass function object by reference // so that it will continue with 5 generate_n >, int, IntSequence&>(back_inserter(coll), // start 4, // number of elements seq); // generates values PRINT_ELEMENTS(coll); // insert values from 42 to 45 generate_n (back_inserter(coll), // start 4, // number of elements IntSequence(42)); // generates values PRINT_ELEMENTS(coll); // continue with first sequence // - pass function object by value // so that it will continue with 5 again generate_n (back_inserter(coll), // start 4, // number of elements seq); // generates values PRINT_ELEMENTS(coll); // continue with first sequence again generate_n (back_inserter(coll), // start 4, // number of elements seq); // generates values PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/fo/memfun1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ //#define mem_fun1 mem_fun #include #include #include #include #include class Person { private: std::string name; public: //... void print () const { std::cout << name << std::endl; } void printWithPrefix (std::string prefix) const { std::cout << prefix << name << std::endl; } }; void foo (const std::vector& coll) { using std::for_each; using std::bind2nd; using std::mem_fun_ref; // call member function print() for each element for_each (coll.begin(), coll.end(), mem_fun_ref(&Person::print)); // call member function printWithPrefix() for each element // - "person: " is passed as an argument to the member function for_each (coll.begin(), coll.end(), bind2nd(mem_fun_ref(&Person::printWithPrefix), "person: ")); } void ptrfoo (const std::vector& coll) // ^^^ pointer ! { using std::for_each; using std::bind2nd; using std::mem_fun; // call member function print() for each referred object for_each (coll.begin(), coll.end(), mem_fun(&Person::print)); // call member function printWithPrefix() for each referred object // - "person: " is passed as an argument to the member function for_each (coll.begin(), coll.end(), bind2nd(mem_fun(&Person::printWithPrefix), "person: ")); } int main() { std::vector coll(5); foo(coll); std::vector coll2; coll2.push_back(new Person); ptrfoo(coll2); } ================================================ FILE: stl侯杰源码/fo/nullary.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ namespace boost { /********************************************************** * type nullary_function * - as supplement to unary_function and binary_function **********************************************************/ template struct nullary_function { typedef Result result_type; }; /********************************************************** * ptr_fun for functions with no argument **********************************************************/ template class pointer_to_nullary_function : public nullary_function { protected: Result (*ptr)(); public: pointer_to_nullary_function() { } explicit pointer_to_nullary_function(Result (*x)()) : ptr(x) { } Result operator()() const { return ptr(); } }; template inline pointer_to_nullary_function ptr_fun(Result (*x)()) { return pointer_to_nullary_function(x); } } ================================================ FILE: stl侯杰源码/fo/print.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include /* PRINT_ELEMENTS() * - prints optional C-string optcstr followed by * - all elements of the collection coll * - separated by spaces */ template inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") { typename T::const_iterator pos; std::cout << optcstr; for (pos=coll.begin(); pos!=coll.end(); ++pos) { std::cout << *pos << ' '; } std::cout << std::endl; } ================================================ FILE: stl侯杰源码/fo/removeif.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include "print.hpp" using namespace std; class Nth { // function object that returns true for the nth call private: int nth; // call for which to return true int count; // call counter public: Nth (int n) : nth(n), count(0) { } bool operator() (int) { return ++count == nth; } }; int main() { list coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll,"coll: "); // remove third element list::iterator pos; pos = remove_if(coll.begin(),coll.end(), // range Nth(3)); // remove criterion coll.erase(pos,coll.end()); PRINT_ELEMENTS(coll,"nth removed: "); } ================================================ FILE: stl侯杰源码/fo/sort1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; /* class Person */ class Person { private: string fn; // first name string ln; // last name public: Person() { } Person(const string& f, const string& n) : fn(f), ln(n) { } string firstname() const; string lastname() const; // ... }; inline string Person::firstname() const { return fn; } inline string Person::lastname() const { return ln; } ostream& operator<< (ostream& s, const Person& p) { s << "[" << p.firstname() << " " << p.lastname() << "]"; return s; } /* class for function predicate * - operator () returns whether a person is less than another person */ class PersonSortCriterion { public: bool operator() (const Person& p1, const Person& p2) const { /* a person is less than another person * - if the last name is less * - if the last name is equal and the first name is less */ return p1.lastname() PersonSet; // create such a collection PersonSet coll; coll.insert(p1); coll.insert(p2); coll.insert(p3); coll.insert(p4); coll.insert(p5); coll.insert(p6); coll.insert(p7); // do something with the elements // - in this case: output them cout << "set:" << endl; PersonSet::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { cout << *pos << endl; } } ================================================ FILE: stl侯杰源码/i18n/Makefile ================================================ include ../Makefile.h # Programme fuer die make PROG.out aufgerufen wird # OUTPROGS = loc1 loc2 CPPPROGS = numget ================================================ FILE: stl侯杰源码/i18n/loc1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { // use classic C locale to read data from standard input cin.imbue(locale::classic()); // use a German locale to write data to standard ouput cout.imbue(locale("de_DE")); // read and output floating-point values in a loop double value; while (cin >> value) { cout << value << endl; } } ================================================ FILE: stl侯杰源码/i18n/loc2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { // create the default locale from the user's environment locale langLocale(""); // and assign it to the standard ouput channel cout.imbue(langLocale); // process the name of the locale bool isGerman; if (langLocale.name() == "de_DE" || langLocale.name() == "de" || langLocale.name() == "german") { isGerman = true; } else { isGerman = false; } // read locale for the input if (isGerman) { cout << "Sprachumgebung fuer Eingaben: "; } else { cout << "Locale for input: "; } string s; cin >> s; if (!cin) { if (isGerman) { cerr << "FEHLER beim Einlesen der Sprachumgebung" << endl; } else { cerr << "ERROR while reading the locale" << endl; } return EXIT_FAILURE; } locale cinLocale(s.c_str()); // and assign it to the standard input channel cin.imbue(cinLocale); // read and output floating-point values in a loop double value; while (cin >> value) { cout << value << endl; } } ================================================ FILE: stl侯杰源码/i18n/numget.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include int main() { // create copy of current global locale std::locale loc; // iterator to read from standard input typedef std::istreambuf_iterator InIt; InIt beg = InIt(std::cin); InIt end = InIt(); // stream which defines input format std::ios_base& fmt = std::cin; // declare output arguments std::ios_base::iostate err; float value; // get numeric input facet of the locale loc std::num_get const& ng = std::use_facet >(loc); // read value with numeric input facet ng.get(beg, end, fmt, err, value); // print value or error message if (err == std::ios_base::goodbit) { std::cout << "value: " << value << '\n'; } else if (err == std::ios_base::eofbit) { std::cout << "value: " << value << " (EOF encountered)\n"; } else if (err & std::ios_base::badbit) { std::cerr << "fatal error while reading numeric value\n"; return EXIT_FAILURE; } else if (err & std::ios_base::failbit) { std::cerr << "format error while reading numeric value\n"; return EXIT_FAILURE; } } ================================================ FILE: stl侯杰源码/io/Makefile ================================================ CPPPROGS = io1 sum1 sum2 charcat1 \ ignore1 ignoreparam1 charset \ cat1 cat2 charcat2 \ inbuf1 \ copy1 copy2 \ countlines OUTPROGS = rdbuf1 rdbuf2 redirect \ rw1 sstr1 \ outbuf1 outbuf1x outbuf2 outbuf3 HEADERS = ignore.hpp ignoreparam.hpp \ frac1out.hpp frac2out.hpp frac1in.hpp frac2in.hpp \ outbuf1.hpp outbuf1x.hpp outbuf2.hpp outbuf3.hpp \ inbuf1.hpp include ../Makefile.h outbuf1: outbuf1.hpp outbuf1.cpp $(CXX) $(CXXFLAGS) $@.cpp $(LDFLAGS) -o $@ outbuf1x: outbuf1x.hpp outbuf1x.cpp $(CXX) $(CXXFLAGS) $@.cpp $(LDFLAGS) -o $@ outbuf2: outbuf2.hpp outbuf2.cpp $(CXX) $(CXXFLAGS) $@.cpp $(LDFLAGS) -o $@ outbuf3: outbuf3.hpp outbuf3.cpp $(CXX) $(CXXFLAGS) $@.cpp $(LDFLAGS) -o $@ ignoreparam1: ignoreparam1.cpp ignoreparam.hpp $(CXX) $(CXXFLAGS) $@.cpp $(LDFLAGS) -o $@ ================================================ FILE: stl侯杰源码/io/cat1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ // header files for file I/O #include #include using namespace std; /* for all file names passed as command-line arguments * - open, print contents, and close file */ int main (int argc, char* argv[]) { ifstream file; // for all command-line arguments for (int i=1; i #include void printFileTwice (const char* filename) { // open file std::ifstream file(filename); // print contents the first time std::cout << file.rdbuf(); // seek to the beginning file.seekg(0); // print contents the second time std::cout << file.rdbuf(); } int main (int argc, char* argv[]) { // print all files passed as a command-line argument twice for (int i=1; i using namespace std; int main() { char c; // while it is possible to read a character while (cin.get(c)) { // print it cout.put(c); } } ================================================ FILE: stl侯杰源码/io/charcat2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { // input stream buffer iterator for cin istreambuf_iterator inpos(cin); // end-of-stream iterator istreambuf_iterator endpos; // output stream buffer iterator for cout ostreambuf_iterator outpos(cout); // while input iterator is valid while (inpos != endpos) { *outpos = *inpos; // assign its value to the output iterator ++inpos; ++outpos; } } ================================================ FILE: stl侯杰源码/io/charset.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include // for strings #include // for I/O #include // for file I/O #include // for setw() #include // for exit() using namespace std; // forward declarations void writeCharsetToFile (const string& filename); void outputFile (const string& filename); int main () { writeCharsetToFile("charset.out"); outputFile("charset.out"); } void writeCharsetToFile (const string& filename) { // open output file ofstream file(filename.c_str()); // file opened? if (! file) { // NO, abort program cerr << "can't open output file \"" << filename << "\"" << endl; exit(EXIT_FAILURE); } // write character set for (int i=32; i<256; i++) { file << "value: " << setw(3) << i << " " << "char: " << static_cast(i) << endl; } } // closes file automatically void outputFile (const string& filename) { // open input file ifstream file(filename.c_str()); // file opened? if (! file) { // NO, abort program cerr << "can't open input file \"" << filename << "\"" << endl; exit(EXIT_FAILURE); } // copy file contents to cout char c; while (file.get(c)) { cout.put(c); } } // closes file automatically ================================================ FILE: stl侯杰源码/io/copy1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include int main () { // copy all standard input to standard output std::cout << std::cin.rdbuf(); } ================================================ FILE: stl侯杰源码/io/copy2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include int main () { // copy all standard input to standard output std::cin >> std::noskipws >> std::cout.rdbuf(); } ================================================ FILE: stl侯杰源码/io/countlines.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include int countLines (std::istream& in); int main (int argc, char* argv[]) { int count; if (argc == 1) { // no argument => count lines of standard input count = countLines(std::cin); } else { // count number of lines of all files passed as argument std::ifstream in; count = 0; for (int i=1; i(in), std::istreambuf_iterator(), '\n'); } ================================================ FILE: stl侯杰源码/io/frac1in.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include inline std::istream& operator >> (std::istream& strm, Fraction& f) { int n, d; strm >> n; // read value of the numerator strm.ignore(); // skip '/' strm >> d; // read value of the denominator f = Fraction(n,d); // assign the whole fraction return strm; } ================================================ FILE: stl侯杰源码/io/frac1out.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include inline std::ostream& operator << (std::ostream& strm, const Fraction& f) { strm << f.numerator() << '/' << f.denominator(); return strm; } ================================================ FILE: stl侯杰源码/io/frac2in.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include template inline std::basic_istream& operator >> (std::basic_istream& strm, Fraction& f) { int n, d; // read value of numerator strm >> n; /* if available * - read '/' and value of demonimator */ if (strm.peek() == '/') { strm.ignore(); strm >> d; } else { d = 1; } /* if denominator is zero * - set failbit as I/O format error */ if (d == 0) { strm.setstate(std::ios::failbit); return strm; } /* if everything is fine so far * change the value of the fraction */ if (strm) { f = Fraction(n,d); } return strm; } ================================================ FILE: stl侯杰源码/io/frac2out.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include template inline std::basic_ostream& operator << (std::basic_ostream& strm, const Fraction& f) { /* string stream * - with same format * - without special field width */ std::basic_ostringstream s; s.copyfmt(strm); s.width(0); // fill string stream s << f.numerator() << '/' << f.denominator(); // print string stream strm << s.str(); return strm; } ================================================ FILE: stl侯杰源码/io/ignore.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include template inline std::basic_istream& ignoreLine (std::basic_istream& strm) { // skip until end-of-line strm.ignore(std::numeric_limits::max(),strm.widen('\n')); // return stream for concatenation return strm; } ================================================ FILE: stl侯杰源码/io/ignore1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "ignore.hpp" int main() { int i; std::cout << "read int and ignore rest of the line" << std::endl; std::cin >> i; // ignore the rest of the line std::cin >> ignoreLine; std::cout << "int: " << i << std::endl; std::cout << "read int and ignore two lines" << std::endl; std::cin >> i; // ignore two lines std::cin >> ignoreLine >> ignoreLine; std::cout << "int: " << i << std::endl; } ================================================ FILE: stl侯杰源码/io/ignoreparam.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include // Ignore: manipulator that ignores N lines class Ignore { public: int num; Ignore(int n) : num(n) { } }; // convenience function Ignore ignore(int n) { return Ignore(n); } std::istream& operator >> (std::istream& strm, const Ignore& manip) { for (int i=0; i::max(),'\n'); } return strm; } ================================================ FILE: stl侯杰源码/io/ignoreparam1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "ignoreparam.hpp" int main() { char c; std::cout << "ignore two lines and print frist character following them\n"; std::cin >> ignore(2) >> c; std::cout << "c: " << c << std::endl; } ================================================ FILE: stl侯杰源码/io/inbuf1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "inbuf1.hpp" int main() { inbuf ib; // create special stream buffer std::istream in(&ib); // initialize input stream with that buffer char c; for (int i=1; i<=20; i++) { // read next character (out of the buffer) in.get(c); // print that character (and flush) std::cout << c << std::flush; // after eight characters, put two characters back into the stream if (i == 8) { in.unget(); in.unget(); } } std::cout << std::endl; } ================================================ FILE: stl侯杰源码/io/inbuf1.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include // for read(): #ifdef _MSC_VER # include #else # include #endif class inbuf : public std::streambuf { protected: /* data buffer: * - at most, four characters in putback area plus * - at most, six characters in ordinary read buffer */ static const int bufferSize = 10; // size of the data buffer char buffer[bufferSize]; // data buffer public: /* constructor * - initialize empty data buffer * - no putback area * => force underflow() */ inbuf() { setg (buffer+4, // beginning of putback area buffer+4, // read position buffer+4); // end position } protected: // insert new characters into the buffer virtual int_type underflow () { // is read position before end of buffer? if (gptr() < egptr()) { return traits_type::to_int_type(*gptr()); } /* process size of putback area * - use number of characters read * - but at most four */ int numPutback; numPutback = gptr() - eback(); if (numPutback > 4) { numPutback = 4; } /* copy up to four characters previously read into * the putback buffer (area of first four characters) */ std::memmove (buffer+(4-numPutback), gptr()-numPutback, numPutback); // read new characters int num; num = read (0, buffer+4, bufferSize-4); if (num <= 0) { // ERROR or EOF return EOF; } // reset buffer pointers setg (buffer+(4-numPutback), // beginning of putback area buffer+4, // read position buffer+4+num); // end of buffer // return next character return traits_type::to_int_type(*gptr()); } }; ================================================ FILE: stl侯杰源码/io/io1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { double x, y; // operands // print header string cout << "Multiplication of two floating point values" << endl; // read first operand cout << "first operand: "; if (! (cin >> x)) { /* input error * => error message and exit program with error status */ cerr << "error while reading the first floating value" << endl; return EXIT_FAILURE; } // read second operand cout << "second operand: "; if (! (cin >> y)) { /* input error * => error message and exit program with error status */ cerr << "error while reading the second floating value" << endl; return EXIT_FAILURE; } // print operands and result cout << x << " times " << y << " equals " << x * y << endl; } ================================================ FILE: stl侯杰源码/io/outbuf1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "outbuf1.hpp" int main() { outbuf ob; // create special output buffer std::ostream out(&ob); // initialize output stream with that output buffer out << "31 hexadecimal: " << std::hex << 31 << std::endl; } ================================================ FILE: stl侯杰源码/io/outbuf1.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include class outbuf : public std::streambuf { protected: /* central output function * - print characters in uppercase mode */ virtual int_type overflow (int_type c) { if (c != EOF) { // convert lowercase to uppercase c = std::toupper(c,getloc()); // and write the character to the standard output if (putchar(c) == EOF) { return EOF; } } return c; } }; ================================================ FILE: stl侯杰源码/io/outbuf1x.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "outbuf1x.hpp" int main() { outbuf ob; // create special output buffer std::ostream out(&ob); // initialize output stream with that output buffer out << "31 hexadecimal: " << std::hex << 31 << std::endl; } ================================================ FILE: stl侯杰源码/io/outbuf1x.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include template > class basic_outbuf : public std::basic_streambuf { protected: /* central output function * - print characters in uppercase mode */ virtual typename traits::int_type overflow (typename traits::int_type c) { if (!traits::eq_int_type(c,traits::eof())) { // convert lowercase to uppercase c = std::toupper(c,getloc()); // and write the character to the standard output if (putchar(c) == EOF) { return traits::eof(); } } return traits::not_eof(c); } }; typedef basic_outbuf outbuf; typedef basic_outbuf woutbuf; ================================================ FILE: stl侯杰源码/io/outbuf2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "outbuf2.hpp" int main() { fdostream out(1); // stream with buffer writing to file descriptor 1 out << "31 hexadecimal: " << std::hex << 31 << std::endl; } ================================================ FILE: stl侯杰源码/io/outbuf2.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include // for write(): #ifdef _MSC_VER # include #else # include #endif class fdoutbuf : public std::streambuf { protected: int fd; // file descriptor public: // constructor fdoutbuf (int _fd) : fd(_fd) { } protected: // write one character virtual int_type overflow (int_type c) { if (c != EOF) { char z = c; if (write (fd, &z, 1) != 1) { return EOF; } } return c; } // write multiple characters virtual std::streamsize xsputn (const char* s, std::streamsize num) { return write(fd,s,num); } }; class fdostream : public std::ostream { protected: fdoutbuf buf; public: fdostream (int fd) : std::ostream(0), buf(fd) { rdbuf(&buf); } }; ================================================ FILE: stl侯杰源码/io/outbuf3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "outbuf3.hpp" int main() { outbuf ob; // create special output buffer std::ostream out(&ob); // initialize output stream with that output buffer out << "31 hexadecimal: " << std::hex << 31 << std::endl; } ================================================ FILE: stl侯杰源码/io/outbuf3.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include // for write(): #ifdef _MSC_VER # include #else # include #endif class outbuf : public std::streambuf { protected: static const int bufferSize = 10; // size of data buffer char buffer[bufferSize]; // data buffer public: /* constructor * - initialize data buffer * - one character less to let the bufferSizeth character * cause a call of overflow() */ outbuf() { setp (buffer, buffer+(bufferSize-1)); } /* destructor * - flush data buffer */ virtual ~outbuf() { sync(); } protected: // flush the characters in the buffer int flushBuffer () { int num = pptr()-pbase(); if (write (1, buffer, num) != num) { return EOF; } pbump (-num); // reset put pointer accordingly return num; } /* buffer full * - write c and all previous characters */ virtual int_type overflow (int_type c) { if (c != EOF) { // insert character into the buffer *pptr() = c; pbump(1); } // flush the buffer if (flushBuffer() == EOF) { // ERROR return EOF; } return c; } /* synchronize data with file/destination * - flush the data in the buffer */ virtual int sync () { if (flushBuffer() == EOF) { // ERROR return -1; } return 0; } }; ================================================ FILE: stl侯杰源码/io/rdbuf1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { // stream for hexadecimal standard output ostream hexout(cout.rdbuf()); hexout.setf (ios::hex, ios::basefield); hexout.setf (ios::showbase); // switch between decimal and hexadecimal output hexout << "hexout: " << 177 << " "; cout << "cout: " << 177 << " "; hexout << "hexout: " << -49 << " "; cout << "cout: " << -49 << " "; hexout << endl; } ================================================ FILE: stl侯杰源码/io/rdbuf2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include void hexMultiplicationTable (std::streambuf* buffer, int num) { std::ostream hexout(buffer); hexout << std::hex << std::showbase; for (int i=1; i<=num; ++i) { for (int j=1; j<=10; ++j) { hexout << i*j << ' '; } hexout << std::endl; } } // does NOT close buffer int main() { using namespace std; int num = 5; cout << "We print " << num << " lines hexadecimal" << endl; hexMultiplicationTable(cout.rdbuf(),num); cout << "That was the output of " << num << " hexadecimal lines " << endl; } ================================================ FILE: stl侯杰源码/io/redirect.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; void redirect(ostream&); int main() { cout << "the first row" << endl; redirect(cout); cout << "the last row" << endl; } void redirect (ostream& strm) { ofstream file("redirect.txt"); // save output buffer of the stream streambuf* strm_buffer = strm.rdbuf(); // redirect ouput into the file strm.rdbuf (file.rdbuf()); file << "one row for the file" << endl; strm << "one row for the stream" << endl; // restore old output buffer strm.rdbuf (strm_buffer); } // closes file AND its buffer automatically ================================================ FILE: stl侯杰源码/io/rw1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { // open file ``example.dat'' for reading and writing filebuf buffer; ostream output(&buffer); istream input(&buffer); buffer.open ("example.dat", ios::in | ios::out | ios::trunc); for (int i=1; i<=4; i++) { // write one line output << i << ". line" << endl; // print all file contents input.seekg(0); // seek to the beginning char c; while (input.get(c)) { cout.put(c); } cout << endl; input.clear(); // clear eofbit and failbit } } ================================================ FILE: stl侯杰源码/io/sstr1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { ostringstream os; // decimal and hexadecimal value os << "dec: " << 15 << hex << " hex: " << 15 << endl; cout << os.str() << endl; // append floating value and bitset bitset<15> b(5789); os << "float: " << 4.67 << " bitset: " << b << endl; // overwrite with octal value os.seekp(0); os << "oct: " << oct << 15; cout << os.str() << endl; } ================================================ FILE: stl侯杰源码/io/sum1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include namespace MyLib { double readAndProcessSum (std::istream&); } int main() { using namespace std; double sum; try { sum = MyLib::readAndProcessSum(cin); } catch (const ios::failure& error) { cerr << "I/O exception: " << error.what() << endl; return EXIT_FAILURE; } catch (const exception& error) { cerr << "standard exception: " << error.what() << endl; return EXIT_FAILURE; } catch (...) { cerr << "unknown exception" << endl; return EXIT_FAILURE; } // print sum cout << "sum: " << sum << endl; } #include namespace MyLib { double readAndProcessSum (std::istream& strm) { using std::ios; double value, sum; // save current state of exception flags ios::iostate oldExceptions = strm.exceptions(); /* let failbit and badbit throw exceptions * - NOTE: failbit is also set at end-of-file */ strm.exceptions (ios::failbit | ios::badbit); try { /* while stream is OK * - read value and add it to sum */ sum = 0; while (strm >> value) { sum += value; } } catch (...) { /* if exception not caused by end-of-file * - restore old state of exception flags * - rethrow exception */ if (!strm.eof()) { strm.exceptions(oldExceptions); // restore exception flags throw; // rethrow } } // restore old state of exception flags strm.exceptions (oldExceptions); // return sum return sum; } } ================================================ FILE: stl侯杰源码/io/sum2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include namespace MyLib { double readAndProcessSum (std::istream&); } int main() { using namespace std; double sum; try { sum = MyLib::readAndProcessSum(cin); } catch (const ios::failure& error) { cerr << "I/O exception: " << error.what() << endl; return EXIT_FAILURE; } catch (const exception& error) { cerr << "standard exception: " << error.what() << endl; return EXIT_FAILURE; } catch (...) { cerr << "unknown exception" << endl; return EXIT_FAILURE; } // print sum cout << "sum: " << sum << endl; } #include namespace MyLib { double readAndProcessSum (std::istream& strm) { double value, sum; /* while stream is OK * - read value and add it to sum */ sum = 0; while (strm >> value) { sum += value; } if (!strm.eof()) { throw std::ios::failure ("input error in readAndProcessSum()"); } // return sum return sum; } } ================================================ FILE: stl侯杰源码/iter/Makefile ================================================ OUTPROGS = itercat advance1 distance swap1 \ reviter1 reviter2 reviter3 reviter4 \ backins frontins inserter \ ostriter \ assoiter CPPPROGS = istriter advance2 HEADERS = distance.hpp assoiter.hpp print.hpp EXPORT = istriter.in advance2.in include ../Makefile.h assoiter: assoiter.hpp assoiter.cpp $(CXX) $(CXXFLAGS) $(LDFLAGS) $@.cpp -o $@ ================================================ FILE: stl侯杰源码/iter/advance1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { list coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } list::iterator pos = coll.begin(); // print actual element cout << *pos << endl; // step three elements forward advance (pos, 3); // print actual element cout << *pos << endl; // step one element backward advance (pos, -1); // print actual element cout << *pos << endl; } ================================================ FILE: stl侯杰源码/iter/advance2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { istream_iterator cinPos(cin); ostream_iterator coutPos(cout," "); /* while input is not at the end of the file * - write every third string */ while (cinPos != istream_iterator()) { // ignore the following two strings advance (cinPos, 2); // read and write the third string if (cinPos != istream_iterator()) { *coutPos++ = *cinPos++; } } cout << endl; } ================================================ FILE: stl侯杰源码/iter/assoiter.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; #include "print.hpp" #include "assoiter.hpp" int main() { set coll; // create inserter for coll // - inconvenient way asso_insert_iterator > iter(coll); // insert elements with the usual iterator interface *iter = 1; iter++; *iter = 2; iter++; *iter = 3; PRINT_ELEMENTS(coll); // create inserter for coll and insert elements // - convenient way asso_inserter(coll) = 44; asso_inserter(coll) = 55; PRINT_ELEMENTS(coll); // use inserter with an algorithm int vals[] = { 33, 67, -4, 13, 5, 2 }; copy (vals, vals+(sizeof(vals)/sizeof(vals[0])), // source asso_inserter(coll)); // destination PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/iter/assoiter.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include /* template class for insert iterator for associative containers */ template class asso_insert_iterator : public std::iterator { protected: Container& container; // container in which elements are inserted public: // constructor explicit asso_insert_iterator (Container& c) : container(c) { } // assignment operator // - inserts a value into the container asso_insert_iterator& operator= (const typename Container::value_type& value) { container.insert(value); return *this; } // dereferencing is a no-op that returns the iterator itself asso_insert_iterator& operator* () { return *this; } // increment operation is a no-op that returns the iterator itself asso_insert_iterator& operator++ () { return *this; } asso_insert_iterator& operator++ (int) { return *this; } }; /* convenience function to create the inserter */ template inline asso_insert_iterator asso_inserter (Container& c) { return asso_insert_iterator(c); } ================================================ FILE: stl侯杰源码/iter/backins.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include "print.hpp" using namespace std; int main() { vector coll; // create back inserter for coll // - inconvenient way back_insert_iterator > iter(coll); // insert elements with the usual iterator interface *iter = 1; iter++; *iter = 2; iter++; *iter = 3; PRINT_ELEMENTS(coll); // create back inserter and insert elements // - convenient way back_inserter(coll) = 44; back_inserter(coll) = 55; PRINT_ELEMENTS(coll); // use back inserter to append all elements again // - reserve enough memory to avoid reallocation coll.reserve(2*coll.size()); copy (coll.begin(), coll.end(), // source back_inserter(coll)); // destination PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/iter/distance.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { list coll; // insert elements from -3 to 9 for (int i=-3; i<=9; ++i) { coll.push_back(i); } // search element with value 5 list::iterator pos; pos = find (coll.begin(), coll.end(), // range 5); // value if (pos != coll.end()) { // process and print difference from the beginning cout << "difference between beginning and 5: " << distance(coll.begin(),pos) << endl; } else { cout << "5 not found" << endl; } } ================================================ FILE: stl侯杰源码/iter/distance.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ template inline long distance (Iterator pos1, Iterator pos2) { long d = 0; distance (pos1, pos2, d); return d; } ================================================ FILE: stl侯杰源码/iter/frontins.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include "print.hpp" using namespace std; int main() { list coll; // create front inserter for coll // - inconvenient way front_insert_iterator > iter(coll); // insert elements with the usual iterator interface *iter = 1; iter++; *iter = 2; iter++; *iter = 3; PRINT_ELEMENTS(coll); // create front inserter and insert elements // - convenient way front_inserter(coll) = 44; front_inserter(coll) = 55; PRINT_ELEMENTS(coll); // use front inserter to insert all elements again copy (coll.begin(), coll.end(), // source front_inserter(coll)); // destination PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/iter/inserter.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include "print.hpp" using namespace std; int main() { set coll; // create insert iterator for coll // - inconvenient way insert_iterator > iter(coll,coll.begin()); // insert elements with the usual iterator interface *iter = 1; iter++; *iter = 2; iter++; *iter = 3; PRINT_ELEMENTS(coll,"set: "); // create inserter and insert elements // - convenient way inserter(coll,coll.end()) = 44; inserter(coll,coll.end()) = 55; PRINT_ELEMENTS(coll,"set: "); // use inserter to insert all elements into a list list coll2; copy (coll.begin(), coll.end(), // source inserter(coll2,coll2.begin())); // destination PRINT_ELEMENTS(coll2,"list: "); // use inserter to reinsert all elements into the list before the second element copy (coll.begin(), coll.end(), // source inserter(coll2,++coll2.begin())); // destination PRINT_ELEMENTS(coll2,"list: "); } ================================================ FILE: stl侯杰源码/iter/istriter.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { // create istream iterator that reads integers from cin istream_iterator intReader(cin); // create end-of-stream iterator istream_iterator intReaderEOF; /* while able to read tokens with istream iterator * - write them twice */ while (intReader != intReaderEOF) { cout << "once: " << *intReader << endl; cout << "once again: " << *intReader << endl; ++intReader; } } ================================================ FILE: stl侯杰源码/iter/itercat.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { vector coll; // insert elements from -3 to 9 for (int i=-3; i<=9; ++i) { coll.push_back (i); } /* print number of elements by processing the distance between beginning and end * - NOTE: uses operator - for iterators */ cout << "number/distance: " << coll.end()-coll.begin() << endl; /* print all elements * - NOTE: uses operator < instead of operator != */ vector::iterator pos; for (pos=coll.begin(); pos #include #include #include using namespace std; int main() { // create ostream iterator for stream cout // - values are separated by a newline character ostream_iterator intWriter(cout,"\n"); // write elements with the usual iterator interface *intWriter = 42; intWriter++; *intWriter = 77; intWriter++; *intWriter = -5; // create collection with elements from 1 to 9 vector coll; for (int i=1; i<=9; ++i) { coll.push_back(i); } // write all elements without any delimiter copy (coll.begin(), coll.end(), ostream_iterator(cout)); cout << endl; // write all elements with " < " as delimiter copy (coll.begin(), coll.end(), ostream_iterator(cout," < ")); cout << endl; } ================================================ FILE: stl侯杰源码/iter/print.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include /* PRINT_ELEMENTS() * - prints optional C-string optcstr followed by * - all elements of the collection coll * - separated by spaces */ template inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") { typename T::const_iterator pos; std::cout << optcstr; for (pos=coll.begin(); pos!=coll.end(); ++pos) { std::cout << *pos << ' '; } std::cout << std::endl; } ================================================ FILE: stl侯杰源码/iter/reviter1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; void print (int elem) { cout << elem << ' '; } int main() { list coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // print all elements in normal order for_each (coll.begin(), coll.end(), // range print); // operation cout << endl; // print all elements in reverse order for_each (coll.rbegin(), coll.rend(), // range print); // operations cout << endl; } ================================================ FILE: stl侯杰源码/iter/reviter2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // find position of element with value 5 vector::iterator pos; pos = find (coll.begin(), coll.end(), 5); // print value to which iterator pos refers cout << "pos: " << *pos << endl; // convert iterator to reverse iterator rpos vector::reverse_iterator rpos(pos); // print value to which reverse iterator rpos refers cout << "rpos: " << *rpos << endl; } ================================================ FILE: stl侯杰源码/iter/reviter3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; void print (int elem) { cout << elem << ' '; } int main() { deque coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // find position of element with value 2 deque::iterator pos1; pos1 = find (coll.begin(), coll.end(), // range 2); // value // find position of element with value 7 deque::iterator pos2; pos2 = find (coll.begin(), coll.end(), // range 7); // value // print all elements in range [pos1,pos2) for_each (pos1, pos2, // range print); // operation cout << endl; // convert iterators to reverse iterators deque::reverse_iterator rpos1(pos1); deque::reverse_iterator rpos2(pos2); // print all elements in range [pos1,pos2) in reverse order for_each (rpos2, rpos1, // range print); // operation cout << endl; } ================================================ FILE: stl侯杰源码/iter/reviter4.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { list coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // find position of element with value 5 list::iterator pos; pos = find (coll.begin(), coll.end(), // range 5); // value // print value of the element cout << "pos: " << *pos << endl; // convert iterator to reverse iterator list::reverse_iterator rpos(pos); // print value of the element to which the reverse iterator refers cout << "rpos: " << *rpos << endl; // convert reverse iterator back to normal iterator list::iterator rrpos; rrpos = rpos.base(); // print value of the element to which the normal iterator refers cout << "rrpos: " << *rrpos << endl; } ================================================ FILE: stl侯杰源码/iter/swap1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include "print.hpp" using namespace std; int main() { list coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll); // swap first and second value iter_swap (coll.begin(), ++coll.begin()); PRINT_ELEMENTS(coll); // swap first and last value iter_swap (coll.begin(), --coll.end()); PRINT_ELEMENTS(coll); } ================================================ FILE: stl侯杰源码/memory/Makefile ================================================ include ../Makefile.h OUTPROGS = myalloc1 HEADERS = myalloc.hpp uninit.o: uninit_fill.cpp uninit_fill_n.cpp uninit_copy.cpp \ allocvoid.cpp defalloc.cpp ================================================ FILE: stl侯杰源码/memory/myalloc.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include namespace MyLib { template class MyAlloc { public: // type definitions typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; // rebind allocator to type U template struct rebind { typedef MyAlloc other; }; // return address of values pointer address (reference value) const { return &value; } const_pointer address (const_reference value) const { return &value; } /* constructors and destructor * - nothing to do because the allocator has no state */ MyAlloc() throw() { } MyAlloc(const MyAlloc&) throw() { } template MyAlloc (const MyAlloc&) throw() { } ~MyAlloc() throw() { } // return maximum number of elements that can be allocated size_type max_size () const throw() { return std::numeric_limits::max() / sizeof(T); } // allocate but don't initialize num elements of type T pointer allocate (size_type num, const void* = 0) { // print message and allocate memory with global new std::cerr << "allocate " << num << " element(s)" << " of size " << sizeof(T) << std::endl; pointer ret = (pointer)(::operator new(num*sizeof(T))); std::cerr << " allocated at: " << (void*)ret << std::endl; return ret; } // initialize elements of allocated storage p with value value void construct (pointer p, const T& value) { // initialize memory with placement new new((void*)p)T(value); } // destroy elements of initialized storage p void destroy (pointer p) { // destroy objects by calling their destructor p->~T(); } // deallocate storage p of deleted elements void deallocate (pointer p, size_type num) { // print message and deallocate memory with global delete std::cerr << "deallocate " << num << " element(s)" << " of size " << sizeof(T) << " at: " << (void*)p << std::endl; ::operator delete((void*)p); } }; // return that all specializations of this allocator are interchangeable template bool operator== (const MyAlloc&, const MyAlloc&) throw() { return true; } template bool operator!= (const MyAlloc&, const MyAlloc&) throw() { return false; } } ================================================ FILE: stl侯杰源码/memory/myalloc1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include "myalloc.hpp" int main() { // create a vector, using MyAlloc<> as allocator std::vector > v; // insert elements // - causes reallocations v.push_back(42); v.push_back(56); v.push_back(11); v.push_back(22); v.push_back(33); v.push_back(44); } ================================================ FILE: stl侯杰源码/num/Makefile ================================================ include ../Makefile.h CPPPROGS = \ complex2 OUTPROGS = \ complex1 \ val1 val2 slice1 gslice1 masked1 indi1 OTHERS = complextests valtests ================================================ FILE: stl侯杰源码/num/complex1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { /* complex number with real and imaginary parts * - real part: 4.0 * - imaginary part: 3.0 */ complex c1(4.0,3.0); /* create complex number from polar coordinates * - magnitude: 5.0 * - phase angle: 0.75 */ complex c2(polar(5.0,0.75)); // print complex numbers with real and imaginary parts cout << "c1: " << c1 << endl; cout << "c2: " << c2 << endl; // print complex numbers as polar coordinates cout << "c1: magnitude: " << abs(c1) << " (squared magnitude: " << norm(c1) << ") " << " phase angle: " << arg(c1) << endl; cout << "c2: magnitude: " << abs(c2) << " (squared magnitude: " << norm(c2) << ") " << " phase angle: " << arg(c2) << endl; // print complex conjugates cout << "c1 conjugated: " << conj(c1) << endl; cout << "c2 conjugated: " << conj(c2) << endl; // print result of a computation cout << "4.4 + c1 * 1.8: " << 4.4 + c1 * 1.8 << endl; /* print sum of c1 and c2: * - note: different types */ cout << "c1 + c2: " << c1 + complex(c2.real(),c2.imag()) << endl; // add square root of c1 to c1 and print the result cout << "c1 += sqrt(c1): " << (c1 += sqrt(c1)) << endl; } ================================================ FILE: stl侯杰源码/num/complex2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { complex c1, c2; while (cin.peek() != EOF) { // read first complex number cout << "complex number c1: "; cin >> c1; if (!cin) { cerr << "input error" << endl; return EXIT_FAILURE; } // read second complex number cout << "complex number c2: "; cin >> c2; if (!cin) { cerr << "input error" << endl; return EXIT_FAILURE; } if (c1 == c2) { cout << "c1 and c2 are equal !" << endl; } cout << "c1 raised to the c2: " << pow(c1,c2) << endl << endl; // skip rest of line cin.ignore(numeric_limits::max(),'\n'); } } ================================================ FILE: stl侯杰源码/num/gslice1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; // print three-dimensional valarray line-by-line template void printValarray3D (const valarray& va, int dim1, int dim2) { for (int i=0; i va(24); // fill valarray with values for (int i=0; i<24; i++) { va[i] = i; } // print valarray printValarray3D (va, 3, 4); // we need two two-dimensional subsets of three times 3 values // in two 12-element arrays size_t lengthvalues[] = { 2, 3 }; size_t stridevalues[] = { 12, 3 }; valarray length(lengthvalues,2); valarray stride(stridevalues,2); // assign the second column of the first three rows // to the first column of the first three rows va[gslice(0,length,stride)] = valarray(va[gslice(1,length,stride)]); // add and assign the third of the first three rows // to the first of the first three rows va[gslice(0,length,stride)] += valarray(va[gslice(2,length,stride)]); // print valarray printValarray3D (va, 3, 4); } ================================================ FILE: stl侯杰源码/num/indi1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; // print valarray as two-dimensional array template void printValarray (const valarray& va, int num) { for (int i=0; i va(12); // initialize valarray by values 1.01, 2.02, ... 12.12 for (int i=0; i<12; i++) { va[i] = (i+1) * 1.01; } printValarray(va,4); /* create array of indexes * - note: element type has to be size_t */ valarray idx(4); idx[0] = 8; idx[1] = 0; idx[2] = 3; idx[3] = 7; // use array of indexes to print the ninth, first, fourth, and eighth elements printValarray(valarray(va[idx]), 4); // change the first and fourth elements and print them again indirectly va[0] = 11.11; va[3] = 44.44; printValarray(valarray(va[idx]), 4); // now select the second, third, sixth, and ninth elements // and assign 99 to them idx[0] = 1; idx[1] = 2; idx[2] = 5; idx[3] = 8; va[idx] = 99; // print the whole valarray again printValarray (va, 4); } ================================================ FILE: stl侯杰源码/num/masked1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; // print valarray line-by-line template void printValarray (const valarray& va, int num) { for (int i=0; i va(12); // fill valarray with values for (int i=0; i<12; i++) { va[i] = i; } printValarray (va, 3); // assign 77 to all values that are less than 5 va[va<5.0] = 77.0; // add 100 to all values that are greater than 5 and less than 9 va[va>5.0 && va<9.0] = valarray(va[va>5.0 && va<9.0]) + 100.0; printValarray (va, 3); } ================================================ FILE: stl侯杰源码/num/slice1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; // print valarray line-by-line template void printValarray (const valarray& va, int num) { for (int i=0; i va(12); // fill valarray with values for (int i=0; i<12; i++) { va[i] = i; } printValarray (va, 3); // first column = second column raised to the third column va[slice(0,4,3)] = pow (valarray(va[slice(1,4,3)]), valarray(va[slice(2,4,3)])); printValarray (va, 3); // create valarray with three times the third element of va valarray vb(va[slice(2,4,0)]); // multiply the third column by the elements of vb va[slice(2,4,3)] *= vb; printValarray (va, 3); // print the square root of the elements in the second row printValarray (sqrt(valarray(va[slice(3,3,1)]))); // double the elements in the third row va[slice(2,4,3)] = valarray(va[slice(2,4,3)]) * 2.0; printValarray (va, 3); } ================================================ FILE: stl侯杰源码/num/val1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; // print valarray template void printValarray (const valarray& va) { for (int i=0; i va1(10), va2(10); // assign values 0.0, 1.1, up to 9.9 to the first valarray for (int i=0; i<10; i++) { va1[i] = i * 1.1; } // assign -1 to all elements of the second valarray va2 = -1; // print both valarrays printValarray(va1); printValarray(va2); // print minimum, maximum, and sum of the first valarray cout << "min(): " << va1.min() << endl; cout << "max(): " << va1.max() << endl; cout << "sum(): " << va1.sum() << endl; // assign values of the first to the second valarray va2 = va1; // remove all elements of the first valarray va1.resize(0); // print both valarrays again printValarray(va1); printValarray(va2); } ================================================ FILE: stl侯杰源码/num/val2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; // print valarray template void printValarray (const valarray& va) { for (int i=0; i va(9); for (int i=0; i vb(va+10.0); // print second valarray printValarray(vb); // create third valarray as a result of processing both existing valarrays valarray vc(9); vc = sqrt(va) + vb/2.0 - 1.0; // print third valarray printValarray(vc); } ================================================ FILE: stl侯杰源码/stl/Makefile ================================================ include ../Makefile.h OUTPROGS = vector1 deque1 list1 set1 \ mmap1 map1 algo1 riter1 \ remove1 remove2 remove3 \ foreach1 transform1 prime1 \ sort1 fo1 CPPPROGS = list2 find1 copy1 copy2 copy3 ioiter1 \ remove4 foreach2 add1 iterbug1 HEADERS = print.hpp ================================================ FILE: stl侯杰源码/stl/add1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include "print.hpp" using namespace std; // function object that adds the value with which it is initialized class AddValue { private: int theValue; // the value to add public: // constructor initializes the value to add AddValue(int v) : theValue(v) { } // the ``function call'' for the element adds the value void operator() (int& elem) const { elem += theValue; } }; int main() { list coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll,"initialized: "); // add value 10 to each element for_each (coll.begin(), coll.end(), // range AddValue(10)); // operation PRINT_ELEMENTS(coll,"after adding 10: "); // add value of first element to each element for_each (coll.begin(), coll.end(), // range AddValue(*coll.begin())); // operation PRINT_ELEMENTS(coll,"after adding first element: "); } ================================================ FILE: stl侯杰源码/stl/algo1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { vector coll; vector::iterator pos; // insert elements from 1 to 6 in arbitrary order coll.push_back(2); coll.push_back(5); coll.push_back(4); coll.push_back(1); coll.push_back(6); coll.push_back(3); // find and print minimum and maximum elements pos = min_element (coll.begin(), coll.end()); cout << "min: " << *pos << endl; pos = max_element (coll.begin(), coll.end()); cout << "max: " << *pos << endl; // sort all elements sort (coll.begin(), coll.end()); // find the first element with value 3 pos = find (coll.begin(), coll.end(), // range 3); // value // reverse the order of the found element with value 3 and all following elements reverse (pos, coll.end()); // print all elements for (pos=coll.begin(); pos!=coll.end(); ++pos) { cout << *pos << ' '; } cout << endl; } ================================================ FILE: stl侯杰源码/stl/copy1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { list coll1; vector coll2; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll1.push_back(i); } // RUNTIME ERROR: // - overwrites nonexisting elements in the destination copy (coll1.begin(), coll1.end(), // source coll2.begin()); // destination //... } ================================================ FILE: stl侯杰源码/stl/copy2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; int main() { list coll1; vector coll2; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll1.push_back(i); } // resize destination to have enough room for the overwriting algorithm coll2.resize (coll1.size()); /* copy elements from first into second collection * - overwrites existing elements in destination */ copy (coll1.begin(), coll1.end(), // source coll2.begin()); // destination /* create third collection with enough room * - initial size is passed as parameter */ deque coll3(coll1.size()); // copy elements from first into third collection copy (coll1.begin(), coll1.end(), // source coll3.begin()); // destination } ================================================ FILE: stl侯杰源码/stl/copy3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include #include using namespace std; int main() { list coll1; // insert elements from 1 to 9 into the first collection for (int i=1; i<=9; ++i) { coll1.push_back(i); } // copy the elements of coll1 into coll2 by appending them vector coll2; copy (coll1.begin(), coll1.end(), // source back_inserter(coll2)); // destination // copy the elements of coll1 into coll3 by inserting them at the front // - reverses the order of the elements deque coll3; copy (coll1.begin(), coll1.end(), // source front_inserter(coll3)); // destination // copy elements of coll1 into coll4 // - only inserter that works for associative collections set coll4; copy (coll1.begin(), coll1.end(), // source inserter(coll4,coll4.begin())); // destination } ================================================ FILE: stl侯杰源码/stl/deque1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { deque coll; // deque container for floating-point elements // insert elements from 1.1 to 6.6 each at the front for (int i=1; i<=6; ++i) { coll.push_front(i*1.1); // insert at the front } // print all elements followed by a space for (int i=0; i #include #include using namespace std; int main() { list coll; list::iterator pos; // insert elements from 20 to 40 for (int i=20; i<=40; ++i) { coll.push_back(i); } /* find position of element with value 3 * - there is none, so pos gets coll.end() */ pos = find (coll.begin(), coll.end(), // range 3); // value /* reverse the order of elements between found element and the end * - because pos is coll.end() it reverses an empty range */ reverse (pos, coll.end()); // find positions of values 25 and 35 list::iterator pos25, pos35; pos25 = find (coll.begin(), coll.end(), // range 25); // value pos35 = find (coll.begin(), coll.end(), // range 35); // value /* print the maximum of the corresponding range * - note: including pos25 but excluding pos35 */ cout << "max: " << *max_element (pos25, pos35) << endl; // process the elements including the last position cout << "max: " << *max_element (pos25, ++pos35) << endl; } ================================================ FILE: stl侯杰源码/stl/fo1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include "print.hpp" using namespace std; int main() { set > coll1; deque coll2; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll1.insert(i); } PRINT_ELEMENTS(coll1,"initialized: "); // transform all elements into coll2 by multiplying 10 transform (coll1.begin(),coll1.end(), // source back_inserter(coll2), // destination bind2nd(multiplies(),10)); // operation PRINT_ELEMENTS(coll2,"transformed: "); // replace value equal to 70 with 42 replace_if (coll2.begin(),coll2.end(), // range bind2nd(equal_to(),70), // replace criterion 42); // new value PRINT_ELEMENTS(coll2,"replaced: "); // remove all elements with values less than 50 coll2.erase(remove_if(coll2.begin(),coll2.end(), // range bind2nd(less(),50)), // remove criterion coll2.end()); PRINT_ELEMENTS(coll2,"removed: "); } ================================================ FILE: stl侯杰源码/stl/foreach1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; // function that prints the passed argument void print (int elem) { cout << elem << ' '; } int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // print all elements for_each (coll.begin(), coll.end(), // range print); // operation cout << endl; } ================================================ FILE: stl侯杰源码/stl/foreach2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; // simple function object that prints the passed argument class PrintInt { public: void operator() (int elem) const { cout << elem << ' '; } }; int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // print all elements for_each (coll.begin(), coll.end(), // range PrintInt()); // operation cout << endl; } ================================================ FILE: stl侯杰源码/stl/ioiter1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; int main() { vector coll; /* read all words from the standard input * - source: all strings until end-of-file (or error) * - destination: coll (inserting) */ copy (istream_iterator(cin), // start of source istream_iterator(), // end of source back_inserter(coll)); // destination // sort elements sort (coll.begin(), coll.end()); /* print all elements without duplicates * - source: coll * - destination: standard output (with newline between elements) */ unique_copy (coll.begin(), coll.end(), // source ostream_iterator(cout,"\n")); // destination } ================================================ FILE: stl侯杰源码/stl/iterbug1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { vector coll1; // empty collection vector coll2; // empty collection /* RUNTIME ERROR: * - beginning is behind the end of the range */ vector::iterator pos = coll1.begin(); reverse (++pos, coll1.end()); // insert elements from 1 to 9 into coll2 for (int i=1; i<=9; ++i) { coll2.push_back (i); } /* RUNTIME ERROR: * - overwriting nonexisting elements */ copy (coll2.begin(), coll2.end(), // source coll1.begin()); // destination /* RUNTIME ERROR: * - collections mistaken * - begin() and end() mistaken */ copy (coll1.begin(), coll2.end(), // source coll1.end()); // destination } ================================================ FILE: stl侯杰源码/stl/list1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { list coll; // list container for character elements // append elements from 'a' to 'z' for (char c='a'; c<='z'; ++c) { coll.push_back(c); } /* print all elements * - while there are elements * - print and remove the first element */ while (! coll.empty()) { cout << coll.front() << ' '; coll.pop_front(); } cout << endl; } ================================================ FILE: stl侯杰源码/stl/list2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { list coll; // list container for character elements // append elements from 'a' to 'z' for (char c='a'; c<='z'; ++c) { coll.push_back(c); } /* print all elements * - iterate over all elements */ list::const_iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { cout << *pos << ' '; } cout << endl; } ================================================ FILE: stl侯杰源码/stl/map1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { /* type of the container: * - map: elements key/value pairs * - string: keys have type string * - float: values have type float */ typedef map StringFloatMap; StringFloatMap coll; // insert some elements into the collection coll["VAT"] = 0.15; coll["Pi"] = 3.1415; coll["an arbitrary number"] = 4983.223; coll["Null"] = 0; /* print all elements * - iterate over all elements * - element member first is the key * - element member second is the value */ StringFloatMap::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { cout << "key: \"" << pos->first << "\" " << "value: " << pos->second << endl; } } ================================================ FILE: stl侯杰源码/stl/mmap1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { // type of the collection typedef multimap IntStringMMap; IntStringMMap coll; // container for int/string values // insert some elements in arbitrary order // - a value with key 1 gets inserted twice coll.insert(make_pair(5,"tagged")); coll.insert(make_pair(2,"a")); coll.insert(make_pair(1,"this")); coll.insert(make_pair(4,"of")); coll.insert(make_pair(6,"strings")); coll.insert(make_pair(1,"is")); coll.insert(make_pair(3,"multimap")); /* print all element values * - iterate over all elements * - element member second is the value */ IntStringMMap::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { cout << pos->second << ' '; } cout << endl; } ================================================ FILE: stl侯杰源码/stl/prime1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include // for abs() using namespace std; // predicate, which returns whether an integer is a prime number bool isPrime (int number) { // ignore negative sign number = abs(number); // 0 and 1 are no prime numbers if (number == 0 || number == 1) { return false; } // find divisor that divides without a remainder int divisor; for (divisor = number/2; number%divisor != 0; --divisor) { ; } // if no divisor greater than 1 is found, it is a prime number return divisor == 1; } int main() { list coll; // insert elements from 24 to 30 for (int i=24; i<=30; ++i) { coll.push_back(i); } // search for prime number list::iterator pos; pos = find_if (coll.begin(), coll.end(), // range isPrime); // predicate if (pos != coll.end()) { // found cout << *pos << " is first prime number found" << endl; } else { // not found cout << "no prime number found" << endl; } } ================================================ FILE: stl侯杰源码/stl/print.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include /* PRINT_ELEMENTS() * - prints optional C-string optcstr followed by * - all elements of the collection coll * - separated by spaces */ template inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") { typename T::const_iterator pos; std::cout << optcstr; for (pos=coll.begin(); pos!=coll.end(); ++pos) { std::cout << *pos << ' '; } std::cout << std::endl; } ================================================ FILE: stl侯杰源码/stl/remove1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { list coll; // insert elements from 6 to 1 and 1 to 6 for (int i=1; i<=6; ++i) { coll.push_front(i); coll.push_back(i); } // print all elements of the collection cout << "pre: "; copy (coll.begin(), coll.end(), // source ostream_iterator(cout," ")); // destination cout << endl; // remove all elements with value 3 remove (coll.begin(), coll.end(), // range 3); // value // print all elements of the collection cout << "post: "; copy (coll.begin(), coll.end(), // source ostream_iterator(cout," ")); // destination cout << endl; } ================================================ FILE: stl侯杰源码/stl/remove2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { list coll; // insert elements from 6 to 1 and 1 to 6 for (int i=1; i<=6; ++i) { coll.push_front(i); coll.push_back(i); } // print all elements of the collection copy (coll.begin(), coll.end(), ostream_iterator(cout," ")); cout << endl; // remove all elements with value 3 // - retain new end list::iterator end = remove (coll.begin(), coll.end(), 3); // print resulting elements of the collection copy (coll.begin(), end, ostream_iterator(cout," ")); cout << endl; // print number of resulting elements cout << "number of removed elements: " << distance(end,coll.end()) << endl; // remove ``removed'' elements coll.erase (end, coll.end()); // print all elements of the modified collection copy (coll.begin(), coll.end(), ostream_iterator(cout," ")); cout << endl; } ================================================ FILE: stl侯杰源码/stl/remove3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { set coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.insert(i); } // print all elements of the collection copy (coll.begin(), coll.end(), ostream_iterator(cout," ")); cout << endl; /* Remove all elements with value 3 * - algorithm remove() does not work * - instead member function erase() works */ int num = coll.erase(3); // print number of removed elements cout << "number of removed elements: " << num << endl; // print all elements of the modified collection copy (coll.begin(), coll.end(), ostream_iterator(cout," ")); cout << endl; } ================================================ FILE: stl侯杰源码/stl/remove4.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { list coll; // insert elements from 6 to 1 and 1 to 6 for (int i=1; i<=6; ++i) { coll.push_front(i); coll.push_back(i); } // remove all elements with value 3 // - poor performance coll.erase (remove(coll.begin(),coll.end(), 3), coll.end()); // remove all elements with value 4 // - good performance coll.remove (4); } ================================================ FILE: stl侯杰源码/stl/riter1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // print all element in reverse order copy (coll.rbegin(), coll.rend(), // source ostream_iterator(cout," ")); // destination cout << endl; } ================================================ FILE: stl侯杰源码/stl/set1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include int main() { // type of the collection typedef std::set IntSet; IntSet coll; // set container for int values /* insert elements from 1 to 6 in arbitrary order * - value 1 gets inserted twice */ coll.insert(3); coll.insert(1); coll.insert(5); coll.insert(4); coll.insert(1); coll.insert(6); coll.insert(2); /* print all elements * - iterate over all elements */ IntSet::const_iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { std::cout << *pos << ' '; } std::cout << std::endl; } ================================================ FILE: stl侯杰源码/stl/sort1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; /* class Person */ class Person { private: string fn; // first name string ln; // last name public: Person() { } Person(const string& f, const string& n) : fn(f), ln(n) { } string firstname() const; string lastname() const; // ... }; inline string Person::firstname() const { return fn; } inline string Person::lastname() const { return ln; } ostream& operator<< (ostream& s, const Person& p) { s << "[" << p.firstname() << " " << p.lastname() << "]"; return s; } /* binary function predicate: * - returns whether a person is less than another person */ bool personSortCriterion (const Person& p1, const Person& p2) { /* a person is less than another person * - if the last name is less * - if the last name is equal and the first name is less */ return p1.lastname() coll; coll.push_back(p1); coll.push_back(p2); coll.push_back(p3); coll.push_back(p4); coll.push_back(p5); coll.push_back(p6); coll.push_back(p7); // print elements cout << "deque before sort():" << endl; deque::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { cout << *pos << endl; } // sort elements sort(coll.begin(),coll.end(), // range personSortCriterion); // sort criterion // print elements cout << "deque after sort():" << endl; for (pos = coll.begin(); pos != coll.end(); ++pos) { cout << *pos << endl; } } ================================================ FILE: stl侯杰源码/stl/transform1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include "print.hpp" int square (int value) { return value*value; } int main() { std::set coll1; std::vector coll2; // insert elements from 1 to 9 into coll1 for (int i=1; i<=9; ++i) { coll1.insert(i); } PRINT_ELEMENTS(coll1,"initialized: "); // transform each element from coll1 to coll2 // - square transformed values std::transform (coll1.begin(),coll1.end(), // source std::back_inserter(coll2), // destination square); // operation PRINT_ELEMENTS(coll2,"squared: "); } ================================================ FILE: stl侯杰源码/stl/vector1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main() { vector coll; // vector container for integer elements // append elements with values 1 to 6 for (int i=1; i<=6; ++i) { coll.push_back(i); } // print all elements followed by a space for (int i=0; i #include #include /* replace functions of the standard char_traits * so that strings behave in a case-insensitive way */ struct ignorecase_traits : public std::char_traits { // return whether c1 and c2 are equal static bool eq(const char& c1, const char& c2) { return std::toupper(c1)==std::toupper(c2); } // return whether c1 is less than c2 static bool lt(const char& c1, const char& c2) { return std::toupper(c1) icstring; /* define an output operator * because the traits type is different than that for std::ostream */ inline std::ostream& operator << (std::ostream& strm, const icstring& s) { // simply convert the icstring into a normal string return strm << std::string(s.data(),s.length()); } #endif // ICSTRING_HPP ================================================ FILE: stl侯杰源码/string/icstring1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include "icstring.hpp" int main() { using std::cout; using std::endl; icstring s1("hallo"); icstring s2("otto"); icstring s3("hALLo"); cout << std::boolalpha; cout << s1 << " == " << s2 << " : " << (s1==s2) << endl; cout << s1 << " == " << s3 << " : " << (s1==s3) << endl; icstring::size_type idx = s1.find("All"); if (idx != icstring::npos) { cout << "index of \"All\" in \"" << s1 << "\": " << idx << endl; } else { cout << "\"All\" not found in \"" << s1 << endl; } } ================================================ FILE: stl侯杰源码/string/iter1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include using namespace std; int main() { // create a string string s("The zip code of Hondelage in Germany is 38108"); cout << "original: " << s << endl; // lowercase all characters transform (s.begin(), s.end(), // source s.begin(), // destination tolower); // operation cout << "lowered: " << s << endl; // uppercase all characters transform (s.begin(), s.end(), // source s.begin(), // destination toupper); // operation cout << "uppered: " << s << endl; } ================================================ FILE: stl侯杰源码/string/iter2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; bool nocase_compare (char c1, char c2) { return toupper(c1) == toupper(c2); } int main() { string s1("This is a string"); string s2("STRING"); // compare case insensitive if (s1.size() == s2.size() && // ensure same sizes equal (s1.begin(),s1.end(), // first source string s2.begin(), // second source string nocase_compare)) { // comparison criterion cout << "the strings are equal" << endl; } else { cout << "the strings are not equal" << endl; } // search case insensitive string::iterator pos; pos = search (s1.begin(),s1.end(), // source string in which to search s2.begin(),s2.end(), // substring to search nocase_compare); // comparison criterion if (pos == s1.end()) { cout << "s2 is not a substring of s1" << endl; } else { cout << '"' << s2 << "\" is a substring of \"" << s1 << "\" (at index " << pos - s1.begin() << ")" << endl; } } ================================================ FILE: stl侯杰源码/string/iter3.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { // create constant string const string hello("Hello, how are you?"); // initialize string s with all characters of string hello string s(hello.begin(),hello.end()); // iterate through all of the characters string::iterator pos; for (pos = s.begin(); pos != s.end(); ++pos) { cout << *pos; } cout << endl; // reverse the order of all characters inside the string reverse (s.begin(), s.end()); cout << "reverse: " << s << endl; // sort all characters inside the string sort (s.begin(), s.end()); cout << "ordered: " << s << endl; /* remove adjacent duplicates * - unique() reorders and returns new end * - erase() shrinks accordingly */ s.erase (unique(s.begin(), s.end()), s.end()); cout << "no duplicates: " << s << endl; } ================================================ FILE: stl侯杰源码/string/string1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main (int argc, char* argv[]) { string filename, basename, extname, tmpname; const string suffix("tmp"); /* for each command-line argument * (which is an ordinary C-string) */ for (int i=1; i " << tmpname << endl; } } ================================================ FILE: stl侯杰源码/string/string2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; int main (int argc, char** argv) { const string delims(" \t,.;"); string line; // for every line read successfully while (getline(cin,line)) { string::size_type begIdx, endIdx; // search beginning of the first word begIdx = line.find_first_not_of(delims); // while beginning of a word found while (begIdx != string::npos) { // search end of the actual word endIdx = line.find_first_of (delims, begIdx); if (endIdx == string::npos) { // end of word is end of line endIdx = line.length(); } // print characters in reverse order for (int i=endIdx-1; i>=static_cast(begIdx); --i) { cout << line[i]; } cout << ' '; // search beginning of the next word begIdx = line.find_first_not_of (delims, endIdx); } cout << endl; } } ================================================ FILE: stl侯杰源码/string/unique.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include #include #include using namespace std; class bothWhiteSpaces { private: const locale& loc; // locale public: /* constructor * - save the locale object */ bothWhiteSpaces (const locale& l) : loc(l) { } /* function call * - returns whether both characters are whitespaces */ bool operator() (char elem1, char elem2) { return isspace(elem1,loc) && isspace(elem2,loc); } }; int main() { string contents; // don't skip leading whitespaces cin.unsetf (ios::skipws); // read all characters while compressing whitespaces unique_copy(istream_iterator(cin), // beginning of source istream_iterator(), // end of source back_inserter(contents), // destination bothWhiteSpaces(cin.getloc())); // criterion for removing // process contents // - here: write it to the standard output cout << contents; } ================================================ FILE: stl侯杰源码/util/Makefile ================================================ OUTPROGS = autoptr1 autoptr2 limits1 minmax1 HEADERS = autoptr.hpp defalloc.hpp include ../Makefile.h ================================================ FILE: stl侯杰源码/util/autoptr.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ /* class auto_ptr * - improved standard conforming implementation */ namespace std { // auxiliary type to enable copies and assignments (now global) template struct auto_ptr_ref { Y* yp; auto_ptr_ref (Y* rhs) : yp(rhs) { } }; template class auto_ptr { private: T* ap; // refers to the actual owned object (if any) public: typedef T element_type; // constructor explicit auto_ptr (T* ptr = 0) throw() : ap(ptr) { } // copy constructors (with implicit conversion) // - note: nonconstant parameter auto_ptr (auto_ptr& rhs) throw() : ap(rhs.release()) { } template auto_ptr (auto_ptr& rhs) throw() : ap(rhs.release()) { } // assignments (with implicit conversion) // - note: nonconstant parameter auto_ptr& operator= (auto_ptr& rhs) throw() { reset(rhs.release()); return *this; } template auto_ptr& operator= (auto_ptr& rhs) throw() { reset(rhs.release()); return *this; } // destructor ~auto_ptr() throw() { delete ap; } // value access T* get() const throw() { return ap; } T& operator*() const throw() { return *ap; } T* operator->() const throw() { return ap; } // release ownership T* release() throw() { T* tmp(ap); ap = 0; return tmp; } // reset value void reset (T* ptr=0) throw() { if (ap != ptr) { delete ap; ap = ptr; } } /* special conversions with auxiliary type to enable copies and assignments */ auto_ptr(auto_ptr_ref rhs) throw() : ap(rhs.yp) { } auto_ptr& operator= (auto_ptr_ref rhs) throw() { // new reset(rhs.yp); return *this; } template operator auto_ptr_ref() throw() { return auto_ptr_ref(release()); } template operator auto_ptr() throw() { return auto_ptr(release()); } }; } ================================================ FILE: stl侯杰源码/util/autoptr1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; /* define output operator for auto_ptr * - print object value or NULL */ template ostream& operator<< (ostream& strm, const auto_ptr& p) { // does p own an object ? if (p.get() == NULL) { strm << "NULL"; // NO: print NULL } else { strm << *p; // YES: print the object } return strm; } int main() { auto_ptr p(new int(42)); auto_ptr q; cout << "after initialization:" << endl; cout << " p: " << p << endl; cout << " q: " << q << endl; q = p; cout << "after assigning auto pointers:" << endl; cout << " p: " << p << endl; cout << " q: " << q << endl; *q += 13; // change value of the object q owns p = q; cout << "after change and reassignment:" << endl; cout << " p: " << p << endl; cout << " q: " << q << endl; } ================================================ FILE: stl侯杰源码/util/autoptr2.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include using namespace std; /* define output operator for auto_ptr * - print object value or NULL */ template ostream& operator<< (ostream& strm, const auto_ptr& p) { // does p own an object ? if (p.get() == NULL) { strm << "NULL"; // NO: print NULL } else { strm << *p; // YES: print the object } return strm; } int main() { const auto_ptr p(new int(42)); const auto_ptr q(new int(0)); const auto_ptr r; cout << "after initialization:" << endl; cout << " p: " << p << endl; cout << " q: " << q << endl; cout << " r: " << r << endl; *q = *p; // *r = *p; // ERROR: undefined behavior *p = -77; cout << "after assigning values:" << endl; cout << " p: " << p << endl; cout << " q: " << q << endl; cout << " r: " << r << endl; // q = p; // ERROR at compile time // r = p; // ERROR at compile time } ================================================ FILE: stl侯杰源码/util/defalloc.hpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ namespace std { template class allocator { public: // type definitions typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T value_type; // rebind allocator to type U template struct rebind { typedef allocator other; }; // return address of values pointer address (reference value) const { return &value; } const_pointer address (const_reference value) const { return &value; } /* constructors and destructor * - nothing to do because the allocator has no state */ allocator() throw() { } allocator(const allocator&) throw() { } template allocator (const allocator&) throw() { } ~allocator() throw() { } // return maximum number of elements that can be allocated size_type max_size () const throw() { return numeric_limits::max() / sizeof(T); } // allocate but don't initialize num elements of type T pointer allocate (size_type num, allocator::const_pointer hint = 0) { // allocate memory with global new return (pointer)(::operator new(num*sizeof(T))); } // initialize elements of allocated storage p with value value void construct (pointer p, const T& value) { // initialize memory with placement new new((void*)p)T(value); } // destroy elements of initialized storage p void destroy (pointer p) { // destroy objects by calling their destructor p->~T(); } // deallocate storage p of deleted elements void deallocate (pointer p, size_type num) { // deallocate memory with global delete ::operator delete((void*)p); } }; // return that all specializations of this allocator are interchangeable template bool operator== (const allocator&, const allocator&) throw() { return true; } template bool operator!= (const allocator&, const allocator&) throw() { return false; } } ================================================ FILE: stl侯杰源码/util/limits1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include #include #include using namespace std; int main() { // use textual representation for bool cout << boolalpha; // print maximum of integral types cout << "max(short): " << numeric_limits::max() << endl; cout << "max(int): " << numeric_limits::max() << endl; cout << "max(long): " << numeric_limits::max() << endl; cout << endl; // print maximum of floating-point types cout << "max(float): " << numeric_limits::max() << endl; cout << "max(double): " << numeric_limits::max() << endl; cout << "max(long double): " << numeric_limits::max() << endl; cout << endl; // print whether char is signed cout << "is_signed(char): " << numeric_limits::is_signed << endl; cout << endl; // print whether numeric limits for type string exist cout << "is_specialized(string): " << numeric_limits::is_specialized << endl; } ================================================ FILE: stl侯杰源码/util/minmax1.cpp ================================================ /* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * 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. */ #include using namespace std; /* function that compares two pointers by comparing the values to which they point */ bool int_ptr_less (int* a, int* b) { return *a < *b; } int main() { int x = 17; int y = 42; int* px = &x; int* py = &y; int* pmax; // call max() with special comparison function pmax = max (px, py, int_ptr_less); //... } ================================================ FILE: tass-sgi-stl-2.91.57-source/JJHOU.TXT ================================================ all files copy from \cygnus\cygwin-b20\include\g++. bundle with G++ 2.91.57  ================================================ FILE: tass-sgi-stl-2.91.57-source/PlotFile.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* a very simple implementation of a class to output unix "plot" format plotter files. See corresponding unix man pages for more details. written by Doug Lea (dl@rocky.oswego.edu) converted to use iostream library by Per Bothner (bothner@cygnus.com) */ #ifndef _PlotFile_h #ifdef __GNUG__ #pragma interface #endif #define _PlotFile_h #include /* Some plot libraries have the `box' command to draw boxes. Some don't. `box' is included here via moves & lines to allow both possiblilties. */ extern "C++" { class PlotFile : public ofstream { protected: PlotFile& cmd(char c); PlotFile& operator << (const int x); PlotFile& operator << (const char *s); public: PlotFile() : ofstream() { } PlotFile(int fd) : ofstream(fd) { } PlotFile(const char *name, int mode=ios::out, int prot=0664) : ofstream(name, mode, prot) { } // PlotFile& remove() { ofstream::remove(); return *this; } // int filedesc() { return ofstream::filedesc(); } // const char* name() { return File::name(); } // void setname(const char* newname) { File::setname(newname); } // int iocount() { return File::iocount(); } PlotFile& arc(const int xi, const int yi, const int x0, const int y0, const int x1, const int y1); PlotFile& box(const int x0, const int y0, const int x1, const int y1); PlotFile& circle(const int x, const int y, const int r); PlotFile& cont(const int xi, const int yi); PlotFile& dot(const int xi, const int yi, const int dx, int n, const int* pat); PlotFile& erase(); PlotFile& label(const char* s); PlotFile& line(const int x0, const int y0, const int x1, const int y1); PlotFile& linemod(const char* s); PlotFile& move(const int xi, const int yi); PlotFile& point(const int xi, const int yi); PlotFile& space(const int x0, const int y0, const int x1, const int y1); }; } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/SFile.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1988, 1992, 1993 Free Software Foundation written by Doug Lea (dl@rocky.oswego.edu) This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 _SFile_h #ifdef __GNUG__ #pragma interface #endif #define _SFile_h 1 #include extern "C++" { class SFile: public fstream { protected: int sz; // unit size for structured binary IO public: SFile() : fstream() { } SFile(int fd, int size); SFile(const char *name, int size, int mode, int prot=0664); void open(const char *name, int size, int mode, int prot=0664); int size() { return sz; } int setsize(int s) { int old = sz; sz = s; return old; } SFile& get(void* x); SFile& put(void* x); SFile& operator[](long i); }; } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/algo.h ================================================ /* * * 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 __SGI_STL_ALGO_H #define __SGI_STL_ALGO_H #include #include #include #include #ifdef __STL_USE_NAMESPACES // Names from 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::random_sample; using __STD::random_sample_n; 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; using __STD::is_sorted; using __STD::is_heap; // Names from stl_heap.h using __STD::push_heap; using __STD::pop_heap; using __STD::make_heap; using __STD::sort_heap; // Names from using __STD::accumulate; using __STD::inner_product; using __STD::partial_sum; using __STD::adjacent_difference; using __STD::power; using __STD::iota; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ALGO_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/algobase.h ================================================ /* * * 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 __SGI_STL_ALGOBASE_H #define __SGI_STL_ALGOBASE_H #ifndef __SGI_STL_PAIR_H #include #endif #ifndef __SGI_STL_ITERATOR_H #include #endif #ifndef __SGI_STL_INTERNAL_ALGOBASE_H #include #endif #ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H #include #endif #ifdef __STL_USE_NAMESPACES // 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::copy_n; using __STD::fill; using __STD::fill_n; using __STD::mismatch; using __STD::equal; using __STD::lexicographical_compare; using __STD::lexicographical_compare_3way; // Names from stl_uninitialized.h using __STD::uninitialized_copy; using __STD::uninitialized_copy_n; using __STD::uninitialized_fill; using __STD::uninitialized_fill_n; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ALGOBASE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/algorithm ================================================ /* * * 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 __SGI_STL_ALGORITHM #define __SGI_STL_ALGORITHM #include #include #include #include #endif /* __SGI_STL_ALGORITHM */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/alloc.h ================================================ /* * 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 __SGI_STL_ALLOC_H #define __SGI_STL_ALLOC_H #ifndef __STL_CONFIG_H #include #endif #ifndef __SGI_STL_INTERNAL_ALLOC_H #include #endif #ifdef __STL_USE_NAMESPACES using __STD::__malloc_alloc_template; using __STD::malloc_alloc; using __STD::simple_alloc; using __STD::debug_alloc; using __STD::__default_alloc_template; using __STD::alloc; using __STD::single_client_alloc; #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG using __STD::__malloc_alloc_oom_handler; #endif /* __STL_STATIC_TEMPLATE_MEMBER_BUG */ #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ALLOC_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/builtinbuf.h ================================================ /* Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 _BUILTINBUF_H #define _BUILTINBUF_H #ifdef __GNUC__ #pragma interface #endif #include #if !_IO_UNIFIED_JUMPTABLES // A builtinbuf is a streambuf where all the virtual operations // call the _IO_jump_t table. extern "C++" { class builtinbuf : public streambuf { friend ios; virtual int overflow(int); virtual int underflow(); virtual streamsize xsgetn(char *, streamsize); virtual streamsize xsputn(const char *, streamsize); virtual streambuf* setbuf(char*, int); virtual int doallocate(); virtual ~builtinbuf(); virtual int sync(); virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out); virtual int pbackfail(int c); virtual streamsize sys_read(char* buf, streamsize size); virtual streampos sys_seek(streamoff, _seek_dir); virtual streamsize sys_write(const char*, streamsize); virtual int sys_stat(void*); // Actually, a (struct stat*) virtual int sys_close(); #if 0 virtual int get_column(); virtual int set_column(int); #endif private: builtinbuf() { } }; } // extern "C++" #endif #endif /* _BUILTINBUF_H */ ================================================ FILE: tass-sgi-stl-2.91.57-source/bvector.h ================================================ /* * * 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 __SGI_STL_BVECTOR_H #define __SGI_STL_BVECTOR_H #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION #include #else #include #include #endif #include #ifdef __STL_USE_NAMESPACES using __STD::bit_vector; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_BVECTOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/cassert ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __CASSERT__ #define __CASSERT__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cctype ================================================ // The -*- C++ -*- character type header. // This file is part of the GNU ANSI C++ Library. #ifndef __CCTYPE__ #define __CCTYPE__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cerrno ================================================ // The -*- C++ -*- error number header. // This file is part of the GNU ANSI C++ Library. #ifndef __CERRNO__ #define __CERRNO__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cfloat ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __CFLOAT__ #define __CFLOAT__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/ciso646 ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __CISO646__ #define __CISO646__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/climits ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __CLIMITS__ #define __CLIMITS__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/clocale ================================================ // The -*- C++ -*- locale support header. // This file is part of the GNU ANSI C++ Library. #ifndef __CLOCALE__ #define __CLOCALE__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cmath ================================================ // The -*- C++ -*- math functions header. // This file is part of the GNU ANSI C++ Library. #ifndef __CMATH__ #define __CMATH__ #include <_G_config.h> #include #ifdef __GNUG__ #pragma interface "cmath" #endif extern "C++" { #if 0 float acos (float); float asin (float); float atan (float); float atan2(float, float); float ceil (float); float cos (float); float cosh (float); float exp (float); float fabs (float); float floor(float); float fmod (float, float); float frexp(float, int*); float modf (float, float*); float ldexp(float, int); float log (float); float log10(float); float pow (float, float); float pow (float, int); float sin (float); float sinh (float); float sqrt (float); float tan (float); float tanh (float); #endif inline float abs (float x) { return fabs (x); } #if ! _G_MATH_H_INLINES /* hpux and SCO define this in math.h */ inline double abs (double x) { return fabs (x); } #endif #if 0 double pow(double, int); long double acos (long double); long double asin (long double); long double atan (long double); long double atan2(long double, long double); long double ceil (long double); long double cos (long double); long double cosh (long double); long double exp (long double); long double fabs (long double); long double floor(long double); long double frexp(long double, int*); long double fmod (long double, long double); long double frexp(long double, int*); long double log (long double); long double log10(long double); long double modf (long double, long double*); long double pow (long double, long double); long double pow (long double, int); long double sin (long double); long double sinh (long double); long double sqrt (long double); long double tan (long double); long double tanh (long double); #endif inline long double abs (long double x) { return fabs (x); } } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/complex ================================================ // Main header for the -*- C++ -*- complex number classes. // This file is part of the GNU ANSI C++ Library. #ifndef __COMPLEX__ #define __COMPLEX__ #include extern "C++" { #define __STD_COMPLEX // ANSI complex types typedef complex float_complex; typedef complex double_complex; typedef complex long_double_complex; } #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/complex.h ================================================ // -*- C++ -*- backward compatiblity header. // Copyright (C) 1994 Free Software Foundation #ifndef __COMPLEX_H__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/csetjmp ================================================ // The -*- C++ -*- setjmp/longjmp header. // This file is part of the GNU ANSI C++ Library. #ifndef __CSETJMP__ #define __CSETJMP__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/csignal ================================================ // The -*- C++ -*- signal handling header. // This file is part of the GNU ANSI C++ Library. #ifndef __CSIGNAL__ #define __CSIGNAL__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cstdarg ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __CSTDARG__ #define __CSTDARG__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cstddef ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __CSTDDEF__ #define __CSTDDEF__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cstdio ================================================ // The -*- C++ -*- standard I/O header. // This file is part of the GNU ANSI C++ Library. #ifndef __CSTDIO__ #define __CSTDIO__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cstdlib ================================================ // The -*- C++ -*- standard library header. // This file is part of the GNU ANSI C++ Library. #ifndef __CSTDLIB__ #define __CSTDLIB__ #include #ifdef __GNUG__ #pragma interface "cstdlib" #endif extern "C++" { #if _G_HAS_LABS inline long abs(long x) { return labs (x); } #else inline long abs(long x) { return x >= 0 ? x : -x; } #endif //inline ldiv_t div(long x, long y) { return ldiv (x, y); } } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cstring ================================================ // The -*- C++ -*- null-terminated string header. // This file is part of the GNU ANSI C++ Library. #ifndef __CSTRING__ #define __CSTRING__ #include #if 0 // Let's not bother with this just yet. #include #ifdef __GNUG__ #pragma interface "cstring" #endif // The ANSI C prototypes for these functions have a const argument type and // non-const return type, so we can't use them. extern "C++" { extern inline const char * _G_strchr (const char *s, int c) { return strchr (s, c); } extern inline char * _G_strchr (char *s, int c) { return const_cast (strchr (s, c)); } extern inline const char * _G_strpbrk (const char *s1, const char *s2) { return strpbrk (s1, s2); } extern inline char * _G_strpbrk (char *s1, const char *s2) { return const_cast (strpbrk (s1, s2)); } extern inline const char * _G_strrchr (const char *s, int c) { return strrchr (s, c); } extern inline char * _G_strrchr (char *s, int c) { return const_cast (strrchr (s, c)); } extern inline const char * _G_strstr (const char *s1, const char *s2) { return strstr (s1, s2); } extern inline char * _G_strstr (char *s1, const char *s2) { return const_cast (strstr (s1, s2)); } extern inline const void * _G_memchr (const void *s, int c, size_t n) { return memchr (s, c, n); } extern inline void * _G_memchr (void *s, int c, size_t n) { return const_cast (memchr (s, c, n)); } } // extern "C++" // Lose any vendor macros for these functions. #undef strchr #undef strpbrk #undef strrchr #undef strstr #undef memchr // Ewww, namespace pollution. Anyone have a better idea? #define strchr _G_strchr #define strpbrk _G_strpbrk #define strrchr _G_strrchr #define strstr _G_strstr #define memchr _G_memchr #endif // 0 #endif // !defined (__CSTRING__) ================================================ FILE: tass-sgi-stl-2.91.57-source/ctime ================================================ // The -*- C++ -*- time header. // This file is part of the GNU ANSI C++ Library. #ifndef __CTIME__ #define __CTIME__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cwchar ================================================ // The -*- C++ -*- wide character header. // This file is part of the GNU ANSI C++ Library. #ifndef __CWCHAR__ #define __CWCHAR__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/cwctype ================================================ // The -*- C++ -*- wide character type header. // This file is part of the GNU ANSI C++ Library. #ifndef __CWCTYPE__ #define __CWCTYPE__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/defalloc.h ================================================ /* * * 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. // // DO NOT USE THIS FILE unless you have an old container implementation // that requires an allocator with the HP-style interface. SGI STL // uses a different allocator interface. SGI-style allocators are not // parametrized with respect to the object type; they traffic in void * // pointers. This file is not included by any other SGI STL header. #ifndef DEFALLOC_H #define DEFALLOC_H #include #include #include #include #include #include template inline T* allocate(ptrdiff_t size, T*) { set_new_handler(0); T* tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); if (tmp == 0) { cerr << "out of memory" << endl; exit(1); } return tmp; } template inline void deallocate(T* buffer) { ::operator delete(buffer); } template class allocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& 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(T))); } size_type max_size() const { return max(size_type(1), size_type(UINT_MAX/sizeof(T))); } }; class allocator { public: typedef void* pointer; }; #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/deque ================================================ /* * * 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 __SGI_STL_DEQUE #define __SGI_STL_DEQUE #include #include #include #include #include #endif /* __SGI_STL_DEQUE */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/deque.h ================================================ /* * * 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 __SGI_STL_DEQUE_H #define __SGI_STL_DEQUE_H #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::deque; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_DEQUE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/editbuf.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. Written by Per Bothner (bothner@cygnus.com). */ #ifndef _EDITBUF_H #define _EDITBUF_H #ifdef __GNUG__ #pragma interface #endif #include #include extern "C++" { typedef unsigned long mark_pointer; // At some point, it might be nice to parameterize this code // in terms of buf_char. typedef /*unsigned*/ char buf_char; // Logical pos from start of buffer (does not count gap). typedef long buf_index; // Pos from start of buffer, possibly including gap_size. typedef long buf_offset; #if 0 struct buf_cookie { FILE *file; struct edit_string *str; struct buf_cookie *next; buf_index tell(); }; #endif struct edit_buffer; struct edit_mark; // A edit_string is defined as the region between the 'start' and 'end' marks. // Normally (always?) 'start->insert_before()' should be false, // and 'end->insert_before()' should be true. struct edit_string { struct edit_buffer *buffer; // buffer that 'start' and 'end' belong to struct edit_mark *start, *end; int length() const; // count of buf_chars currently in string edit_string(struct edit_buffer *b, struct edit_mark *ms, struct edit_mark *me) { buffer = b; start = ms; end = me; } /* Make a fresh, contiguous copy of the data in STR. Assign length of STR to *LENP. (Output has extra NUL at out[*LENP].) */ buf_char *copy_bytes(int *lenp) const; // FILE *open_file(char *mode); void assign(struct edit_string *src); // copy bytes from src to this }; struct edit_streambuf : public streambuf { friend edit_buffer; edit_string *str; edit_streambuf* next; // Chain of edit_streambuf's for a edit_buffer. short _mode; edit_streambuf(edit_string* bstr, int mode); ~edit_streambuf(); virtual int underflow(); virtual int overflow(int c = EOF); virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); void flush_to_buffer(); void flush_to_buffer(edit_buffer* buffer); int _inserting; int inserting() { return _inserting; } void inserting(int i) { _inserting = i; } // int delete_chars(int count, char* cut_buf); Not implemented. int truncate(); int is_reading() { return gptr() != NULL; } buf_char* current() { return is_reading() ? gptr() : pptr(); } void set_current(char *p, int is_reading); protected: void disconnect_gap_from_file(edit_buffer* buffer); }; // A 'edit_mark' indicates a position in a buffer. // It is "attached" the text (rather than the offset). // There are two kinds of mark, which have different behavior // when text is inserted at the mark: // If 'insert_before()' is true the mark will be adjusted to be // *after* the new text. struct edit_mark { struct edit_mark *chain; mark_pointer _pos; inline int insert_before() { return _pos & 1; } inline unsigned long index_in_buffer(struct edit_buffer *) { return _pos >> 1; } inline buf_char *ptr(struct edit_buffer *buf); buf_index tell(); edit_mark() { } edit_mark(struct edit_string *str, long delta); edit_buffer *buffer(); ~edit_mark(); }; // A 'edit_buffer' consists of a sequence of buf_chars (the data), // a list of edit_marks pointing into the data, and a list of FILEs // also pointing into the data. // A 'edit_buffer' coerced to a edit_string is the string of // all the buf_chars in the buffer. // This implementation uses a conventional buffer gap (as in Emacs). // The gap start is defined by de-referencing a (buf_char**). // This is because sometimes a FILE is inserting into the buffer, // so rather than having each putc adjust the gap, we use indirection // to have the gap be defined as the write pointer of the FILE. // (This assumes that putc adjusts a pointer (as in GNU's libc), not an index.) struct edit_buffer { buf_char *data; /* == emacs buffer_text.p1+1 */ buf_char *_gap_start; edit_streambuf* _writer; // If non-NULL, currently writing stream inline buf_char *gap_start() { return _writer ? _writer->pptr() : _gap_start; } buf_offset __gap_end_pos; // size of part 1 + size of gap /* int gap; implicit: buf_size - size1 - size2 */ int buf_size; struct edit_streambuf *files; struct edit_mark start_mark; struct edit_mark end_mark; edit_buffer(); inline buf_offset gap_end_pos() { return __gap_end_pos; } inline struct edit_mark *start_marker() { return &start_mark; } inline struct edit_mark *end_marker() { return &end_mark; } /* these should be protected, ultimately */ buf_index tell(edit_mark*); buf_index tell(buf_char*); inline buf_char *gap_end() { return data + gap_end_pos(); } inline int gap_size() { return gap_end() - gap_start(); } inline int size1() { return gap_start() - data; } inline int size2() { return buf_size - gap_end_pos(); } inline struct edit_mark * mark_list() { return &start_mark; } void make_gap (buf_offset); void move_gap (buf_offset pos); void move_gap (buf_char *pos) { move_gap(pos - data); } void gap_left (int pos); void gap_right (int pos); void adjust_markers(mark_pointer low, mark_pointer high, int amount, buf_char *old_data); void delete_range(buf_index from, buf_index to); void delete_range(struct edit_mark *start, struct edit_mark *end); }; extern buf_char * bstr_copy(struct edit_string *str, int *lenp); // Convert a edit_mark to a (buf_char*) inline buf_char *edit_mark::ptr(struct edit_buffer *buf) { return buf->data + index_in_buffer(buf); } inline void edit_streambuf::flush_to_buffer() { edit_buffer* buffer = str->buffer; if (buffer->_writer == this) flush_to_buffer(buffer); } } // extern "C++" #endif /* !_EDITBUF_H*/ ================================================ FILE: tass-sgi-stl-2.91.57-source/floatio.h ================================================ /* Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * %W% (Berkeley) %G% */ /* * Floating point scanf/printf (input/output) definitions. */ /* 11-bit exponent (VAX G floating point) is 308 decimal digits */ #define MAXEXP 308 /* 128 bit fraction takes up 39 decimal digits; max reasonable precision */ #define MAXFRACT 39 ================================================ FILE: tass-sgi-stl-2.91.57-source/fstream ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __FSTREAM__ #define __FSTREAM__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/fstream.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 _FSTREAM_H #define _FSTREAM_H #ifdef __GNUG__ #pragma interface #endif #include extern "C++" { class fstreambase : virtual public ios { #ifdef _IO_NEW_STREAMS mutable filebuf __my_fb; // mutable so rdbuf() can be const #endif void __fb_init (); public: fstreambase(); fstreambase(int fd); fstreambase(int fd, char *p, int l); /* Deprecated */ fstreambase(const char *name, int mode, int prot=0664); void close(); #ifdef _IO_NEW_STREAMS filebuf* rdbuf() const { return &__my_fb; } #else filebuf* rdbuf() const { return (filebuf*) ios::rdbuf(); } #endif void open(const char *name, int mode, int prot=0664); int is_open() const { return rdbuf()->is_open(); } void setbuf(char *ptr, int len) { rdbuf()->setbuf(ptr, len); } void attach(int fd); #ifdef _STREAM_COMPAT int filedesc() { return rdbuf()->fd(); } fstreambase& raw() { rdbuf()->setbuf(NULL, 0); return *this; } #endif }; class ifstream : public fstreambase, public istream { public: ifstream() : fstreambase() { } ifstream(int fd) : fstreambase(fd) { } ifstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/ ifstream(const char *name, int mode=ios::in, int prot=0664) : fstreambase(name, mode, prot) { } void open(const char *name, int mode=ios::in, int prot=0664) { fstreambase::open(name, mode, prot); } }; class ofstream : public fstreambase, public ostream { public: ofstream() : fstreambase() { } ofstream(int fd) : fstreambase(fd) { } ofstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/ ofstream(const char *name, int mode=ios::out, int prot=0664) : fstreambase(name, mode, prot) { } void open(const char *name, int mode=ios::out, int prot=0664) { fstreambase::open(name, mode, prot); } }; class fstream : public fstreambase, public iostream { public: fstream() : fstreambase() { } fstream(int fd) : fstreambase(fd) { } fstream(const char *name, int mode, int prot=0664) : fstreambase(name, mode, prot) { } fstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/ void open(const char *name, int mode, int prot=0664) { fstreambase::open(name, mode, prot); } }; } // extern "C++" #endif /*!_FSTREAM_H*/ ================================================ FILE: tass-sgi-stl-2.91.57-source/function.h ================================================ /* * * 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 __SGI_STL_FUNCTION_H #define __SGI_STL_FUNCTION_H #ifndef __STL_CONFIG_H #include #endif #ifndef __SGI_STL_INTERNAL_RELOPS #include #endif #include #ifndef __SGI_STL_INTERNAL_FUNCTION_H #include #endif #ifdef __STL_USE_NAMESPACE_FOR_RELOPS // Names from stl_relops.h using __STD_RELOPS::operator!=; using __STD_RELOPS::operator>; using __STD_RELOPS::operator<=; using __STD_RELOPS::operator>=; #endif /* __STL_USE_NAMESPACE_FOR_RELOPS */ #ifdef __STL_USE_NAMESPACES // 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::identity_element; 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::unary_compose; using __STD::binary_compose; using __STD::compose1; using __STD::compose2; using __STD::pointer_to_unary_function; using __STD::pointer_to_binary_function; using __STD::ptr_fun; using __STD::identity; using __STD::select1st; using __STD::select2nd; using __STD::project1st; using __STD::project2nd; using __STD::constant_void_fun; using __STD::constant_unary_fun; using __STD::constant_binary_fun; using __STD::constant0; using __STD::constant1; using __STD::constant2; using __STD::subtractive_rng; 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; using __STD::mem_fun1; using __STD::mem_fun1_ref; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_FUNCTION_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/functional ================================================ /* * 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 __SGI_STL_FUNCTIONAL #define __SGI_STL_FUNCTIONAL #include #include #include #endif /* __SGI_STL_FUNCTIONAL */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/hash_map ================================================ /* * 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 __SGI_STL_HASH_MAP #define __SGI_STL_HASH_MAP #ifndef __SGI_STL_INTERNAL_HASHTABLE_H #include #endif #include #endif /* __SGI_STL_HASH_MAP */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/hash_map.h ================================================ /* * 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 __SGI_STL_HASH_MAP_H #define __SGI_STL_HASH_MAP_H #ifndef __SGI_STL_INTERNAL_HASHTABLE_H #include #endif #include #ifdef __STL_USE_NAMESPACES using __STD::hash; using __STD::hashtable; using __STD::hash_map; using __STD::hash_multimap; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_HASH_MAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/hash_set ================================================ /* * 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 __SGI_STL_HASH_SET #define __SGI_STL_HASH_SET #ifndef __SGI_STL_INTERNAL_HASHTABLE_H #include #endif #include #endif /* __SGI_STL_HASH_SET */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/hash_set.h ================================================ /* * 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 __SGI_STL_HASH_SET_H #define __SGI_STL_HASH_SET_H #ifndef __SGI_STL_INTERNAL_HASHTABLE_H #include #endif #include #ifdef __STL_USE_NAMESPACES using __STD::hash; using __STD::hashtable; using __STD::hash_set; using __STD::hash_multiset; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_HASH_SET_H */ ================================================ FILE: tass-sgi-stl-2.91.57-source/hashtable.h ================================================ /* * 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 __SGI_STL_HASHTABLE_H #define __SGI_STL_HASHTABLE_H #include #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::hash; using __STD::hashtable; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_HASHTABLE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/heap.h ================================================ /* * * 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 __SGI_STL_HEAP_H #define __SGI_STL_HEAP_H #include #include #ifdef __STL_USE_NAMESPACES using __STD::push_heap; using __STD::pop_heap; using __STD::make_heap; using __STD::sort_heap; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_HEAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/indstream.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. Written by Per Bothner (bothner@cygnus.com). */ #ifndef _INDSTREAM_H #define _INDSTREAM_H #ifdef __GNUG__ #pragma interface #endif #include extern "C++" { // An indirectbuf is one that forwards all of its I/O requests // to another streambuf. // All get-related requests are sent to get_stream(). // All put-related requests are sent to put_stream(). // An indirectbuf can be used to implement Common Lisp // synonym-streams and two-way-streams. // // class synonymbuf : public indirectbuf { // Symbol *sym; // synonymbuf(Symbol *s) { sym = s; } // virtual streambuf *lookup_stream(int mode) { // return coerce_to_streambuf(lookup_value(sym)); } // }; class indirectbuf : public streambuf { protected: streambuf *_get_stream; // Optional cache for get_stream(). streambuf *_put_stream; // Optional cache for put_stream(). int _delete_flags; public: streambuf *get_stream() { return _get_stream ? _get_stream : lookup_stream(ios::in); } streambuf *put_stream() { return _put_stream ? _put_stream : lookup_stream(ios::out); } virtual streambuf *lookup_stream(int/*mode*/) { return NULL; } // ERROR! indirectbuf(streambuf *get=NULL, streambuf *put=NULL, int delete_mode=0); virtual ~indirectbuf(); virtual streamsize xsputn(const char* s, streamsize n); virtual streamsize xsgetn(char* s, streamsize n); virtual int underflow(); virtual int uflow(); virtual int overflow(int c = EOF); virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out); virtual int sync(); virtual int pbackfail(int c); }; } // extern "C++" #endif /* !_INDSTREAM_H */ ================================================ FILE: tass-sgi-stl-2.91.57-source/iolibio.h ================================================ #include "libio.h" /* These emulate stdio functionality, but with a different name (_IO_ungetc instead of ungetc), and using _IO_FILE instead of FILE. */ #ifdef __cplusplus extern "C" { #endif extern int _IO_fclose __P((_IO_FILE*)); extern _IO_FILE *_IO_fdopen __P((int, const char*)); extern int _IO_fflush __P((_IO_FILE*)); extern int _IO_fgetpos __P((_IO_FILE*, _IO_fpos_t*)); extern char* _IO_fgets __P((char*, int, _IO_FILE*)); extern _IO_FILE *_IO_fopen __P((const char*, const char*)); extern int _IO_fprintf __P((_IO_FILE*, const char*, ...)); extern int _IO_fputs __P((const char*, _IO_FILE*)); extern int _IO_fsetpos __P((_IO_FILE*, const _IO_fpos_t *)); extern long int _IO_ftell __P((_IO_FILE*)); extern _IO_size_t _IO_fread __P((void*, _IO_size_t, _IO_size_t, _IO_FILE*)); extern _IO_size_t _IO_fwrite __P((const void*, _IO_size_t, _IO_size_t, _IO_FILE*)); extern char* _IO_gets __P((char*)); extern void _IO_perror __P((const char*)); extern int _IO_printf __P((const char*, ...)); extern int _IO_puts __P((const char*)); extern int _IO_scanf __P((const char*, ...)); extern void _IO_setbuffer __P((_IO_FILE *, char*, _IO_size_t)); extern int _IO_setvbuf __P((_IO_FILE*, char*, int, _IO_size_t)); extern int _IO_sscanf __P((const char*, const char*, ...)); extern int _IO_sprintf __P((char *, const char*, ...)); extern int _IO_ungetc __P((int, _IO_FILE*)); extern int _IO_vsscanf __P((const char *, const char *, _IO_va_list)); extern int _IO_vsprintf __P((char*, const char*, _IO_va_list)); struct obstack; extern int _IO_obstack_vprintf __P ((struct obstack *, const char *, _IO_va_list)); extern int _IO_obstack_printf __P ((struct obstack *, const char *, ...)); #ifndef _IO_pos_BAD #define _IO_pos_BAD ((_IO_fpos_t)(-1)) #endif #define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN)) #define _IO_fseek(__fp, __offset, __whence) \ (_IO_seekoff(__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD ? EOF : 0) #define _IO_rewind(FILE) (void)_IO_seekoff(FILE, 0, 0, _IOS_INPUT|_IOS_OUTPUT) #define _IO_vprintf(FORMAT, ARGS) _IO_vfprintf(_IO_stdout, FORMAT, ARGS) #if _G_IO_IO_FILE_VERSION == 0x20001 #define _IO_freopen(FILENAME, MODE, FP) \ (_IO_file_close_it(FP), _IO_file_fopen(FP, FILENAME, MODE, 0)) #else #define _IO_freopen(FILENAME, MODE, FP) \ (_IO_file_close_it(FP), _IO_file_fopen(FP, FILENAME, MODE)) #endif #define _IO_fileno(FP) ((FP)->_fileno) extern _IO_FILE* _IO_popen __P((const char*, const char*)); #define _IO_pclose _IO_fclose #define _IO_setbuf(_FP, _BUF) _IO_setbuffer(_FP, _BUF, _IO_BUFSIZ) #define _IO_setlinebuf(_FP) _IO_setvbuf(_FP, NULL, 1, 0) #ifdef __cplusplus } #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/iomanip ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __IOMANIP__ #define __IOMANIP__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/iomanip.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 _IOMANIP_H #ifdef __GNUG__ #pragma interface #endif #define _IOMANIP_H #include extern "C++" { //----------------------------------------------------------------------------- // Parametrized Manipulators as specified by ANSI draft //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Stream Manipulators //----------------------------------------------------------------------------- // template class smanip; // TP = Type Param template class sapp { ios& (*_f)(ios&, TP); public: sapp(ios& (*f)(ios&, TP)) : _f(f) {} // smanip operator()(TP a) { return smanip(_f, a); } }; template inline istream& operator>>(istream& i, const smanip& m); template inline ostream& operator<<(ostream& o, const smanip& m); template class smanip { ios& (*_f)(ios&, TP); TP _a; public: smanip(ios& (*f)(ios&, TP), TP a) : _f(f), _a(a) {} // friend istream& operator>> <>(istream& i, const smanip& m); friend ostream& operator<< <>(ostream& o, const smanip& m); }; #ifdef __GNUG__ extern template class smanip; extern template class smanip; #endif template inline istream& operator>>(istream& i, const smanip& m) { (*m._f)(i, m._a); return i; } template inline ostream& operator<<(ostream& o, const smanip& m) { (*m._f)(o, m._a); return o;} #ifdef __GNUG__ extern template istream& operator>>(istream&, const smanip&); extern template istream& operator>>(istream&, const smanip&); extern template ostream& operator<<(ostream&, const smanip&); extern template ostream& operator<<(ostream&, const smanip&); #endif //----------------------------------------------------------------------------- // Input-Stream Manipulators //----------------------------------------------------------------------------- // template class imanip; template class iapp { istream& (*_f)(istream&, TP); public: iapp(istream& (*f)(istream&,TP)) : _f(f) {} // imanip operator()(TP a) { return imanip(_f, a); } }; template inline istream& operator>>(istream&, const imanip&); template class imanip { istream& (*_f)(istream&, TP); TP _a; public: imanip(istream& (*f)(istream&, TP), TP a) : _f(f), _a(a) {} // friend istream& operator>> <>(istream& i, const imanip& m); }; template inline istream& operator>>(istream& i, const imanip& m) { return (*m._f)( i, m._a); } //----------------------------------------------------------------------------- // Output-Stream Manipulators //----------------------------------------------------------------------------- // template class omanip; template class oapp { ostream& (*_f)(ostream&, TP); public: oapp(ostream& (*f)(ostream&,TP)) : _f(f) {} // omanip operator()(TP a) { return omanip(_f, a); } }; template inline ostream& operator<<(ostream&, const omanip&); template class omanip { ostream& (*_f)(ostream&, TP); TP _a; public: omanip(ostream& (*f)(ostream&, TP), TP a) : _f(f), _a(a) {} // friend ostream& operator<< <>(ostream& o, const omanip& m); }; template inline ostream& operator<<(ostream& o, const omanip& m) { return (*m._f)(o, m._a); } //----------------------------------------------------------------------------- // Available Manipulators //----------------------------------------------------------------------------- // // Macro to define an iomanip function, with one argument // The underlying function is `__iomanip_' // #define __DEFINE_IOMANIP_FN1(type,param,function) \ extern ios& __iomanip_##function (ios&, param); \ inline type function (param n) \ { return type (__iomanip_##function, n); } __DEFINE_IOMANIP_FN1( smanip, int, setbase) __DEFINE_IOMANIP_FN1( smanip, int, setfill) __DEFINE_IOMANIP_FN1( smanip, int, setprecision) __DEFINE_IOMANIP_FN1( smanip, int, setw) __DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, resetiosflags) __DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, setiosflags) } // extern "C++" #endif /*!_IOMANIP_H*/ ================================================ FILE: tass-sgi-stl-2.91.57-source/iosfwd ================================================ // -*- C++ -*- I/O forward declaration header. // This file is part of the GNU ANSI C++ Library. #ifndef __IOSFWD__ #define __IOSFWD__ class ios; class streambuf; class istream; class ostream; class iostream; class filebuf; class ifstream; class ofstream; class fstream; #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/iostdio.h ================================================ /* Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 defines a stdio-like environment, except that it avoid link-time name clashes with an existing stdio. It allows for testing the libio using stdio-using programs with an incompatible libc.a. It is not predantically correct - e.g. some macros are used that may evaluate a stream argument more than once. */ #ifndef _IOSTDIO_H #define _IOSTDIO_H #include "iolibio.h" typedef _IO_FILE FILE; #ifndef EOF #define EOF (-1) #endif #ifndef BUFSIZ #define BUFSIZ 1024 #endif /* #define size_t, fpos_t L_tmpname TMP_MAX */ #define _IOFBF 0 /* Fully buffered. */ #define _IOLBF 1 /* Line buffered. */ #define _IONBF 2 /* No buffering. */ #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 #define stdin _IO_stdin #define stdout _IO_stdout #define stderr _IO_stderr #define getc(_fp) _IO_getc(_fp) #define putc(_ch, _fp) _IO_putc(_ch, _fp) #define clearerr _IO_clearerr #define fclose _IO_fclose #define feof _IO_feof #define ferror _IO_ferror #define fflush _IO_fflush #define fgetc(__fp) _IO_getc(_fp) #define fgetpos _IO_fgetpos #define fgets _IO_fgets #define fopen _IO_fopen #define fprintf _IO_fprintf #define fputc(_ch, _fp) _IO_putc(_ch, _fp) #define fputs _IO_fputs #define fread _IO_fread #define freopen _IO_freopen #define fscanf _IO_fscanf #define fseek _IO_fseek #define fsetpos _IO_fsetpos #define ftell _IO_ftell #define fwrite _IO_fwrite #define gets _IO_gets #define perror _IO_perror #define printf _IO_printf #define puts _IO_puts #define rewind _IO_rewind #define scanf _IO_scanf #define setbuf _IO_setbuf #define setbuffer _IO_setbuffer #define setvbuf _IO_setvbuf #define sprintf _IO_sprintf #define sscanf _IO_sscanf #define ungetc _IO_ungetc #define vfprintf _IO_vfprintf #define vprintf(__fmt, __args) vfprintf(stdout, __fmt, __args) #define vsprintf _IO_vsprintf #if 0 /* We can use the libc versions of these, since they don't pass FILE*s. */ #define remove ??? __P((const char*)) #define rename ??? __P((const char* _old, const char* _new)) #define tmpfile ??? __P((void)) #define tmpnam ??? __P((char*)) #endif #if !defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE) #define fdopen _IO_fdopen #define fileno _IO_fileno #define popen _IO_popen #define pclose _IO_pclose #define setbuf _IO_setbuf #define setlinebuf _IO_setlinebuf #endif #endif /* _IOSTDIO_H */ ================================================ FILE: tass-sgi-stl-2.91.57-source/iostream ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __IOSTREAM__ #define __IOSTREAM__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/iostream.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 _IOSTREAM_H #ifdef __GNUG__ #pragma interface #endif #define _IOSTREAM_H #include extern "C++" { class istream; class ostream; typedef ios& (*__manip)(ios&); typedef istream& (*__imanip)(istream&); typedef ostream& (*__omanip)(ostream&); extern istream& ws(istream& ins); extern ostream& flush(ostream& outs); extern ostream& endl(ostream& outs); extern ostream& ends(ostream& outs); class ostream : virtual public ios { // NOTE: If fields are changed, you must fix _fake_ostream in stdstreams.C! void do_osfx(); public: ostream() { } ostream(streambuf* sb, ostream* tied=NULL); int opfx() { if (!good()) return 0; else { if (_tie) _tie->flush(); _IO_flockfile(_strbuf); return 1;} } void osfx() { _IO_funlockfile(_strbuf); if (flags() & (ios::unitbuf|ios::stdio)) do_osfx(); } ostream& flush(); ostream& put(char c) { _strbuf->sputc(c); return *this; } #ifdef _STREAM_COMPAT /* Temporary binary compatibility. REMOVE IN NEXT RELEASE. */ ostream& put(unsigned char c) { return put((char)c); } ostream& put(signed char c) { return put((char)c); } #endif ostream& write(const char *s, streamsize n); ostream& write(const unsigned char *s, streamsize n) { return write((const char*)s, n);} ostream& write(const signed char *s, streamsize n) { return write((const char*)s, n);} ostream& write(const void *s, streamsize n) { return write((const char*)s, n);} ostream& seekp(streampos); ostream& seekp(streamoff, _seek_dir); streampos tellp(); ostream& form(const char *format ...); ostream& vform(const char *format, _IO_va_list args); ostream& operator<<(char c); ostream& operator<<(unsigned char c) { return (*this) << (char)c; } ostream& operator<<(signed char c) { return (*this) << (char)c; } ostream& operator<<(const char *s); ostream& operator<<(const unsigned char *s) { return (*this) << (const char*)s; } ostream& operator<<(const signed char *s) { return (*this) << (const char*)s; } ostream& operator<<(const void *p); ostream& operator<<(int n); ostream& operator<<(unsigned int n); ostream& operator<<(long n); ostream& operator<<(unsigned long n); #if defined(__GNUC__) __extension__ ostream& operator<<(long long n); __extension__ ostream& operator<<(unsigned long long n); #endif ostream& operator<<(short n) {return operator<<((int)n);} ostream& operator<<(unsigned short n) {return operator<<((unsigned int)n);} #if _G_HAVE_BOOL ostream& operator<<(bool b) { return operator<<((int)b); } #endif ostream& operator<<(double n); ostream& operator<<(float n) { return operator<<((double)n); } #if _G_HAVE_LONG_DOUBLE_IO ostream& operator<<(long double n); #else ostream& operator<<(long double n) { return operator<<((double)n); } #endif ostream& operator<<(__omanip func) { return (*func)(*this); } ostream& operator<<(__manip func) {(*func)(*this); return *this;} ostream& operator<<(streambuf*); #ifdef _STREAM_COMPAT streambuf* ostreambuf() const { return _strbuf; } #endif }; class istream : virtual public ios { // NOTE: If fields are changed, you must fix _fake_istream in stdstreams.C! protected: _IO_size_t _gcount; int _skip_ws(); public: istream(): _gcount (0) { } istream(streambuf* sb, ostream*tied=NULL); istream& get(char* ptr, int len, char delim = '\n'); istream& get(unsigned char* ptr, int len, char delim = '\n') { return get((char*)ptr, len, delim); } istream& get(char& c); istream& get(unsigned char& c) { return get((char&)c); } istream& getline(char* ptr, int len, char delim = '\n'); istream& getline(unsigned char* ptr, int len, char delim = '\n') { return getline((char*)ptr, len, delim); } istream& get(signed char& c) { return get((char&)c); } istream& get(signed char* ptr, int len, char delim = '\n') { return get((char*)ptr, len, delim); } istream& getline(signed char* ptr, int len, char delim = '\n') { return getline((char*)ptr, len, delim); } istream& read(char *ptr, streamsize n); istream& read(unsigned char *ptr, streamsize n) { return read((char*)ptr, n); } istream& read(signed char *ptr, streamsize n) { return read((char*)ptr, n); } istream& read(void *ptr, streamsize n) { return read((char*)ptr, n); } istream& get(streambuf& sb, char delim = '\n'); istream& gets(char **s, char delim = '\n'); int ipfx(int need = 0) { if (!good()) { set(ios::failbit); return 0; } else { _IO_flockfile(_strbuf); if (_tie && (need == 0 || rdbuf()->in_avail() < need)) _tie->flush(); if (!need && (flags() & ios::skipws)) return _skip_ws(); else return 1; } } int ipfx0() { // Optimized version of ipfx(0). if (!good()) { set(ios::failbit); return 0; } else { _IO_flockfile(_strbuf); if (_tie) _tie->flush(); if (flags() & ios::skipws) return _skip_ws(); else return 1; } } int ipfx1() { // Optimized version of ipfx(1). if (!good()) { set(ios::failbit); return 0; } else { _IO_flockfile(_strbuf); if (_tie && rdbuf()->in_avail() == 0) _tie->flush(); return 1; } } void isfx() { _IO_funlockfile(_strbuf); } int get() { if (!ipfx1()) return EOF; else { int ch = _strbuf->sbumpc(); if (ch == EOF) set(ios::eofbit); return ch; } } int peek(); _IO_size_t gcount() { return _gcount; } istream& ignore(int n=1, int delim = EOF); int sync (); istream& seekg(streampos); istream& seekg(streamoff, _seek_dir); streampos tellg(); istream& putback(char ch) { if (good() && _strbuf->sputbackc(ch) == EOF) clear(ios::badbit); return *this;} istream& unget() { if (good() && _strbuf->sungetc() == EOF) clear(ios::badbit); return *this;} istream& scan(const char *format ...); istream& vscan(const char *format, _IO_va_list args); #ifdef _STREAM_COMPAT istream& unget(char ch) { return putback(ch); } int skip(int i); streambuf* istreambuf() const { return _strbuf; } #endif istream& operator>>(char*); istream& operator>>(unsigned char* p) { return operator>>((char*)p); } istream& operator>>(signed char*p) { return operator>>((char*)p); } istream& operator>>(char& c); istream& operator>>(unsigned char& c) {return operator>>((char&)c);} istream& operator>>(signed char& c) {return operator>>((char&)c);} istream& operator>>(int&); istream& operator>>(long&); #if defined(__GNUC__) __extension__ istream& operator>>(long long&); __extension__ istream& operator>>(unsigned long long&); #endif istream& operator>>(short&); istream& operator>>(unsigned int&); istream& operator>>(unsigned long&); istream& operator>>(unsigned short&); #if _G_HAVE_BOOL istream& operator>>(bool&); #endif istream& operator>>(float&); istream& operator>>(double&); istream& operator>>(long double&); istream& operator>>( __manip func) {(*func)(*this); return *this;} istream& operator>>(__imanip func) { return (*func)(*this); } istream& operator>>(streambuf*); }; class iostream : public istream, public ostream { public: iostream() { } iostream(streambuf* sb, ostream*tied=NULL); }; class _IO_istream_withassign : public istream { public: _IO_istream_withassign& operator=(istream&); _IO_istream_withassign& operator=(_IO_istream_withassign& rhs) { return operator= (static_cast (rhs)); } }; class _IO_ostream_withassign : public ostream { public: _IO_ostream_withassign& operator=(ostream&); _IO_ostream_withassign& operator=(_IO_ostream_withassign& rhs) { return operator= (static_cast (rhs)); } }; extern _IO_istream_withassign cin; // clog->rdbuf() == cerr->rdbuf() extern _IO_ostream_withassign cout, cerr; extern _IO_ostream_withassign clog #if _G_CLOG_CONFLICT __asm__ ("__IO_clog") #endif ; extern istream& lock(istream& ins); extern istream& unlock(istream& ins); extern ostream& lock(ostream& outs); extern ostream& unlock(ostream& outs); struct Iostream_init { } ; // Compatibility hack for AT&T library. inline ios& dec(ios& i) { i.setf(ios::dec, ios::dec|ios::hex|ios::oct); return i; } inline ios& hex(ios& i) { i.setf(ios::hex, ios::dec|ios::hex|ios::oct); return i; } inline ios& oct(ios& i) { i.setf(ios::oct, ios::dec|ios::hex|ios::oct); return i; } } // extern "C++" #endif /*!_IOSTREAM_H*/ ================================================ FILE: tass-sgi-stl-2.91.57-source/iostreamP.h ================================================ /* Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 "streambuf.h" #include "libioP.h" ================================================ FILE: tass-sgi-stl-2.91.57-source/istream.h ================================================ /* Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 ================================================ FILE: tass-sgi-stl-2.91.57-source/iterator ================================================ /* * * 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 __SGI_STL_ITERATOR #define __SGI_STL_ITERATOR #include #include #include #include #include #endif /* __SGI_STL_ITERATOR */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/iterator.h ================================================ /* * * 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 __SGI_STL_ITERATOR_H #define __SGI_STL_ITERATOR_H #ifndef __SGI_STL_FUNCTION_H #include #endif #include #include #ifndef __SGI_STL_INTERNAL_ITERATOR_H #include #endif #ifndef __TYPE_TRAITS_H #include #endif #ifndef __SGI_STL_INTERNAL_CONSTRUCT_H #include #endif #ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H #include #endif #ifdef __STL_USE_NAMESPACES // 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 using __STD::input_iterator; using __STD::output_iterator; using __STD::forward_iterator; using __STD::bidirectional_iterator; using __STD::random_access_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION using __STD::iterator_traits; #endif using __STD::iterator_category; using __STD::distance_type; using __STD::value_type; using __STD::distance; 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::reverse_bidirectional_iterator; using __STD::istream_iterator; using __STD::ostream_iterator; // Names from stl_construct.h using __STD::construct; using __STD::destroy; // Names from stl_raw_storage_iter.h using __STD::raw_storage_iterator; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ITERATOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/libio.h ================================================ /* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc. This file is part of the GNU IO Library. Written by Per Bothner . This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 _IO_STDIO_H #define _IO_STDIO_H #include <_G_config.h> #define _IO_pos_t _G_fpos_t /* obsolete */ #define _IO_fpos_t _G_fpos_t #define _IO_size_t _G_size_t #define _IO_ssize_t _G_ssize_t #define _IO_off_t _G_off_t #define _IO_pid_t _G_pid_t #define _IO_uid_t _G_uid_t #define _IO_HAVE_SYS_WAIT _G_HAVE_SYS_WAIT #define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE #define _IO_BUFSIZ _G_BUFSIZ #define _IO_va_list _G_va_list #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 #define _IO_fpos64_t _G_fpos64_t #define _IO_off64_t _G_off64_t #endif #ifdef _G_NEED_STDARG_H /* This define avoids name pollution if we're using GNU stdarg.h */ # define __need___va_list # include # ifdef __GNUC_VA_LIST # undef _IO_va_list # define _IO_va_list __gnuc_va_list # endif /* __GNUC_VA_LIST */ #endif #ifndef __P # if _G_HAVE_SYS_CDEFS # include # else # ifdef __STDC__ # define __P(p) p # else # define __P(p) () # endif # endif #endif /*!__P*/ /* For backward compatibility */ #ifndef _PARAMS # define _PARAMS(protos) __P(protos) #endif /*!_PARAMS*/ #ifndef __STDC__ # define const #endif #define _IO_UNIFIED_JUMPTABLES 1 #if !_G_HAVE_PRINTF_FP # define _IO_USE_DTOA 1 #endif #ifndef EOF # define EOF (-1) #endif #ifndef NULL # if defined __GNUG__ && \ (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) # define NULL (__null) # else # if !defined(__cplusplus) # define NULL ((void*)0) # else # define NULL (0) # endif # endif #endif #define _IOS_INPUT 1 #define _IOS_OUTPUT 2 #define _IOS_ATEND 4 #define _IOS_APPEND 8 #define _IOS_TRUNC 16 #define _IOS_NOCREATE 32 #define _IOS_NOREPLACE 64 #define _IOS_BIN 128 /* Magic numbers and bits for the _flags field. The magic numbers use the high-order bits of _flags; the remaining bits are available for variable flags. Note: The magic numbers must all be negative if stdio emulation is desired. */ #define _IO_MAGIC 0xFBAD0000 /* Magic number */ #define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */ #define _IO_MAGIC_MASK 0xFFFF0000 #define _IO_USER_BUF 1 /* User owns buffer; don't delete it on close. */ #define _IO_UNBUFFERED 2 #define _IO_NO_READS 4 /* Reading not allowed */ #define _IO_NO_WRITES 8 /* Writing not allowd */ #define _IO_EOF_SEEN 0x10 #define _IO_ERR_SEEN 0x20 #define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */ #define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/ #define _IO_IN_BACKUP 0x100 #define _IO_LINE_BUF 0x200 #define _IO_TIED_PUT_GET 0x400 /* Set if put and get pointer logicly tied. */ #define _IO_CURRENTLY_PUTTING 0x800 #define _IO_IS_APPENDING 0x1000 #define _IO_IS_FILEBUF 0x2000 #define _IO_BAD_SEEN 0x4000 /* These are "formatting flags" matching the iostream fmtflags enum values. */ #define _IO_SKIPWS 01 #define _IO_LEFT 02 #define _IO_RIGHT 04 #define _IO_INTERNAL 010 #define _IO_DEC 020 #define _IO_OCT 040 #define _IO_HEX 0100 #define _IO_SHOWBASE 0200 #define _IO_SHOWPOINT 0400 #define _IO_UPPERCASE 01000 #define _IO_SHOWPOS 02000 #define _IO_SCIENTIFIC 04000 #define _IO_FIXED 010000 #define _IO_UNITBUF 020000 #define _IO_STDIO 040000 #define _IO_DONT_CLOSE 0100000 #define _IO_BOOLALPHA 0200000 struct _IO_jump_t; struct _IO_FILE; /* Handle lock. */ #ifdef _IO_MTSAFE_IO # if defined __GLIBC__ && __GLIBC__ >= 2 # if __GLIBC_MINOR__ > 0 # include # else # include # endif # define _IO_LOCK_T _IO_lock_t * # else /*# include */ # endif #else # if defined(__GLIBC__) && __GLIBC__ >= 2 typedef void _IO_lock_t; # define _IO_LOCK_T void * # else # ifdef __linux__ struct _IO_lock_t { void *ptr; short int field1; short int field2; }; # define _IO_LOCK_T struct _IO_lock_t # else typedef void _IO_lock_t; # endif # endif #endif /* A streammarker remembers a position in a buffer. */ struct _IO_marker { struct _IO_marker *_next; struct _IO_FILE *_sbuf; /* If _pos >= 0 it points to _buf->Gbase()+_pos. FIXME comment */ /* if _pos < 0, it points to _buf->eBptr()+_pos. FIXME comment */ int _pos; #if 0 void set_streampos(streampos sp) { _spos = sp; } void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); } public: streammarker(streambuf *sb); ~streammarker(); int saving() { return _spos == -2; } int delta(streammarker&); int delta(); #endif }; struct _IO_FILE { int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ #define _IO_file_flags _flags /* The following pointers correspond to the C++ streambuf protocol. */ /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ char* _IO_read_ptr; /* Current read pointer */ char* _IO_read_end; /* End of get area. */ char* _IO_read_base; /* Start of putback+get area. */ char* _IO_write_base; /* Start of put area. */ char* _IO_write_ptr; /* Current put pointer. */ char* _IO_write_end; /* End of put area. */ char* _IO_buf_base; /* Start of reserve area. */ char* _IO_buf_end; /* End of reserve area. */ /* The following fields are used to support backing up and undo. */ char *_IO_save_base; /* Pointer to start of non-current get area. */ char *_IO_backup_base; /* Pointer to first valid character of backup area */ char *_IO_save_end; /* Pointer to end of non-current get area. */ struct _IO_marker *_markers; struct _IO_FILE *_chain; int _fileno; int _blksize; #ifdef _G_IO_IO_FILE_VERSION _IO_off_t _old_offset; #else _IO_off_t _offset; #endif #define __HAVE_COLUMN /* temporary */ /* 1+column number of pbase(); 0 is unknown. */ unsigned short _cur_column; char _unused; char _shortbuf[1]; /* char* _save_gptr; char* _save_egptr; */ #ifdef _IO_LOCK_T _IO_LOCK_T _lock; #endif #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 _IO_off64_t _offset; int _unused2[16]; /* Make sure we don't get into trouble again. */ #endif }; #ifndef __cplusplus typedef struct _IO_FILE _IO_FILE; #endif #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 #define _IO_stdin_ _IO_2_1_stdin_ #define _IO_stdout_ _IO_2_1_stdout_ #define _IO_stderr_ _IO_2_1_stderr_ #endif struct _IO_FILE_plus; extern struct _IO_FILE_plus _IO_stdin_, _IO_stdout_, _IO_stderr_; #define _IO_stdin ((_IO_FILE*)(&_IO_stdin_)) #define _IO_stdout ((_IO_FILE*)(&_IO_stdout_)) #define _IO_stderr ((_IO_FILE*)(&_IO_stderr_)) /* Define the user-visible type, with user-friendly member names. */ typedef struct { _IO_ssize_t (*read) __P ((struct _IO_FILE *, void *, _IO_ssize_t)); _IO_ssize_t (*write) __P ((struct _IO_FILE *, const void *, _IO_ssize_t)); _IO_fpos_t (*seek) __P ((struct _IO_FILE *, _IO_off_t, int)); int (*close) __P ((struct _IO_FILE *)); } _IO_cookie_io_functions_t; /* Special file type for fopencookie function. */ struct _IO_cookie_file { struct _IO_FILE file; const void *vtable; void *cookie; _IO_cookie_io_functions_t io_functions; }; #ifdef __cplusplus extern "C" { #endif extern int __underflow __P ((_IO_FILE *)); extern int __uflow __P ((_IO_FILE *)); extern int __overflow __P ((_IO_FILE *, int)); #define _IO_getc_unlocked(_fp) \ ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end ? __uflow (_fp) \ : *(unsigned char *) (_fp)->_IO_read_ptr++) #define _IO_peekc_unlocked(_fp) \ ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end \ && __underflow (_fp) == EOF ? EOF \ : *(unsigned char *) (_fp)->_IO_read_ptr) #define _IO_putc_unlocked(_ch, _fp) \ (((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end) \ ? __overflow (_fp, (unsigned char) (_ch)) \ : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch))) #define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0) #define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0) extern int _IO_getc __P ((_IO_FILE *__fp)); extern int _IO_putc __P ((int __c, _IO_FILE *__fp)); extern int _IO_feof __P ((_IO_FILE *__fp)); extern int _IO_ferror __P ((_IO_FILE *__fp)); extern int _IO_peekc_locked __P ((_IO_FILE *__fp)); /* This one is for Emacs. */ #define _IO_PENDING_OUTPUT_COUNT(_fp) \ ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base) extern void _IO_flockfile __P ((_IO_FILE *)); extern void _IO_funlockfile __P ((_IO_FILE *)); extern int _IO_ftrylockfile __P ((_IO_FILE *)); #ifdef _IO_MTSAFE_IO # define _IO_peekc(_fp) _IO_peekc_locked (_fp) #else # define _IO_peekc(_fp) _IO_peekc_unlocked (_fp) # define _IO_flockfile(_fp) /**/ # define _IO_funlockfile(_fp) /**/ # define _IO_ftrylockfile(_fp) /**/ # define _IO_cleanup_region_start(_fct, _fp) /**/ # define _IO_cleanup_region_end(_Doit) /**/ #endif /* !_IO_MTSAFE_IO */ extern int _IO_vfscanf __P ((_IO_FILE *, const char *, _IO_va_list, int *)); extern int _IO_vfprintf __P ((_IO_FILE *, const char *, _IO_va_list)); extern _IO_ssize_t _IO_padn __P ((_IO_FILE *, int, _IO_ssize_t)); extern _IO_size_t _IO_sgetn __P ((_IO_FILE *, void *, _IO_size_t)); #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 extern _IO_fpos64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); extern _IO_fpos64_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos64_t, int)); #else extern _IO_fpos_t _IO_seekoff __P ((_IO_FILE *, _IO_off_t, int, int)); extern _IO_fpos_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos_t, int)); #endif extern void _IO_free_backup_area __P ((_IO_FILE *)); #ifdef __cplusplus } #endif #endif /* _IO_STDIO_H */ ================================================ FILE: tass-sgi-stl-2.91.57-source/libioP.h ================================================ /* Copyright (C) 1993, 1997 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 #ifndef __set_errno # define __set_errno(Val) errno = (Val) #endif #if defined __GLIBC__ && __GLIBC__ >= 2 # if __GLIBC_MINOR__ > 0 # include # else # include # endif #else /*# include */ #endif #include "iolibio.h" #ifdef __cplusplus extern "C" { #endif #define _IO_seek_set 0 #define _IO_seek_cur 1 #define _IO_seek_end 2 /* THE JUMPTABLE FUNCTIONS. * The _IO_FILE type is used to implement the FILE type in GNU libc, * as well as the streambuf class in GNU iostreams for C++. * These are all the same, just used differently. * An _IO_FILE (or FILE) object is allows followed by a pointer to * a jump table (of pointers to functions). The pointer is accessed * with the _IO_JUMPS macro. The jump table has a eccentric format, * so as to be compatible with the layout of a C++ virtual function table. * (as implemented by g++). When a pointer to a streambuf object is * coerced to an (_IO_FILE*), then _IO_JUMPS on the result just * happens to point to the virtual function table of the streambuf. * Thus the _IO_JUMPS function table used for C stdio/libio does * double duty as the virtual function table for C++ streambuf. * * The entries in the _IO_JUMPS function table (and hence also the * virtual functions of a streambuf) are described below. * The first parameter of each function entry is the _IO_FILE/streambuf * object being acted on (i.e. the 'this' parameter). */ #define _IO_JUMPS(THIS) ((struct _IO_FILE_plus *) (THIS))->vtable #ifdef _G_USING_THUNKS # define JUMP_FIELD(TYPE, NAME) TYPE NAME # define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC (THIS) # define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC (THIS, X1) # define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC (THIS, X1, X2) # define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC (THIS, X1,X2, X3) # define JUMP_INIT(NAME, VALUE) VALUE # define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0), JUMP_INIT (dummy2, 0) #else /* These macros will change when we re-implement vtables to use "thunks"! */ # define JUMP_FIELD(TYPE, NAME) struct { short delta1, delta2; TYPE pfn; } NAME # define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC.pfn (THIS) # define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1) # define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1, X2) # define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1,X2,X3) # define JUMP_INIT(NAME, VALUE) {0, 0, VALUE} # define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0) #endif /* The 'finish' function does any final cleaning up of an _IO_FILE object. It does not delete (free) it, but does everything else to finalize it/ It matches the streambuf::~streambuf virtual destructor. */ typedef void (*_IO_finish_t) __P ((_IO_FILE *, int)); /* finalize */ #define _IO_FINISH(FP) JUMP1 (__finish, FP, 0) /* The 'overflow' hook flushes the buffer. The second argument is a character, or EOF. It matches the streambuf::overflow virtual function. */ typedef int (*_IO_overflow_t) __P ((_IO_FILE *, int)); #define _IO_OVERFLOW(FP, CH) JUMP1 (__overflow, FP, CH) /* The 'underflow' hook tries to fills the get buffer. It returns the next character (as an unsigned char) or EOF. The next character remains in the get buffer, and the get position is not changed. It matches the streambuf::underflow virtual function. */ typedef int (*_IO_underflow_t) __P ((_IO_FILE *)); #define _IO_UNDERFLOW(FP) JUMP0 (__underflow, FP) /* The 'uflow' hook returns the next character in the input stream (cast to unsigned char), and increments the read position; EOF is returned on failure. It matches the streambuf::uflow virtual function, which is not in the cfront implementation, but was added to C++ by the ANSI/ISO committee. */ #define _IO_UFLOW(FP) JUMP0 (__uflow, FP) /* The 'pbackfail' hook handles backing up. It matches the streambuf::pbackfail virtual function. */ typedef int (*_IO_pbackfail_t) __P ((_IO_FILE *, int)); #define _IO_PBACKFAIL(FP, CH) JUMP1 (__pbackfail, FP, CH) /* The 'xsputn' hook writes upto N characters from buffer DATA. Returns the number of character actually written. It matches the streambuf::xsputn virtual function. */ typedef _IO_size_t (*_IO_xsputn_t) __P ((_IO_FILE *FP, const void *DATA, _IO_size_t N)); #define _IO_XSPUTN(FP, DATA, N) JUMP2 (__xsputn, FP, DATA, N) /* The 'xsgetn' hook reads upto N characters into buffer DATA. Returns the number of character actually read. It matches the streambuf::xsgetn virtual function. */ typedef _IO_size_t (*_IO_xsgetn_t) __P ((_IO_FILE *FP, void *DATA, _IO_size_t N)); #define _IO_XSGETN(FP, DATA, N) JUMP2 (__xsgetn, FP, DATA, N) /* The 'seekoff' hook moves the stream position to a new position relative to the start of the file (if DIR==0), the current position (MODE==1), or the end of the file (MODE==2). It matches the streambuf::seekoff virtual function. It is also used for the ANSI fseek function. */ #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 typedef _IO_fpos64_t (*_IO_seekoff_t) __P ((_IO_FILE *FP, _IO_off64_t OFF, int DIR, int MODE)); #else typedef _IO_fpos_t (*_IO_seekoff_t) __P ((_IO_FILE *FP, _IO_off_t OFF, int DIR, int MODE)); #endif #define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3 (__seekoff, FP, OFF, DIR, MODE) /* The 'seekpos' hook also moves the stream position, but to an absolute position given by a fpos_t (seekpos). It matches the streambuf::seekpos virtual function. It is also used for the ANSI fgetpos and fsetpos functions. */ /* The _IO_seek_cur and _IO_seek_end options are not allowed. */ #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 typedef _IO_fpos64_t (*_IO_seekpos_t) __P ((_IO_FILE *, _IO_fpos64_t, int)); #else typedef _IO_fpos_t (*_IO_seekpos_t) __P ((_IO_FILE *, _IO_fpos_t, int)); #endif #define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2 (__seekpos, FP, POS, FLAGS) /* The 'setbuf' hook gives a buffer to the file. It matches the streambuf::setbuf virtual function. */ typedef _IO_FILE* (*_IO_setbuf_t) __P ((_IO_FILE *, char *, _IO_ssize_t)); #define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2 (__setbuf, FP, BUFFER, LENGTH) /* The 'sync' hook attempts to synchronize the internal data structures of the file with the external state. It matches the streambuf::sync virtual function. */ typedef int (*_IO_sync_t) __P ((_IO_FILE *)); #define _IO_SYNC(FP) JUMP0 (__sync, FP) /* The 'doallocate' hook is used to tell the file to allocate a buffer. It matches the streambuf::doallocate virtual function, which is not in the ANSI/ISO C++ standard, but is part traditional implementations. */ typedef int (*_IO_doallocate_t) __P ((_IO_FILE *)); #define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP) /* The following four hooks (sysread, syswrite, sysclose, sysseek, and sysstat) are low-level hooks specific to this implementation. There is no correspondence in the ANSI/ISO C++ standard library. The hooks basically correspond to the Unix system functions (read, write, close, lseek, and stat) except that a _IO_FILE* parameter is used instead of a integer file descriptor; the default implementation used for normal files just calls those functions. The advantage of overriding these functions instead of the higher-level ones (underflow, overflow etc) is that you can leave all the buffering higher-level functions. */ /* The 'sysread' hook is used to read data from the external file into an existing buffer. It generalizes the Unix read(2) function. It matches the streambuf::sys_read virtual function, which is specific to this implementation. */ typedef _IO_ssize_t (*_IO_read_t) __P ((_IO_FILE *, void *, _IO_ssize_t)); #define _IO_SYSREAD(FP, DATA, LEN) JUMP2 (__read, FP, DATA, LEN) /* The 'syswrite' hook is used to write data from an existing buffer to an external file. It generalizes the Unix write(2) function. It matches the streambuf::sys_write virtual function, which is specific to this implementation. */ typedef _IO_ssize_t (*_IO_write_t) __P ((_IO_FILE *,const void *,_IO_ssize_t)); #define _IO_SYSWRITE(FP, DATA, LEN) JUMP2 (__write, FP, DATA, LEN) /* The 'sysseek' hook is used to re-position an external file. It generalizes the Unix lseek(2) function. It matches the streambuf::sys_seek virtual function, which is specific to this implementation. */ #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 typedef _IO_fpos64_t (*_IO_seek_t) __P ((_IO_FILE *, _IO_off64_t, int)); #else typedef _IO_fpos_t (*_IO_seek_t) __P ((_IO_FILE *, _IO_off_t, int)); #endif #define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2 (__seek, FP, OFFSET, MODE) /* The 'sysclose' hook is used to finalize (close, finish up) an external file. It generalizes the Unix close(2) function. It matches the streambuf::sys_close virtual function, which is specific to this implementation. */ typedef int (*_IO_close_t) __P ((_IO_FILE *)); /* finalize */ #define _IO_SYSCLOSE(FP) JUMP0 (__close, FP) /* The 'sysstat' hook is used to get information about an external file into a struct stat buffer. It generalizes the Unix fstat(2) call. It matches the streambuf::sys_stat virtual function, which is specific to this implementation. */ typedef int (*_IO_stat_t) __P ((_IO_FILE *, void *)); #define _IO_SYSSTAT(FP, BUF) JUMP1 (__stat, FP, BUF) #if _G_IO_IO_FILE_VERSION == 0x20001 /* The 'showmany' hook can be used to get an image how much input is available. In many cases the answer will be 0 which means unknown but some cases one can provide real information. */ typedef int (*_IO_showmanyc_t) __P ((_IO_FILE *)); #define _IO_SHOWMANYC(FP) JUMP0 (__showmanyc, FP) /* The 'imbue' hook is used to get information about the currently installed locales. */ typedef void (*_IO_imbue_t) __P ((_IO_FILE *, void *)); #define _IO_IMBUE(FP, LOCALE) JUMP1 (__imbue, FP, LOCALE) #endif #define _IO_CHAR_TYPE char /* unsigned char ? */ #define _IO_INT_TYPE int struct _IO_jump_t { JUMP_FIELD(_G_size_t, __dummy); #ifdef _G_USING_THUNKS JUMP_FIELD(_G_size_t, __dummy2); #endif JUMP_FIELD(_IO_finish_t, __finish); JUMP_FIELD(_IO_overflow_t, __overflow); JUMP_FIELD(_IO_underflow_t, __underflow); JUMP_FIELD(_IO_underflow_t, __uflow); JUMP_FIELD(_IO_pbackfail_t, __pbackfail); /* showmany */ JUMP_FIELD(_IO_xsputn_t, __xsputn); JUMP_FIELD(_IO_xsgetn_t, __xsgetn); JUMP_FIELD(_IO_seekoff_t, __seekoff); JUMP_FIELD(_IO_seekpos_t, __seekpos); JUMP_FIELD(_IO_setbuf_t, __setbuf); JUMP_FIELD(_IO_sync_t, __sync); JUMP_FIELD(_IO_doallocate_t, __doallocate); JUMP_FIELD(_IO_read_t, __read); JUMP_FIELD(_IO_write_t, __write); JUMP_FIELD(_IO_seek_t, __seek); JUMP_FIELD(_IO_close_t, __close); JUMP_FIELD(_IO_stat_t, __stat); #if _G_IO_IO_FILE_VERSION == 0x20001 JUMP_FIELD(_IO_showmanyc_t, __showmanyc); JUMP_FIELD(_IO_imbue_t, __imbue); #endif #if 0 get_column; set_column; #endif }; /* We always allocate an extra word following an _IO_FILE. This contains a pointer to the function jump table used. This is for compatibility with C++ streambuf; the word can be used to smash to a pointer to a virtual function table. */ struct _IO_FILE_plus { _IO_FILE file; const struct _IO_jump_t *vtable; }; /* Generic functions */ #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 extern _IO_fpos64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); extern _IO_fpos64_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos64_t, int)); #else extern _IO_fpos_t _IO_seekoff __P ((_IO_FILE *, _IO_off_t, int, int)); extern _IO_fpos_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos_t, int)); #endif extern void _IO_switch_to_main_get_area __P ((_IO_FILE *)); extern void _IO_switch_to_backup_area __P ((_IO_FILE *)); extern int _IO_switch_to_get_mode __P ((_IO_FILE *)); extern void _IO_init __P ((_IO_FILE *, int)); extern int _IO_sputbackc __P ((_IO_FILE *, int)); extern int _IO_sungetc __P ((_IO_FILE *)); extern void _IO_un_link __P ((_IO_FILE *)); extern void _IO_link_in __P ((_IO_FILE *)); extern void _IO_doallocbuf __P ((_IO_FILE *)); extern void _IO_unsave_markers __P ((_IO_FILE *)); extern void _IO_setb __P ((_IO_FILE *, char *, char *, int)); extern unsigned _IO_adjust_column __P ((unsigned, const char *, int)); #define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n) /* Marker-related function. */ extern void _IO_init_marker __P ((struct _IO_marker *, _IO_FILE *)); extern void _IO_remove_marker __P ((struct _IO_marker *)); extern int _IO_marker_difference __P ((struct _IO_marker *, struct _IO_marker *)); extern int _IO_marker_delta __P ((struct _IO_marker *)); extern int _IO_seekmark __P ((_IO_FILE *, struct _IO_marker *, int)); /* Default jumptable functions. */ extern int _IO_default_underflow __P ((_IO_FILE *)); extern int _IO_default_uflow __P ((_IO_FILE *)); extern int _IO_default_doallocate __P ((_IO_FILE *)); extern void _IO_default_finish __P ((_IO_FILE *, int)); extern int _IO_default_pbackfail __P ((_IO_FILE *, int)); extern _IO_FILE* _IO_default_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); extern _IO_size_t _IO_default_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); extern _IO_size_t _IO_default_xsgetn __P ((_IO_FILE *, void *, _IO_size_t)); #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 extern _IO_fpos64_t _IO_default_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); extern _IO_fpos64_t _IO_default_seekpos __P ((_IO_FILE *, _IO_fpos64_t, int)); #else extern _IO_fpos_t _IO_default_seekoff __P ((_IO_FILE *, _IO_off_t, int, int)); extern _IO_fpos_t _IO_default_seekpos __P ((_IO_FILE *, _IO_fpos_t, int)); #endif extern _IO_ssize_t _IO_default_write __P ((_IO_FILE *, const void *, _IO_ssize_t)); extern _IO_ssize_t _IO_default_read __P ((_IO_FILE *, void *, _IO_ssize_t)); extern int _IO_default_stat __P ((_IO_FILE *, void *)); #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 extern _IO_fpos64_t _IO_default_seek __P ((_IO_FILE *, _IO_off64_t, int)); #else extern _IO_fpos_t _IO_default_seek __P ((_IO_FILE *, _IO_off_t, int)); #endif extern int _IO_default_sync __P ((_IO_FILE *)); #define _IO_default_close ((_IO_close_t) _IO_default_sync) extern struct _IO_jump_t _IO_file_jumps; extern struct _IO_jump_t _IO_streambuf_jumps; extern struct _IO_jump_t _IO_proc_jumps; extern struct _IO_jump_t _IO_str_jumps; extern int _IO_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); extern int _IO_flush_all __P ((void)); extern void _IO_cleanup __P ((void)); extern void _IO_flush_all_linebuffered __P ((void)); #define _IO_do_flush(_f) \ _IO_do_write(_f, (_f)->_IO_write_base, \ (_f)->_IO_write_ptr-(_f)->_IO_write_base) #define _IO_in_put_mode(_fp) ((_fp)->_flags & _IO_CURRENTLY_PUTTING) #define _IO_mask_flags(fp, f, mask) \ ((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask))) #define _IO_setg(fp, eb, g, eg) ((fp)->_IO_read_base = (eb),\ (fp)->_IO_read_ptr = (g), (fp)->_IO_read_end = (eg)) #define _IO_setp(__fp, __p, __ep) \ ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr = __p, (__fp)->_IO_write_end = (__ep)) #define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL) #define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP) #define _IO_have_markers(fp) ((fp)->_markers != NULL) #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base) /* Jumptable functions for files. */ extern int _IO_file_doallocate __P ((_IO_FILE *)); extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 extern _IO_fpos64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); extern _IO_fpos64_t _IO_file_seek __P ((_IO_FILE *, _IO_off64_t, int)); #else extern _IO_fpos_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off_t, int, int)); extern _IO_fpos_t _IO_file_seek __P ((_IO_FILE *, _IO_off_t, int)); #endif extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); extern int _IO_file_stat __P ((_IO_FILE *, void *)); extern int _IO_file_close __P ((_IO_FILE *)); extern int _IO_file_underflow __P ((_IO_FILE *)); extern int _IO_file_overflow __P ((_IO_FILE *, int)); #define _IO_file_is_open(__fp) ((__fp)->_fileno >= 0) extern void _IO_file_init __P ((_IO_FILE *)); extern _IO_FILE* _IO_file_attach __P ((_IO_FILE *, int)); extern _IO_FILE* _IO_file_open __P ((_IO_FILE *, const char *, int, int, int, int)); #if _G_IO_IO_FILE_VERSION == 0x20001 extern _IO_FILE* _IO_file_fopen __P ((_IO_FILE *, const char *, const char *, int)); #else extern _IO_FILE* _IO_file_fopen __P ((_IO_FILE *, const char *, const char *)); #endif extern _IO_ssize_t _IO_file_write __P ((_IO_FILE *, const void *, _IO_ssize_t)); extern _IO_ssize_t _IO_file_read __P ((_IO_FILE *, void *, _IO_ssize_t)); extern int _IO_file_sync __P ((_IO_FILE *)); extern int _IO_file_close_it __P ((_IO_FILE *)); extern void _IO_file_finish __P ((_IO_FILE *, int)); /* Jumptable functions for proc_files. */ extern _IO_FILE* _IO_proc_open __P ((_IO_FILE *, const char *, const char *)); extern int _IO_proc_close __P ((_IO_FILE *)); /* Jumptable functions for strfiles. */ extern int _IO_str_underflow __P ((_IO_FILE *)); extern int _IO_str_overflow __P ((_IO_FILE *, int)); extern int _IO_str_pbackfail __P ((_IO_FILE *, int)); #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 extern _IO_fpos64_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); #else extern _IO_fpos_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off_t, int, int)); #endif extern void _IO_str_finish __P ((_IO_FILE *, int)); /* Other strfile functions */ extern void _IO_str_init_static __P ((_IO_FILE *, char *, int, char *)); extern void _IO_str_init_readonly __P ((_IO_FILE *, const char *, int)); extern _IO_ssize_t _IO_str_count __P ((_IO_FILE *)); extern int _IO_vasprintf __P ((char **result_ptr, __const char *format, _IO_va_list args)); extern int _IO_vdprintf __P ((int d, __const char *format, _IO_va_list arg)); extern int _IO_vsnprintf __P ((char *string, _IO_size_t maxlen, __const char *format, _IO_va_list args)); extern _IO_size_t _IO_getline __P ((_IO_FILE *,char *, _IO_size_t, int, int)); extern _IO_size_t _IO_getline_info __P ((_IO_FILE *,char *, _IO_size_t, int, int, int *)); extern _IO_ssize_t _IO_getdelim __P ((char **, _IO_size_t *, int, _IO_FILE *)); extern double _IO_strtod __P ((const char *, char **)); extern char *_IO_dtoa __P ((double __d, int __mode, int __ndigits, int *__decpt, int *__sign, char **__rve)); extern int _IO_outfloat __P ((double __value, _IO_FILE *__sb, int __type, int __width, int __precision, int __flags, int __sign_mode, int __fill)); extern _IO_FILE *_IO_list_all; extern void (*_IO_cleanup_registration_needed) __P ((void)); #ifndef EOF # define EOF (-1) #endif #ifndef NULL # if defined __GNUG__ && \ (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) # define NULL (__null) # else # if !defined(__cplusplus) # define NULL ((void*)0) # else # define NULL (0) # endif # endif #endif #if _G_HAVE_MMAP # include # include # include # include # if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) # define MAP_ANONYMOUS MAP_ANON # endif # if !defined(MAP_ANONYMOUS) || !defined(EXEC_PAGESIZE) # undef _G_HAVE_MMAP # define _G_HAVE_MMAP 0 # endif #endif /* _G_HAVE_MMAP */ #if _G_HAVE_MMAP # ifdef _LIBC /* When using this code in the GNU libc we must not pollute the name space. */ # define mmap __mmap # define munmap __munmap # endif # define ROUND_TO_PAGE(_S) \ (((_S) + EXEC_PAGESIZE - 1) & ~(EXEC_PAGESIZE - 1)) # define FREE_BUF(_B, _S) \ munmap ((_B), ROUND_TO_PAGE (_S)) # define ALLOC_BUF(_B, _S, _R) \ do { \ (_B) = (char *) mmap (0, ROUND_TO_PAGE (_S), \ PROT_READ | PROT_WRITE, \ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ if ((_B) == (char *) -1) \ return (_R); \ } while (0) #else /* _G_HAVE_MMAP */ # define FREE_BUF(_B, _S) \ free(_B) # define ALLOC_BUF(_B, _S, _R) \ do { \ (_B) = (char*)malloc(_S); \ if ((_B) == NULL) \ return (_R); \ } while (0) #endif /* _G_HAVE_MMAP */ #ifndef OS_FSTAT # define OS_FSTAT fstat #endif struct stat; extern _IO_ssize_t _IO_read __P ((int, void *, _IO_size_t)); extern _IO_ssize_t _IO_write __P ((int, const void *, _IO_size_t)); extern _IO_off_t _IO_lseek __P ((int, _IO_off_t, int)); extern int _IO_close __P ((int)); extern int _IO_fstat __P ((int, struct stat *)); extern int _IO_vscanf __P ((const char *, _IO_va_list)); /* Operations on _IO_fpos_t. Normally, these are trivial, but we provide hooks for configurations where an _IO_fpos_t is a struct. Note that _IO_off_t must be an integral type. */ /* _IO_pos_BAD is an _IO_fpos_t value indicating error, unknown, or EOF. */ #ifndef _IO_pos_BAD # if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 # define _IO_pos_BAD ((_IO_fpos64_t) -1) # else # define _IO_pos_BAD ((_IO_fpos_t) -1) # endif #endif /* _IO_pos_as_off converts an _IO_fpos_t value to an _IO_off_t value. */ #ifndef _IO_pos_as_off # if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 # define _IO_pos_as_off(__pos) ((_IO_off64_t) (__pos)) # else # define _IO_pos_as_off(__pos) ((_IO_off_t) (__pos)) # endif #endif /* _IO_pos_adjust adjust an _IO_fpos_t by some number of bytes. */ #ifndef _IO_pos_adjust # define _IO_pos_adjust(__pos, __delta) ((__pos) += (__delta)) #endif /* _IO_pos_0 is an _IO_fpos_t value indicating beginning of file. */ #ifndef _IO_pos_0 # if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 # define _IO_pos_0 ((_IO_fpos64_t) 0) # else # define _IO_pos_0 ((_IO_fpos_t) 0) # endif #endif #ifdef __cplusplus } #endif #ifdef _IO_MTSAFE_IO /* check following! */ # define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \ 0, 0, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock } #else /* check following! */ # define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD } #endif /* VTABLE_LABEL defines NAME as of the CLASS class. CNLENGTH is strlen(#CLASS). */ #ifdef __GNUC__ # if _G_VTABLE_LABEL_HAS_LENGTH # define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \ extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CNLENGTH #CLASS); # else # define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \ extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CLASS); # endif #endif /* __GNUC__ */ #if !defined(builtinbuf_vtable) && defined(__cplusplus) # ifdef __GNUC__ VTABLE_LABEL(builtinbuf_vtable, builtinbuf, 10) # else # if _G_VTABLE_LABEL_HAS_LENGTH # define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##10builtinbuf # else # define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##builtinbuf # endif # endif #endif /* !defined(builtinbuf_vtable) && defined(__cplusplus) */ #if defined(__STDC__) || defined(__cplusplus) # define _IO_va_start(args, last) va_start(args, last) #else # define _IO_va_start(args, last) va_start(args) #endif extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf; #if 1 # define COERCE_FILE(FILE) /* Nothing */ #else /* This is part of the kludge for binary compatibility with old stdio. */ # define COERCE_FILE(FILE) \ (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) == _OLD_MAGIC_MASK \ && (FILE) = *(FILE**)&((int*)fp)[1]) #endif #ifdef EINVAL # define MAYBE_SET_EINVAL __set_errno (EINVAL) #else # define MAYBE_SET_EINVAL /* nothing */ #endif #ifdef IO_DEBUG # define CHECK_FILE(FILE, RET) \ if ((FILE) == NULL) { MAYBE_SET_EINVAL; return RET; } \ else { COERCE_FILE(FILE); \ if (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \ { MAYBE_SET_EINVAL; return RET; }} #else # define CHECK_FILE(FILE, RET) COERCE_FILE (FILE) #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/list ================================================ /* * * 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 __SGI_STL_LIST #define __SGI_STL_LIST #include #include #include #include #include #endif /* __SGI_STL_LIST */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/list.h ================================================ /* * * 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 __SGI_STL_LIST_H #define __SGI_STL_LIST_H #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::list; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_LIST_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/map ================================================ /* * * 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 __SGI_STL_MAP #define __SGI_STL_MAP #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #endif /* __SGI_STL_MAP */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/map.h ================================================ /* * * 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 __SGI_STL_MAP_H #define __SGI_STL_MAP_H #include #include #ifdef __STL_USE_NAMESPACES using __STD::map; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_MAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/memory ================================================ /* * 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 __SGI_STL_MEMORY #define __SGI_STL_MEMORY #include #include #include #include #include #include // Note: auto_ptr is commented out in this release because the details // of the interface are still being discussed by the C++ standardization // committee. It will be included once the iterface is finalized. #if 0 #if defined(_MUTABLE_IS_KEYWORD) && defined(_EXPLICIT_IS_KEYWORD) && \ defined(__STL_MEMBER_TEMPLATES) __STL_BEGIN_NAMESPACE template class auto_ptr { private: X* ptr; mutable bool owns; public: typedef X element_type; explicit auto_ptr(X* p = 0) __STL_NOTHROW : ptr(p), owns(p) {} auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) { a.owns = 0; } template auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) { a.owns = 0; } auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW { if (&a != this) { if (owns) delete ptr; owns = a.owns; ptr = a.ptr; a.owns = 0; } } template auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW { if (&a != this) { if (owns) delete ptr; owns = a.owns; ptr = a.ptr; a.owns = 0; } } ~auto_ptr() { if (owns) delete ptr; } X& operator*() const __STL_NOTHROW { return *ptr; } X* operator->() const __STL_NOTHROW { return ptr; } X* get() const __STL_NOTHROW { return ptr; } X* release const __STL_NOTHROW { owns = false; return ptr } }; __STL_END_NAMESPACE #endif /* mutable && explicit && member templates */ #endif /* 0 */ #endif /* __SGI_STL_MEMORY */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/multimap.h ================================================ /* * * 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 __SGI_STL_MULTIMAP_H #define __SGI_STL_MULTIMAP_H #include #include #ifdef __STL_USE_NAMESPACES using __STD::multimap; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_MULTIMAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/multiset.h ================================================ /* * * 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 __SGI_STL_MULTISET_H #define __SGI_STL_MULTISET_H #include #include #ifdef __STL_USE_NAMESPACES using __STD::multiset; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_MULTISET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/numeric ================================================ /* * * 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 __SGI_STL_NUMERIC #define __SGI_STL_NUMERIC #include #include #include #include #include #include #include #endif /* __SGI_STL_NUMERIC */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/ostream.h ================================================ /* Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 ================================================ FILE: tass-sgi-stl-2.91.57-source/pair.h ================================================ /* * * 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 __SGI_STL_PAIR_H #define __SGI_STL_PAIR_H #ifndef __STL_CONFIG_H #include #endif #ifndef __SGI_STL_INTERNAL_RELOPS #include #endif #ifndef __SGI_STL_INTERNAL_PAIR_H #include #endif #ifdef __STL_USE_NAMESPACES using __STD::pair; using __STD::make_pair; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_PAIR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/parsestream.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. Written by Per Bothner (bothner@cygnus.com). */ #ifndef PARSESTREAM_H #define PARSESTREAM_H #ifdef __GNUG__ #pragma interface #endif #include "streambuf.h" extern "C++" { // A parsebuf is a streambuf optimized for scanning text files. // It keeps track of line and column numbers. // It is guaranteed to remember the entire current line, // as well the '\n'-s on either side of it (if they exist). // You can arbitrarily seek (or unget) within this extended line. // Other backward seeks are not supported. // Normal read semantics are supported (and hence istream operators like >>). class parsebuf : public streambuf { protected: _IO_fpos_t pos_at_line_start; long _line_length; unsigned long __line_number; char *buf_start; char *buf_end; public: parsebuf *chain; // Return column number (raw - don't handle tabs etc). // Retult can be -1, meaning: at '\n' before current line. virtual int tell_in_line(); // seek to (raw) column I in current line. // Result is new (raw) column position - differs from I if unable to seek. // Seek to -1 tries to seek to before previous LF. virtual int seek_in_line(int i); // Note: there is no "current line" initially, until something is read. // Current line number, starting with 0. // If tell_in_line()==-1, then line number of next line. int line_number() { return __line_number; } // Length of current line, not counting either '\n'. int line_length() { return _line_length; } // Current line - not a copy, so file ops may trash it. virtual char* current_line(); virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); virtual streambuf* setbuf(char* p, int len); protected: parsebuf() { chain= NULL; __line_number = 0; pos_at_line_start = 0; _line_length = -1; } virtual int pbackfail(int c); }; // A string_parsebuf is a parsebuf whose source is a fixed string. class string_parsebuf : public parsebuf { public: int do_delete; string_parsebuf(char *str, int len, int delete_at_close=0); virtual int underflow(); virtual char* current_line(); virtual int seek_in_line(int i); virtual int tell_in_line(); char *left() const { return base(); } char *right() const { return ebuf(); } // streampos seekoff(streamoff, _seek_dir, int); }; // A func_parsebuf calls a given function to get new input. // Each call returns an entire NUL-terminated line (without the '\n'). // That line has been allocated with malloc(), not new. // The interface is tailored to the GNU readline library. // Example: // char* DoReadLine(void* arg) // { // char *line = readline((char*)arg); /* 'arg' is used as prompt. */ // if line == NULL) { putc('\n', stderr); return NULL; } // if (line[0] != '\0') add_history(line); // return line; // } // char PromptBuffer[100] = "> "; // func_parsebuf my_stream(DoReadLine, PromptBuffer); typedef char *(*CharReader)(void *arg); class istream; class func_parsebuf : public parsebuf { public: void *arg; CharReader read_func; int backed_up_to_newline; func_parsebuf(CharReader func, void *argm = NULL); int underflow(); virtual int tell_in_line(); virtual int seek_in_line(int i); virtual char* current_line(); }; // A general_parsebuf is a parsebuf which gets its input from some // other streambuf. It explicitly buffers up an entire line. class general_parsebuf : public parsebuf { public: streambuf *sbuf; int delete_buf; // Delete sbuf when destroying this. general_parsebuf(streambuf *buf, int delete_arg_buf = 0); int underflow(); virtual int tell_in_line(); virtual int seek_in_line(int i); ~general_parsebuf(); virtual char* current_line(); }; #if 0 class parsestream : public istream { streammarker marks[2]; short _first; // of the two marks; either 0 or 1 int _lineno; int first() { return _first; } int second() { return 1-_first; } int line_length() { marks[second].delta(marks[first]); } int line_length() { marks[second].delta(marks[first]); } int seek_in_line(int i); int tell_in_line(); int line_number(); }; #endif } // extern "C++" #endif /*!defined(PARSESTREAM_H)*/ ================================================ FILE: tass-sgi-stl-2.91.57-source/pfstream.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Written by Per Bothner (bothner@cygnus.com). */ #ifndef _PFSTREAM_H #define _PFSTREAM_H #ifdef __GNUG__ #pragma interface #endif #include extern "C++" { // ipfstream foo("NAME") is like: ifstream foo("NAME"). However, // if NAME starts *or ends* with a '|', the remainder of NAME is // evaluated as a shell command (using a procbuf), and all input // read from foo is whatever that shell writes to its standard output. // E.g. ipfstream foo("|zcat foo.Z") or ipfstream foo("zcat foo.Z|") // (These two forms are equivalent.) class ipfstream : public ifstream { public: ipfstream(const char *name, int mode=ios::in, int prot=0664); }; // opfstream foo("NAME") is like: ofstream foo("NAME"). // However, if NAME starts with a '|', the remainder of NAME is // evaluated as a shell command (using a procbuf), and all output // written to foo is piped to the standard input of that shell. // E.g. opfstream foo("|more"); class opfstream : public ofstream { public: opfstream(const char *name, int mode=ios::out, int prot=0664); }; } // extern "C++" #endif /*!_PFSTREAM_H*/ ================================================ FILE: tass-sgi-stl-2.91.57-source/procbuf.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Written by Per Bothner (bothner@cygnus.com). */ #ifndef _PROCBUF_H #define _PROCBUF_H #ifdef __GNUG__ #pragma interface #endif #include extern "C++" { class procbuf : public filebuf { /* Following fields must match those in struct _IO_proc_file */ _IO_pid_t _pid; procbuf *_next; public: procbuf() : filebuf() { } procbuf(const char *command, int mode); procbuf* open(const char *command, int mode); procbuf *close() { return (procbuf*)filebuf::close(); } virtual int sys_close(); ~procbuf(); }; } // extern "C++" #endif /* !_PROCBUF_H */ ================================================ FILE: tass-sgi-stl-2.91.57-source/pthread_alloc ================================================ /* * 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 __SGI_STL_PTHREAD_ALLOC #define __SGI_STL_PTHREAD_ALLOC // Pthread-specific node allocator. // This is similar to the default allocator, except that free-list // information is kept separately for each thread, avoiding locking. // This should be reasonably fast even in the presence of threads. // The down side is that storage may not be well-utilized. // It is not an error to allocate memory in thread A and deallocate // it n thread B. But this effectively transfers ownership of the memory, // so that it can only be reallocated by thread B. Thus this can effectively // result in a storage leak if it's done on a regular basis. // It can also result in frequent sharing of // cache lines among processors, with potentially serious performance // consequences. #include #include #ifndef __RESTRICT # define __RESTRICT #endif __STL_BEGIN_NAMESPACE // Note that this class has nonstatic members. We instantiate it once // per thread. template class __pthread_alloc_template { private: enum {ALIGN = 8}; enum {MAX_BYTES = 128}; // power of 2 enum {NFREELISTS = MAX_BYTES/ALIGN}; union obj { union obj * free_list_link; char client_data[ALIGN]; /* The client sees this. */ }; // Per instance state obj* volatile free_list[NFREELISTS]; __pthread_alloc_template* next; // Free list link static size_t ROUND_UP(size_t bytes) { return (((bytes) + ALIGN-1) & ~(ALIGN - 1)); } static size_t FREELIST_INDEX(size_t bytes) { return (((bytes) + ALIGN-1)/ALIGN - 1); } // Returns an object of size n, and optionally adds to size n free list. void *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. static char *chunk_alloc(size_t size, int &nobjs); // Chunk allocation state. And other shared state. // Protected by chunk_allocator_lock. static pthread_mutex_t chunk_allocator_lock; static char *start_free; static char *end_free; static size_t heap_size; static __pthread_alloc_template* free_allocators; static pthread_key_t key; static bool key_initialized; // Pthread key under which allocator is stored. // Allocator instances that are currently unclaimed by any thread. static void destructor(void *instance); // Function to be called on thread exit to reclaim allocator // instance. static __pthread_alloc_template *new_allocator(); // Return a recycled or new allocator instance. static __pthread_alloc_template *get_allocator_instance(); // ensure that the current thread has an associated // allocator instance. class lock { public: lock () { pthread_mutex_lock(&chunk_allocator_lock); } ~lock () { pthread_mutex_unlock(&chunk_allocator_lock); } }; friend class lock; public: __pthread_alloc_template() : next(0) { memset((void *)free_list, 0, NFREELISTS * sizeof(obj *)); } /* n must be > 0 */ static void * allocate(size_t n) { obj * volatile * my_free_list; obj * __RESTRICT result; __pthread_alloc_template* a; if (n > MAX_BYTES) { return(malloc(n)); } if (!key_initialized || !(a = (__pthread_alloc_template*) pthread_getspecific(key))) { a = get_allocator_instance(); } my_free_list = a -> free_list + FREELIST_INDEX(n); result = *my_free_list; if (result == 0) { void *r = a -> refill(ROUND_UP(n)); return r; } *my_free_list = result -> free_list_link; return (result); }; /* p may not be 0 */ static void deallocate(void *p, size_t n) { obj *q = (obj *)p; obj * volatile * my_free_list; __pthread_alloc_template* a; if (n > MAX_BYTES) { free(p); return; } if (!key_initialized || !(a = (__pthread_alloc_template*) pthread_getspecific(key))) { a = get_allocator_instance(); } my_free_list = a->free_list + FREELIST_INDEX(n); q -> free_list_link = *my_free_list; *my_free_list = q; } static void * reallocate(void *p, size_t old_sz, size_t new_sz); } ; typedef __pthread_alloc_template pthread_alloc; template void __pthread_alloc_template::destructor(void * instance) { __pthread_alloc_template* a = (__pthread_alloc_template*)instance; a -> next = free_allocators; free_allocators = a; } template __pthread_alloc_template* __pthread_alloc_template::new_allocator() { if (0 != free_allocators) { __pthread_alloc_template* result = free_allocators; free_allocators = free_allocators -> next; return result; } else { return new __pthread_alloc_template; } } template __pthread_alloc_template* __pthread_alloc_template::get_allocator_instance() { __pthread_alloc_template* result; if (!key_initialized) { /*REFERENCED*/ lock lock_instance; if (!key_initialized) { if (pthread_key_create(&key, destructor)) { abort(); // failed } key_initialized = true; } } result = new_allocator(); if (pthread_setspecific(key, result)) abort(); return result; } /* We allocate memory in large chunks in order to avoid fragmenting */ /* the malloc heap too much. */ /* We assume that size is properly aligned. */ template char *__pthread_alloc_template ::chunk_alloc(size_t size, int &nobjs) { { char * result; size_t total_bytes; size_t bytes_left; /*REFERENCED*/ lock lock_instance; // Acquire lock for this routine total_bytes = size * nobjs; bytes_left = end_free - start_free; if (bytes_left >= total_bytes) { result = start_free; start_free += total_bytes; return(result); } else if (bytes_left >= size) { nobjs = bytes_left/size; total_bytes = size * nobjs; result = start_free; start_free += total_bytes; return(result); } else { size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); // Try to make use of the left-over piece. if (bytes_left > 0) { __pthread_alloc_template* a = (__pthread_alloc_template*)pthread_getspecific(key); obj * volatile * my_free_list = a->free_list + FREELIST_INDEX(bytes_left); ((obj *)start_free) -> free_list_link = *my_free_list; *my_free_list = (obj *)start_free; } # ifdef _SGI_SOURCE // Try to get memory that's aligned on something like a // cache line boundary, so as to avoid parceling out // parts of the same line to different threads and thus // possibly different processors. { const int cache_line_size = 128; // probable upper bound bytes_to_get &= ~(cache_line_size-1); start_free = (char *)memalign(cache_line_size, bytes_to_get); if (0 == start_free) { start_free = (char *)malloc_alloc::allocate(bytes_to_get); } } # else /* !SGI_SOURCE */ start_free = (char *)malloc_alloc::allocate(bytes_to_get); # endif heap_size += bytes_to_get; end_free = start_free + bytes_to_get; } } // lock is released here return(chunk_alloc(size, nobjs)); } /* Returns an object of size n, and optionally adds to size n free list.*/ /* We assume that n is properly aligned. */ /* We hold the allocation lock. */ template void *__pthread_alloc_template ::refill(size_t n) { int nobjs = 128; char * chunk = chunk_alloc(n, nobjs); obj * volatile * my_free_list; obj * result; obj * current_obj, * next_obj; int i; if (1 == nobjs) { return(chunk); } my_free_list = free_list + FREELIST_INDEX(n); /* Build free list in chunk */ result = (obj *)chunk; *my_free_list = next_obj = (obj *)(chunk + n); for (i = 1; ; i++) { current_obj = next_obj; next_obj = (obj *)((char *)next_obj + n); if (nobjs - 1 == i) { current_obj -> free_list_link = 0; break; } else { current_obj -> free_list_link = next_obj; } } return(result); } template void *__pthread_alloc_template ::reallocate(void *p, size_t old_sz, size_t new_sz) { void * result; size_t copy_sz; if (old_sz > MAX_BYTES && new_sz > MAX_BYTES) { return(realloc(p, new_sz)); } if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p); result = allocate(new_sz); copy_sz = new_sz > old_sz? old_sz : new_sz; memcpy(result, p, copy_sz); deallocate(p, old_sz); return(result); } template __pthread_alloc_template * __pthread_alloc_template::free_allocators = 0; template pthread_key_t __pthread_alloc_template::key; template bool __pthread_alloc_template::key_initialized = false; template pthread_mutex_t __pthread_alloc_template::chunk_allocator_lock = PTHREAD_MUTEX_INITIALIZER; template char *__pthread_alloc_template ::start_free = 0; template char *__pthread_alloc_template ::end_free = 0; template size_t __pthread_alloc_template ::heap_size = 0; __STL_END_NAMESPACE #endif /* __SGI_STL_PTHREAD_ALLOC */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/pthread_alloc.h ================================================ /* * 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 __SGI_STL_PTHREAD_ALLOC_H #define __SGI_STL_PTHREAD_ALLOC_H #include #ifdef __STL_USE_NAMESPACES using __STD::__pthread_alloc_template; using __STL::pthread_alloc; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_PTHREAD_ALLOC_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/queue ================================================ /* * * 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 __SGI_STL_QUEUE #define __SGI_STL_QUEUE #include #include #include #include #include #include #include #include #include #include #endif /* __SGI_STL_QUEUE */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/rope ================================================ /* * 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 __SGI_STL_ROPE #define __SGI_STL_ROPE #include #include #include #include #include #include #include #include #include #include #endif /* __SGI_STL_ROPE */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/rope.h ================================================ /* * 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 __SGI_STL_ROPE_H #define __SGI_STL_ROPE_H #include #include #ifdef __STL_USE_NAMESPACES using __STD::char_producer; using __STD::sequence_buffer; using __STD::rope; using __STD::crope; using __STD::wrope; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_ROPE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/ropeimpl.h ================================================ /* * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ # include # include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf // if necessary. Assumes path_end[leaf_index] and leaf_pos are correct. // Results in a valid buf_ptr if the iterator can be legitimately // dereferenced. template void __rope_iterator_base::setbuf (__rope_iterator_base &x) { const RopeBase * leaf = x.path_end[x.leaf_index]; size_t leaf_pos = x.leaf_pos; size_t pos = x.current_pos; switch(leaf -> tag) { case RopeBase::leaf: x.buf_start = ((__rope_RopeLeaf *)leaf) -> data; x.buf_ptr = x.buf_start + (pos - leaf_pos); x.buf_end = x.buf_start + leaf -> size; break; case RopeBase::function: case RopeBase::substringfn: { size_t len = iterator_buf_len; size_t buf_start_pos = leaf_pos; size_t leaf_end = leaf_pos + leaf -> size; char_producer *fn = ((__rope_RopeFunction *)leaf) -> 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.tmp_buf); x.buf_ptr = x.tmp_buf + (pos - buf_start_pos); x.buf_start = x.tmp_buf; x.buf_end = x.tmp_buf + len; } break; default: __stl_assert(0); } } // Set path and buffer inside a rope iterator. We assume that // pos and root are already set. template void __rope_iterator_base::setcache (__rope_iterator_base &x) { const RopeBase * path[RopeBase::max_rope_depth+1]; const RopeBase * curr_rope; int curr_depth = -1; /* index into path */ size_t curr_start_pos = 0; size_t pos = x.current_pos; unsigned char dirns = 0; // Bit vector indicating right turns in the path __stl_assert(pos <= x.root -> size); if (pos >= x.root -> size) { x.buf_ptr = 0; return; } curr_rope = x.root; if (0 != curr_rope -> c_string) { /* Treat the root as a leaf. */ x.buf_start = curr_rope -> c_string; x.buf_end = curr_rope -> c_string + curr_rope -> size; x.buf_ptr = curr_rope -> c_string + pos; x.path_end[0] = curr_rope; x.leaf_index = 0; x.leaf_pos = 0; return; } for(;;) { ++curr_depth; __stl_assert(curr_depth <= RopeBase::max_rope_depth); path[curr_depth] = curr_rope; switch(curr_rope -> tag) { case RopeBase::leaf: case RopeBase::function: case RopeBase::substringfn: x.leaf_pos = curr_start_pos; goto done; case RopeBase::concat: { __rope_RopeConcatenation *c = (__rope_RopeConcatenation *)curr_rope; RopeBase * left = c -> left; size_t left_len = left -> size; dirns <<= 1; if (pos >= curr_start_pos + left_len) { dirns |= 1; curr_rope = c -> right; curr_start_pos += left_len; } else { curr_rope = left; } } break; } } done: // Copy last section of path into path_end. { int i = -1; int j = curr_depth + 1 - path_cache_len; if (j < 0) j = 0; while (j <= curr_depth) { x.path_end[++i] = path[j++]; } x.leaf_index = i; } x.path_directions = dirns; setbuf(x); } // Specialized version of the above. Assumes that // the path cache is valid for the previous position. template void __rope_iterator_base::setcache_for_incr (__rope_iterator_base &x) { int current_index = x.leaf_index; const RopeBase * current_node = x.path_end[current_index]; size_t len = current_node -> size; size_t node_start_pos = x.leaf_pos; unsigned char dirns = x.path_directions; __rope_RopeConcatenation * c; __stl_assert(x.current_pos <= x.root -> size); if (x.current_pos - node_start_pos < len) { /* More stuff in this leaf, we just didn't cache it. */ setbuf(x); return; } __stl_assert(node_start_pos + len == x.current_pos); // node_start_pos is starting position of last_node. while (--current_index >= 0) { if (!(dirns & 1) /* Path turned left */) break; current_node = x.path_end[current_index]; c = (__rope_RopeConcatenation *)current_node; // Otherwise we were in the right child. Thus we should pop // the concatenation node. node_start_pos -= c -> left -> size; dirns >>= 1; } if (current_index < 0) { // We underflowed the cache. Punt. setcache(x); return; } current_node = x.path_end[current_index]; c = (__rope_RopeConcatenation *)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 -> left -> size; current_node = c -> right; x.path_end[++current_index] = current_node; dirns |= 1; while (RopeBase::concat == current_node -> tag) { ++current_index; if (path_cache_len == current_index) { int i; for (i = 0; i < path_cache_len-1; i++) { x.path_end[i] = x.path_end[i+1]; } --current_index; } current_node = ((__rope_RopeConcatenation *)current_node) -> left; x.path_end[current_index] = current_node; dirns <<= 1; // node_start_pos is unchanged. } x.leaf_index = current_index; x.leaf_pos = node_start_pos; x.path_directions = dirns; setbuf(x); } template void __rope_iterator_base::incr(size_t n) { current_pos += n; if (0 != buf_ptr) { size_t chars_left = buf_end - buf_ptr; if (chars_left > n) { buf_ptr += n; } else if (chars_left == n) { buf_ptr += n; setcache_for_incr(*this); } else { buf_ptr = 0; } } } template void __rope_iterator_base::decr(size_t n) { if (0 != buf_ptr) { size_t chars_left = buf_ptr - buf_start; if (chars_left >= n) { buf_ptr -= n; } else { buf_ptr = 0; } } current_pos -= n; } template void __rope_iterator::check() { if (root_rope -> tree_ptr != root) { // Rope was modified. Get things fixed up. RopeBase::unref(root); root = root_rope -> tree_ptr; RopeBase::ref(root); buf_ptr = 0; } } template inline __rope_const_iterator::__rope_const_iterator (const __rope_iterator & x) : __rope_iterator_base(x) { } template inline __rope_iterator::__rope_iterator (rope& r, size_t pos) : __rope_iterator_base(r.tree_ptr, pos), root_rope(&r) { RopeBase::ref(root); } template inline size_t rope::char_ptr_len(const charT *s) { const charT *p = s; while (!is0(*p)) { ++p; } return(p - s); } template rope::RopeLeaf * rope::RopeLeaf_from_char_ptr(__GC_CONST charT *s, size_t size) { RopeLeaf *t = LAlloc::allocate(); t -> tag = RopeBase::leaf; if (__is_basic_char_type((charT *)0)) { // already eos terminated. t -> c_string = s; } else { t -> c_string = 0; } t -> is_balanced = true; t -> depth = 0; t -> size = size; t -> data = s; # ifndef __GC t -> refcount = 1; t -> init_refcount_lock(); # endif return (t); } # ifdef __GC template void __rope_RopeBase::fn_finalization_proc(void * tree, void *) { delete ((__rope_RopeFunction *)tree) -> fn; } # endif template rope::RopeFunction * rope::RopeFunction_from_fn (char_producer *fn, size_t size, bool delete_fn) { if (0 == size) return 0; RopeFunction *t = FAlloc::allocate(); t -> tag = RopeBase::function; t -> c_string = 0; t -> is_balanced = true; t -> depth = 0; t -> size = size; t -> fn = fn; # ifdef __GC if (delete_fn) { GC_REGISTER_FINALIZER(t, RopeBase::fn_finalization_proc, 0, 0, 0); } # else t -> delete_when_done = delete_fn; t -> refcount = 1; t -> init_refcount_lock(); # endif return (t); } #ifndef __GC template inline void __rope_RopeBase::free_c_string() { charT * cstr = c_string; if (0 != cstr) { size_t sz = size + 1; destroy(cstr, cstr + sz); DataAlloc::deallocate(cstr, sz); } } template inline void __rope_RopeBase::free_string(charT* s, size_t n) { if (!__is_basic_char_type((charT *)0)) { destroy(s, s + n); } DataAlloc::deallocate(s, rounded_up_size(n)); } template void __rope_RopeBase::free_tree() { switch(tag) { case leaf: { __rope_RopeLeaf * l = (__rope_RopeLeaf *)this; charT * d = l -> data; if (d != c_string) { free_c_string(); } free_string(d, size); LAlloc::deallocate(l); } break; case concat: { __rope_RopeConcatenation * c = (__rope_RopeConcatenation *)this; __rope_RopeBase * left = c -> left; __rope_RopeBase * right = c -> right; free_c_string(); left -> unref_nonnil(); right -> unref_nonnil(); CAlloc::deallocate(c); } break; case function: { __rope_RopeFunction * fn = (__rope_RopeFunction *)this; free_c_string(); if ( fn -> delete_when_done) { delete fn -> fn; } FAlloc::deallocate(fn); break; } case substringfn: { __rope_RopeSubstring * ss = (__rope_RopeSubstring *)this; __rope_RopeBase *base = ss -> base; free_c_string(); base -> unref_nonnil(); SAlloc::deallocate(ss); break; } } } #else template inline void __rope_RopeBase::free_string(charT* s, size_t n) {} #endif // Concatenate a C string onto a leaf rope by copying the rope data. // Used for short ropes. template rope::RopeLeaf * rope::leaf_concat_char_iter (RopeLeaf * r, const charT * iter, size_t len) { size_t old_len = r -> size; charT * new_data = (charT *) DataAlloc::allocate(rounded_up_size(old_len + len)); RopeLeaf * result; uninitialized_copy_n(r -> data, old_len, new_data); uninitialized_copy_n(iter, len, new_data + old_len); __cond_store_eos(new_data[old_len + len]); __STL_TRY { result = RopeLeaf_from_char_ptr(new_data, old_len + len); } __STL_UNWIND(RopeBase::free_string(new_data, old_len + len)); return result; } #ifndef __GC // As above, but it's OK to clobber original if refcount is 1 template rope::RopeLeaf * rope::destr_leaf_concat_char_iter (RopeLeaf * r, const charT * iter, size_t len) { __stl_assert(r -> refcount >= 1); if (r -> refcount > 1) return leaf_concat_char_iter(r, iter, len); size_t old_len = r -> size; if (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 -> data + old_len); if (__is_basic_char_type((charT *)0)) { __cond_store_eos(r -> data[old_len + len]); __stl_assert(r -> c_string == r -> data); } else if (r -> c_string != r -> data && 0 != r -> c_string) { r -> free_c_string(); r -> c_string = 0; } r -> size = old_len + len; __stl_assert(r -> refcount == 1); r -> refcount = 2; return r; } else { RopeLeaf * result = leaf_concat_char_iter(r, iter, len); __stl_assert(result -> refcount == 1); 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 rope::RopeBase * rope::tree_concat (RopeBase * left, RopeBase * right) { RopeConcatenation * result = CAlloc::allocate(); unsigned char child_depth = left -> depth; size_t rsize; result -> tag = RopeBase::concat; result -> c_string = 0; result -> is_balanced = false; result -> size = rsize = left -> size + right -> size; if (right -> depth > child_depth) child_depth = right -> depth; unsigned char depth = (unsigned char)(child_depth + 1); result -> depth = depth; result -> left = left; result -> right = right; # ifndef __GC result -> refcount = 1; result -> init_refcount_lock(); # endif if (depth > 20 && (rsize < 1000 || depth > RopeBase::max_rope_depth)) { RopeBase * balanced; __STL_TRY { balanced = balance(result); # ifndef __GC if (result != balanced) { __stl_assert(1 == result -> refcount && 1 == balanced -> refcount); } # endif result -> unref_nonnil(); } __STL_UNWIND(CAlloc::deallocate(result)); // 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 rope::RopeBase * rope::concat_char_iter (RopeBase * r, const charT *s, size_t slen) { RopeBase *result; if (0 == slen) { ref(r); return r; } if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen); if (RopeBase::leaf == r -> tag && r -> size + slen <= copy_max) { result = leaf_concat_char_iter((RopeLeaf *)r, s, slen); # ifndef __GC __stl_assert(1 == result -> refcount); # endif return result; } if (RopeBase::concat == r -> tag && RopeBase::leaf == ((RopeConcatenation *)r) -> right -> tag) { RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right); if (right -> size + slen <= copy_max) { RopeBase * left = ((RopeConcatenation *)r) -> left; RopeBase * nright = leaf_concat_char_iter((RopeLeaf *)right, s, slen); left -> ref_nonnil(); __STL_TRY { result = tree_concat(left, nright); } __STL_UNWIND(unref(left); unref(nright)); # ifndef __GC __stl_assert(1 == result -> refcount); # endif return result; } } RopeBase * nright = RopeLeaf_from_unowned_char_ptr(s, slen); __STL_TRY { r -> ref_nonnil(); result = tree_concat(r, nright); } __STL_UNWIND(unref(r); unref(nright)); # ifndef __GC __stl_assert(1 == result -> refcount); # endif return result; } #ifndef __GC template rope::RopeBase * rope ::destr_concat_char_iter (RopeBase * r, const charT *s, size_t slen) { RopeBase *result; if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen); size_t count = r -> refcount; size_t orig_size = r -> size; __stl_assert(count >= 1); if (count > 1) return concat_char_iter(r, s, slen); if (0 == slen) { r -> refcount = 2; // One more than before return r; } if (orig_size + slen <= copy_max && RopeBase::leaf == r -> tag) { result = destr_leaf_concat_char_iter((RopeLeaf *)r, s, slen); return result; } if (RopeBase::concat == r -> tag) { RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right); if (RopeBase::leaf == right -> tag && right -> size + slen <= copy_max) { RopeBase * new_right = destr_leaf_concat_char_iter(right, s, slen); if (right == new_right) { __stl_assert(new_right -> refcount == 2); new_right -> refcount = 1; } else { __stl_assert(new_right -> refcount >= 1); right -> unref_nonnil(); } __stl_assert(r -> refcount == 1); r -> refcount = 2; // One more than before. ((RopeConcatenation *)r) -> right = new_right; r -> size = orig_size + slen; if (0 != r -> c_string) { r -> free_c_string(); r -> c_string = 0; } return r; } } RopeBase *right = RopeLeaf_from_unowned_char_ptr(s, slen); r -> ref_nonnil(); __STL_TRY { result = tree_concat(r, right); } __STL_UNWIND(unref(r); unref(right)) __stl_assert(1 == result -> refcount); return result; } #endif /* !__GC */ template rope::RopeBase * rope::concat(RopeBase * left, RopeBase * right) { if (0 == left) { ref(right); return right; } if (0 == right) { left -> ref_nonnil(); return left; } if (RopeBase::leaf == right -> tag) { if (RopeBase::leaf == left -> tag) { if (right -> size + left -> size <= copy_max) { return leaf_concat_char_iter((RopeLeaf *)left, ((RopeLeaf *)right) -> data, right -> size); } } else if (RopeBase::concat == left -> tag && RopeBase::leaf == ((RopeConcatenation *)left) -> right -> tag) { RopeLeaf * leftright = (RopeLeaf *)(((RopeConcatenation *)left) -> right); if (leftright -> size + right -> size <= copy_max) { RopeBase * leftleft = ((RopeConcatenation *)left) -> left; RopeBase * rest = leaf_concat_char_iter(leftright, ((RopeLeaf *)right) -> data, right -> size); leftleft -> ref_nonnil(); __STL_TRY { return(tree_concat(leftleft, rest)); } __STL_UNWIND(unref(leftleft); unref(rest)) } } } left -> ref_nonnil(); right -> ref_nonnil(); __STL_TRY { return(tree_concat(left, right)); } __STL_UNWIND(unref(left); unref(right)); } template rope::RopeBase * rope::substring(RopeBase * base, size_t start, size_t endp1) { if (0 == base) return 0; size_t len = base -> size; size_t adj_endp1; const size_t lazy_threshold = 128; if (endp1 >= len) { if (0 == start) { base -> ref_nonnil(); return base; } else { adj_endp1 = len; } } else { adj_endp1 = endp1; } switch(base -> tag) { case RopeBase::concat: { RopeConcatenation *c = (RopeConcatenation *)base; RopeBase *left = c -> left; RopeBase *right = c -> right; size_t left_len = left -> size; RopeBase * result; if (adj_endp1 <= left_len) { return substring(left, start, endp1); } else if (start >= left_len) { return substring(right, start - left_len, adj_endp1 - left_len); } self_destruct_ptr left_result(substring(left, start, left_len)); self_destruct_ptr right_result( substring(right, 0, endp1 - left_len)); result = concat(left_result, right_result); # ifndef __GC __stl_assert(1 == result -> refcount); # endif return result; } case RopeBase::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 -> data + start; result = RopeLeaf_from_char_ptr(section, result_len); result -> c_string = 0; // Not eos terminated. # else // We should sometimes create substring node instead. result = RopeLeaf_from_unowned_char_ptr( l -> data + start, result_len); # endif return result; } case RopeBase::substringfn: // Avoid introducing mutiple 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 * space = SAlloc::allocate(); RopeSubstring * result = new(space) RopeSubstring(old -> base, start + old -> start, adj_endp1 - start); return result; } // else fall through: } case RopeBase::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 *) DataAlloc::allocate(rounded_up_size(result_len)); __STL_TRY { (*(f -> fn))(start, result_len, section); } __STL_UNWIND(RopeBase::free_string(section, result_len)); __cond_store_eos(section[result_len]); return RopeLeaf_from_char_ptr(section, result_len); } } /*NOTREACHED*/ __stl_assert(false); lazy: { // Create substring node. RopeSubstring * space = SAlloc::allocate(); RopeSubstring * result = new(space) RopeSubstring(base, start, adj_endp1 - start); return result; } } template class __rope_flatten_char_consumer : public __rope_char_consumer { private: charT * buf_ptr; public: charT * buffer; __rope_flatten_char_consumer(charT * buffer) { buf_ptr = buffer; }; ~__rope_flatten_char_consumer() {} bool operator() (const charT* leaf, size_t n) { uninitialized_copy_n(leaf, n, buf_ptr); buf_ptr += n; return true; } }; template class __rope_find_char_char_consumer : public __rope_char_consumer { private: charT pattern; public: size_t count; // Number of nonmatching characters __rope_find_char_char_consumer(charT p) : pattern(p), 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] == pattern) { count += i; return false; } } count += n; return true; } }; template class __rope_insert_char_consumer : public __rope_char_consumer { private: typedef ostream insert_ostream; insert_ostream & o; public: charT * buffer; __rope_insert_char_consumer(insert_ostream & writer) : 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 bool __rope_insert_char_consumer::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++) o << leaf[i]; return true; } inline bool __rope_insert_char_consumer::operator() (const char * leaf, size_t n) { size_t i; for (i = 0; i < n; i++) o.put(leaf[i]); return true; } #if !defined(_MSC_VER) && !defined(__BORLANDC__) // I couldn't get this to work with the VC++ version of basic_ostream. inline bool __rope_insert_char_consumer::operator() (const wchar_t * leaf, size_t n) { size_t i; for (i = 0; i < n; i++) o.put(leaf[i]); return true; } #endif /* !_MSC_VER && !BORLAND */ template bool rope::apply_to_pieces( __rope_char_consumer& c, const RopeBase * r, size_t begin, size_t end) { if (0 == r) return true; switch(r -> tag) { case RopeBase::concat: { RopeConcatenation *conc = (RopeConcatenation *)r; RopeBase *left = conc -> left; size_t left_len = left -> size; if (begin < left_len) { size_t left_end = min(left_len, end); if (!apply_to_pieces(c, left, begin, left_end)) { return false; } } if (end > left_len) { RopeBase *right = conc -> right; size_t right_start = max(left_len, begin); if (!apply_to_pieces(c, right, right_start - left_len, end - left_len)) { return false; } } } return true; case RopeBase::leaf: { RopeLeaf * l = (RopeLeaf *)r; return c(l -> data + begin, end - begin); } case RopeBase::function: case RopeBase::substringfn: { RopeFunction * f = (RopeFunction *)r; size_t len = end - begin; bool result; charT * buffer = DataAlloc::allocate(len); __STL_TRY { (*(f -> fn))(begin, end, buffer); result = c(buffer, len); DataAlloc::deallocate(buffer, len); } __STL_UNWIND(DataAlloc::deallocate(buffer, len)) return result; } default: __stl_assert(false); /*NOTREACHED*/ return false; } } inline void __rope_fill(ostream& o, size_t n) { char f = o.fill(); size_t i; for (i = 0; i < n; i++) o.put(f); } template 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 ostream& operator<< (ostream& o, const rope& r) { size_t w = o.width(); bool left = bool(o.flags() & ios::left); size_t pad_len; size_t rope_len = r.size(); __rope_insert_char_consumer 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); __STL_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); } __STL_UNWIND(if (!is_simple) o.width(w)) return o; } template charT * rope::flatten(RopeBase * r, size_t start, size_t len, charT * buffer) { __rope_flatten_char_consumer c(buffer); apply_to_pieces(c, r, start, start + len); return(buffer + len); } template size_t rope::find(charT pattern, size_t start) const { __rope_find_char_char_consumer c(pattern); apply_to_pieces(c, tree_ptr, start, size()); return start + c.count; } template charT * rope::flatten(RopeBase * r, charT * buffer) { if (0 == r) return buffer; switch(r -> tag) { case RopeBase::concat: { RopeConcatenation *c = (RopeConcatenation *)r; RopeBase *left = c -> left; RopeBase *right = c -> right; charT * rest = flatten(left, buffer); return flatten(right, rest); } case RopeBase::leaf: { RopeLeaf * l = (RopeLeaf *)r; return copy_n(l -> data, l -> size, buffer).second; } case RopeBase::function: case RopeBase::substringfn: // We dont yet do anything with substring nodes. // This needs to be fixed before ropefiles will work well. { RopeFunction * f = (RopeFunction *)r; (*(f -> fn))(0, f -> size, buffer); return buffer + f -> size; } default: __stl_assert(false); /*NOTREACHED*/ return 0; } } // This needs work for charT != char template void rope::dump(RopeBase * r, int indent) { for (int i = 0; i < indent; i++) putchar(' '); if (0 == r) { printf("NULL\n"); return; } if (RopeBase::concat == r -> tag) { RopeConcatenation *c = (RopeConcatenation *)r; RopeBase *left = c -> left; RopeBase *right = c -> right; # ifdef __GC printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n", r, r -> depth, r -> size, r -> is_balanced? "" : "not"); # else printf("Concatenation %p (rc = %ld, depth = %d, len = %ld, %s balanced)\n", r, r -> refcount, r -> depth, r -> size, r -> is_balanced? "" : "not"); # endif dump(left, indent + 2); dump(right, indent + 2); return; } else { char * kind; switch (r -> tag) { case RopeBase::leaf: kind = "Leaf"; break; case RopeBase::function: kind = "Function"; break; case RopeBase::substringfn: kind = "Function representing substring"; break; default: kind = "(corrupted kind field!)"; } # ifdef __GC printf("%s %p (depth = %d, len = %ld) ", kind, r, r -> depth, r -> size); # else printf("%s %p (rc = %ld, depth = %d, len = %ld) ", kind, r, r -> refcount, r -> depth, r -> size); # endif if (__is_one_byte_char_type((charT *)0)) { const int max_len = 40; self_destruct_ptr prefix(substring(r, 0, max_len)); charT buffer[max_len + 1]; bool too_big = r -> size > prefix-> size; flatten(prefix, buffer); buffer[prefix -> size] = __eos((charT *)0); printf("%s%s\n", (char *)buffer, too_big? "...\n" : "\n"); } else { printf("\n"); } } } template const unsigned long rope::min_len[__rope_RopeBase::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 */2971215073 }; // These are Fibonacci numbers < 2**32. template rope::RopeBase * rope::balance(RopeBase *r) { RopeBase * forest[RopeBase::max_rope_depth + 1]; RopeBase * result = 0; int i; // Inariant: // The concatenation of forest in descending order is equal to r. // forest[i].size >= min_len[i] // forest[i].depth = i // References from forest are included in refcount. for (i = 0; i <= RopeBase::max_rope_depth; ++i) forest[i] = 0; __STL_TRY { add_to_forest(r, forest); for (i = 0; i <= RopeBase::max_rope_depth; ++i) if (0 != forest[i]) { # ifndef __GC self_destruct_ptr old(result); # endif result = concat(forest[i], result); forest[i] -> unref_nonnil(); # if !defined(__GC) && defined(__STL_USE_EXCEPTIONS) forest[i] = 0; # endif } } __STL_UNWIND(for(i = 0; i <= RopeBase::max_rope_depth; i++) unref(forest[i])) if (result -> depth > RopeBase::max_rope_depth) abort(); return(result); } template void rope::add_to_forest(RopeBase *r, RopeBase **forest) { if (r -> is_balanced) { add_leaf_to_forest(r, forest); return; } __stl_assert(r -> tag == RopeBase::concat); { RopeConcatenation *c = (RopeConcatenation *)r; add_to_forest(c -> left, forest); add_to_forest(c -> right, forest); } } template void rope::add_leaf_to_forest(RopeBase *r, RopeBase **forest) { RopeBase * insertee; // included in refcount RopeBase * too_tiny = 0; // included in refcount int i; // forest[0..i-1] is empty size_t s = r -> size; for (i = 0; s >= min_len[i+1]/* not this bucket */; ++i) { if (0 != forest[i]) { # ifndef __GC self_destruct_ptr old(too_tiny); # endif too_tiny = concat_and_set_balanced(forest[i], too_tiny); forest[i] -> unref_nonnil(); forest[i] = 0; } } { # ifndef __GC self_destruct_ptr old(too_tiny); # endif insertee = concat_and_set_balanced(too_tiny, r); } // Too_tiny dead, and no longer included in refcount. // Insertee is live and included. __stl_assert(is_almost_balanced(insertee)); __stl_assert(insertee -> depth <= r -> depth + 1); for (;; ++i) { if (0 != forest[i]) { # ifndef __GC self_destruct_ptr old(insertee); # endif insertee = concat_and_set_balanced(forest[i], insertee); forest[i] -> unref_nonnil(); forest[i] = 0; __stl_assert(is_almost_balanced(insertee)); } __stl_assert(min_len[i] <= insertee -> size); __stl_assert(forest[i] == 0); if (i == RopeBase::max_rope_depth || insertee -> size < min_len[i+1]) { forest[i] = insertee; // refcount is OK since insertee is now dead. return; } } } template charT rope::fetch(RopeBase *r, size_type i) { __GC_CONST charT * cstr = r -> c_string; __stl_assert(i < r -> size); if (0 != cstr) return cstr[i]; for(;;) { switch(r -> tag) { case RopeBase::concat: { RopeConcatenation *c = (RopeConcatenation *)r; RopeBase *left = c -> left; size_t left_len = left -> size; if (i >= left_len) { i -= left_len; r = c -> right; } else { r = left; } } break; case RopeBase::leaf: { RopeLeaf * l = (RopeLeaf *)r; return l -> data[i]; } case RopeBase::function: case RopeBase::substringfn: { RopeFunction * f = (RopeFunction *)r; charT result; (*(f -> 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 charT* rope::fetch_ptr(RopeBase *r, size_type i) { RopeBase * clrstack[RopeBase::max_rope_depth]; size_t csptr = 0; for(;;) { if (r -> refcount > 1) return 0; switch(r -> tag) { case RopeBase::concat: { RopeConcatenation *c = (RopeConcatenation *)r; RopeBase *left = c -> left; size_t left_len = left -> size; if (c -> c_string != 0) clrstack[csptr++] = c; if (i >= left_len) { i -= left_len; r = c -> right; } else { r = left; } } break; case RopeBase::leaf: { RopeLeaf * l = (RopeLeaf *)r; if (l -> c_string != l -> data && l -> c_string != 0) clrstack[csptr++] = l; while (csptr > 0) { -- csptr; RopeBase * d = clrstack[csptr]; d -> free_c_string(); d -> c_string = 0; } return l -> data + i; } case RopeBase::function: case RopeBase::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 int rope::compare (const RopeBase *left, const RopeBase *right) { size_t left_len; size_t right_len; if (0 == right) return 0 != left; if (0 == left) return -1; left_len = left -> size; right_len = right -> size; if (RopeBase::leaf == left -> tag) { RopeLeaf *l = (RopeLeaf *) left; if (RopeBase::leaf == right -> tag) { RopeLeaf *r = (RopeLeaf *) right; return lexicographical_compare_3way( l -> data, l -> data + left_len, r -> data, r -> data + right_len); } else { const_iterator rstart(right, 0); const_iterator rend(right, right_len); return lexicographical_compare_3way( l -> data, l -> data + left_len, rstart, rend); } } else { const_iterator lstart(left, 0); const_iterator lend(left, left_len); if (RopeBase::leaf == right -> tag) { RopeLeaf *r = (RopeLeaf *) right; return lexicographical_compare_3way( lstart, lend, r -> data, r -> 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 __rope_charT_ref_proxy& __rope_charT_ref_proxy::operator= (charT c) { RopeBase * old = root -> tree_ptr; # ifndef __GC // First check for the case in which everything is uniquely // referenced. In that case we can do this destructively. charT * charT_ptr = my_rope::fetch_ptr(old, pos); if (0 != charT_ptr) { *charT_ptr = c; return *this; } # endif self_destruct_ptr left(my_rope::substring(old, 0, pos)); self_destruct_ptr right(my_rope::substring(old, pos+1, old -> size)); self_destruct_ptr result_left(my_rope::destr_concat_char_iter(left, &c, 1)); # ifndef __GC __stl_assert(left == result_left || 1 == result_left -> refcount); # endif RopeBase * result = my_rope::concat(result_left, right); # ifndef __GC __stl_assert(1 <= result -> refcount); RopeBase::unref(old); # endif root -> tree_ptr = result; return *this; } template inline __rope_charT_ref_proxy::operator charT () const { if (current_valid) { return current; } else { return my_rope::fetch(root->tree_ptr, pos); } } template __rope_charT_ptr_proxy __rope_charT_ref_proxy::operator& () const { return __rope_charT_ptr_proxy(*this); } template rope::rope(size_t n, charT c) { rope result; const size_t exponentiate_threshold = 32; size_t exponent; size_t rest; charT *rest_buffer; RopeBase * remainder; rope remainder_rope; if (0 == n) { tree_ptr = 0; return; } exponent = n / exponentiate_threshold; rest = n % exponentiate_threshold; if (0 == rest) { remainder = 0; } else { rest_buffer = DataAlloc::allocate(rounded_up_size(rest)); uninitialized_fill_n(rest_buffer, rest, c); __cond_store_eos(rest_buffer[rest]); __STL_TRY { remainder = RopeLeaf_from_char_ptr(rest_buffer, rest); } __STL_UNWIND(RopeBase::free_string(rest_buffer, rest)) } remainder_rope.tree_ptr = remainder; if (exponent != 0) { charT * base_buffer = DataAlloc::allocate(rounded_up_size(exponentiate_threshold)); RopeLeaf * base_leaf; rope base_rope; uninitialized_fill_n(base_buffer, exponentiate_threshold, c); __cond_store_eos(base_buffer[exponentiate_threshold]); __STL_TRY { base_leaf = RopeLeaf_from_char_ptr(base_buffer, exponentiate_threshold); } __STL_UNWIND(RopeBase::free_string(base_buffer, exponentiate_threshold)) base_rope.tree_ptr = base_leaf; if (1 == exponent) { result = base_rope; # ifndef __GC __stl_assert(1 == result -> tree_ptr -> refcount); # endif } else { result = power(base_rope, exponent, concat_fn()); } if (0 != remainder) { result += remainder_rope; } } else { result = remainder_rope; } tree_ptr = result.tree_ptr; tree_ptr -> ref_nonnil(); } template charT rope::empty_c_str[1]; # ifdef __STL_PTHREADS template pthread_mutex_t rope::swap_lock = PTHREAD_MUTEX_INITIALIZER; # endif template const charT * rope::c_str() const { if (0 == tree_ptr) { empty_c_str[0] = __eos((charT *)0); // Possibly redundant, // but probably fast. return empty_c_str; } __GC_CONST charT * old_c_string = tree_ptr -> c_string; if (0 != old_c_string) return(old_c_string); size_t s = size(); charT * result = DataAlloc::allocate(s + 1); flatten(tree_ptr, result); result[s] = __eos((charT *)0); # ifdef __GC tree_ptr -> c_string = result; # else if ((old_c_string = atomic_swap(&(tree_ptr -> c_string), result)) != 0) { // It must have been added in the interim. Hence it had to have been // separately allocated. Deallocate the old copy, since we just // replaced it. destroy(old_c_string, old_c_string + s + 1); DataAlloc::deallocate(old_c_string, s + 1); } # endif return(result); } template const charT * rope::replace_with_c_str() { if (0 == tree_ptr) { empty_c_str[0] = __eos((charT *)0); return empty_c_str; } __GC_CONST charT * old_c_string = tree_ptr -> c_string; if (RopeBase::leaf == tree_ptr -> tag && 0 != old_c_string) { return(old_c_string); } size_t s = size(); charT * result = DataAlloc::allocate(rounded_up_size(s)); flatten(tree_ptr, result); result[s] = __eos((charT *)0); tree_ptr -> unref_nonnil(); tree_ptr = RopeLeaf_from_char_ptr(result, s); return(result); } // Algorithm specializations. More should be added. #ifndef _MSC_VER // I couldn't get this to work with VC++ template void __rope_rotate(__rope_iterator first, __rope_iterator middle, __rope_iterator last) { __stl_assert(first.container() == middle.container() && middle.container() == last.container()); rope& r(first.container()); rope prefix = r.substr(0, first.index()); rope suffix = r.substr(last.index(), r.size() - last.index()); rope part1 = r.substr(middle.index(), last.index() - middle.index()); rope part2 = r.substr(first.index(), middle.index() - first.index()); r = prefix; r += part1; r += part2; r += suffix; } inline void rotate(__rope_iterator first, __rope_iterator middle, __rope_iterator last) { __rope_rotate(first, middle, last); } # if 0 // Probably not useful for several reasons: // - for SGIs 7.1 compiler and probably some others, // this forces lots of rope 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 first, __rope_iterator middle, __rope_iterator last) { __rope_rotate(first, middle, last); } # endif #endif /* _MSC_VER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/set ================================================ /* * * 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 __SGI_STL_SET #define __SGI_STL_SET #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #endif /* __SGI_STL_SET */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/set.h ================================================ /* * * 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 __SGI_STL_SET_H #define __SGI_STL_SET_H #include #include #ifdef __STL_USE_NAMESPACES using __STD::set; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_SET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/slist ================================================ /* * 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 __SGI_STL_SLIST #define __SGI_STL_SLIST #include #include #include #include #include #endif /* __SGI_STL_SLIST */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/slist.h ================================================ /* * 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 __SGI_STL_SLIST_H #define __SGI_STL_SLIST_H #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::slist; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_SLIST_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stack ================================================ /* * * 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 __SGI_STL_STACK #define __SGI_STL_STACK #include #include #include #include #include #include #endif /* __SGI_STL_STACK */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stack.h ================================================ /* * * 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 __SGI_STL_STACK_H #define __SGI_STL_STACK_H #include #include #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::stack; using __STD::queue; using __STD::priority_queue; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_STACK_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/std/bastring.cc ================================================ // Member templates for the -*- C++ -*- string classes. // Copyright (C) 1994 Free Software Foundation // This file is part of the GNU ANSI C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // As a special exception, if you link this library with files // compiled with a GNU compiler to produce an executable, this does not cause // the resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. // Written by Jason Merrill based upon the specification by Takanori Adachi // in ANSI X3J16/94-0013R2. extern "C++" { template inline void * basic_string ::Rep:: operator new (size_t s, size_t extra) { return Allocator::allocate(s + extra * sizeof (charT)); } template inline void basic_string ::Rep:: operator delete (void * ptr) { Allocator::deallocate(ptr, sizeof(Rep) + reinterpret_cast(ptr)->res * sizeof (charT)); } template inline size_t basic_string ::Rep:: frob_size (size_t s) { size_t i = 16; while (i < s) i *= 2; return i; } template inline basic_string ::Rep * basic_string ::Rep:: create (size_t extra) { extra = frob_size (extra + 1); Rep *p = new (extra) Rep; p->res = extra; p->ref = 1; p->selfish = false; return p; } template charT * basic_string ::Rep:: clone () { Rep *p = Rep::create (len); p->copy (0, data (), len); p->len = len; return p->data (); } template inline bool basic_string ::Rep:: excess_slop (size_t s, size_t r) { return 2 * (s <= 16 ? 16 : s) < r; } template inline bool basic_string :: check_realloc (basic_string::size_type s) const { s += sizeof (charT); rep ()->selfish = false; return (rep ()->ref > 1 || s > capacity () || Rep::excess_slop (s, capacity ())); } template void basic_string :: alloc (basic_string::size_type size, bool save) { if (! check_realloc (size)) return; Rep *p = Rep::create (size); if (save) { p->copy (0, data (), length ()); p->len = length (); } else p->len = 0; repup (p); } template basic_string & basic_string :: replace (size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2) { const size_t len2 = str.length (); if (pos1 == 0 && n1 >= length () && pos2 == 0 && n2 >= len2) return operator= (str); OUTOFRANGE (pos2 > len2); if (n2 > len2 - pos2) n2 = len2 - pos2; return replace (pos1, n1, str.data () + pos2, n2); } template inline void basic_string ::Rep:: copy (size_t pos, const charT *s, size_t n) { if (n) traits::copy (data () + pos, s, n); } template inline void basic_string ::Rep:: move (size_t pos, const charT *s, size_t n) { if (n) traits::move (data () + pos, s, n); } template basic_string & basic_string :: replace (size_type pos, size_type n1, const charT* s, size_type n2) { const size_type len = length (); OUTOFRANGE (pos > len); if (n1 > len - pos) n1 = len - pos; LENGTHERROR (len - n1 > max_size () - n2); size_t newlen = len - n1 + n2; if (check_realloc (newlen)) { Rep *p = Rep::create (newlen); p->copy (0, data (), pos); p->copy (pos + n2, data () + pos + n1, len - (pos + n1)); p->copy (pos, s, n2); repup (p); } else { rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1)); rep ()->copy (pos, s, n2); } rep ()->len = newlen; return *this; } template inline void basic_string ::Rep:: set (size_t pos, const charT c, size_t n) { traits::set (data () + pos, c, n); } template basic_string & basic_string :: replace (size_type pos, size_type n1, size_type n2, charT c) { const size_t len = length (); OUTOFRANGE (pos > len); if (n1 > len - pos) n1 = len - pos; LENGTHERROR (len - n1 > max_size () - n2); size_t newlen = len - n1 + n2; if (check_realloc (newlen)) { Rep *p = Rep::create (newlen); p->copy (0, data (), pos); p->copy (pos + n2, data () + pos + n1, len - (pos + n1)); p->set (pos, c, n2); repup (p); } else { rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1)); rep ()->set (pos, c, n2); } rep ()->len = newlen; return *this; } template void basic_string :: resize (size_type n, charT c) { LENGTHERROR (n > max_size ()); if (n > length ()) append (n - length (), c); else erase (n); } template basic_string ::size_type basic_string :: copy (charT* s, size_type n, size_type pos) const { OUTOFRANGE (pos > length ()); if (n > length () - pos) n = length () - pos; traits::copy (s, data () + pos, n); return n; } template basic_string ::size_type basic_string :: find (const charT* s, size_type pos, size_type n) const { size_t xpos = pos; for (; xpos + n <= length (); ++xpos) if (traits::eq (data () [xpos], *s) && traits::compare (data () + xpos, s, n) == 0) return xpos; return npos; } template inline basic_string ::size_type basic_string :: _find (const charT* ptr, charT c, size_type xpos, size_type len) { for (; xpos < len; ++xpos) if (traits::eq (ptr [xpos], c)) return xpos; return npos; } template basic_string ::size_type basic_string :: find (charT c, size_type pos) const { return _find (data (), c, pos, length ()); } template basic_string ::size_type basic_string :: rfind (const charT* s, size_type pos, size_type n) const { if (n > length ()) return npos; size_t xpos = length () - n; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0; ) if (traits::eq (data () [xpos], *s) && traits::compare (data () + xpos, s, n) == 0) return xpos; return npos; } template basic_string ::size_type basic_string :: rfind (charT c, size_type pos) const { if (1 > length ()) return npos; size_t xpos = length () - 1; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0; ) if (traits::eq (data () [xpos], c)) return xpos; return npos; } template basic_string ::size_type basic_string :: find_first_of (const charT* s, size_type pos, size_type n) const { size_t xpos = pos; for (; xpos < length (); ++xpos) if (_find (s, data () [xpos], 0, n) != npos) return xpos; return npos; } template basic_string ::size_type basic_string :: find_last_of (const charT* s, size_type pos, size_type n) const { if (length() == 0) return npos; size_t xpos = length () - 1; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0;) if (_find (s, data () [xpos], 0, n) != npos) return xpos; return npos; } template basic_string ::size_type basic_string :: find_first_not_of (const charT* s, size_type pos, size_type n) const { size_t xpos = pos; for (; xpos < length (); ++xpos) if (_find (s, data () [xpos], 0, n) == npos) return xpos; return npos; } template basic_string ::size_type basic_string :: find_first_not_of (charT c, size_type pos) const { size_t xpos = pos; for (; xpos < length (); ++xpos) if (traits::ne (data () [xpos], c)) return xpos; return npos; } template basic_string ::size_type basic_string :: find_last_not_of (const charT* s, size_type pos, size_type n) const { if (length() == 0) return npos; size_t xpos = length () - 1; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0;) if (_find (s, data () [xpos], 0, n) == npos) return xpos; return npos; } template basic_string ::size_type basic_string :: find_last_not_of (charT c, size_type pos) const { if (length() == 0) return npos; size_t xpos = length () - 1; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0;) if (traits::ne (data () [xpos], c)) return xpos; return npos; } template int basic_string :: compare (const basic_string& str, size_type pos, size_type n) const { OUTOFRANGE (pos > length ()); size_t rlen = length () - pos; if (rlen > n) rlen = n; if (rlen > str.length ()) rlen = str.length (); int r = traits::compare (data () + pos, str.data (), rlen); if (r != 0) return r; if (rlen == n) return 0; return (length () - pos) - str.length (); } template int basic_string :: compare (const charT* s, size_type pos, size_type n) const { OUTOFRANGE (pos > length ()); size_t rlen = length () - pos; if (rlen > n) rlen = n; int r = traits::compare (data () + pos, s, rlen); if (r != 0) return r; return (length () - pos) - n; } #include template istream & operator>> (istream &is, basic_string &s) { int w = is.width (0); if (is.ipfx0 ()) { register streambuf *sb = is.rdbuf (); s.resize (0); while (1) { int ch = sb->sbumpc (); if (ch == EOF) { is.setstate (ios::eofbit); break; } else if (traits::is_del (ch)) { sb->sungetc (); break; } s += ch; if (--w == 1) break; } } is.isfx (); if (s.length () == 0) is.setstate (ios::failbit); return is; } template ostream & operator<< (ostream &o, const basic_string & s) { return o.write (s.data (), s.length ()); } template istream& getline (istream &is, basic_string & s, charT delim) { if (is.ipfx1 ()) { _IO_size_t count = 0; streambuf *sb = is.rdbuf (); s.resize (0); while (1) { int ch = sb->sbumpc (); if (ch == EOF) { is.setstate (count == 0 ? (ios::failbit|ios::eofbit) : ios::eofbit); break; } ++count; if (ch == delim) break; s += ch; if (s.length () == s.npos - 1) { is.setstate (ios::failbit); break; } } } // We need to be friends with istream to do this. // is._gcount = count; is.isfx (); return is; } template basic_string ::Rep basic_string::nilRep = { 0, 0, 1, false }; template const basic_string ::size_type basic_string ::npos; } // extern "C++" ================================================ FILE: tass-sgi-stl-2.91.57-source/std/bastring.h ================================================ // Main templates for the -*- C++ -*- string classes. // Copyright (C) 1994, 1995 Free Software Foundation // This file is part of the GNU ANSI C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // As a special exception, if you link this library with files // compiled with a GNU compiler to produce an executable, this does not cause // the resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. // Written by Jason Merrill based upon the specification by Takanori Adachi // in ANSI X3J16/94-0013R2. #ifndef __BASTRING__ #define __BASTRING__ #ifdef __GNUG__ #pragma interface #endif #include #include // NOTE : This does NOT conform to the draft standard and is likely to change #include extern "C++" { class istream; class ostream; #include #ifdef __STL_USE_EXCEPTIONS extern void __out_of_range (const char *); extern void __length_error (const char *); #define OUTOFRANGE(cond) \ do { if (cond) __out_of_range (#cond); } while (0) #define LENGTHERROR(cond) \ do { if (cond) __length_error (#cond); } while (0) #else #include #define OUTOFRANGE(cond) assert (!(cond)) #define LENGTHERROR(cond) assert (!(cond)) #endif template , class Allocator = alloc > class basic_string { private: struct Rep { size_t len, res, ref; bool selfish; charT* data () { return reinterpret_cast(this + 1); } charT& operator[] (size_t s) { return data () [s]; } charT* grab () { if (selfish) return clone (); ++ref; return data (); } void release () { if (--ref == 0) delete this; } inline static void * operator new (size_t, size_t); inline static void operator delete (void *); inline static Rep* create (size_t); charT* clone (); inline void copy (size_t, const charT *, size_t); inline void move (size_t, const charT *, size_t); inline void set (size_t, const charT, size_t); inline static bool excess_slop (size_t, size_t); inline static size_t frob_size (size_t); private: Rep &operator= (const Rep &); }; public: // types: typedef traits traits_type; typedef typename traits::char_type value_type; typedef Allocator allocator_type; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef charT& reference; typedef const charT& const_reference; typedef charT* pointer; typedef const charT* const_pointer; typedef pointer iterator; typedef const_pointer const_iterator; typedef ::reverse_iterator reverse_iterator; typedef ::reverse_iterator const_reverse_iterator; static const size_type npos = static_cast(-1); private: Rep *rep () const { return reinterpret_cast(dat) - 1; } void repup (Rep *p) { rep ()->release (); dat = p->data (); } public: const charT* data () const { return rep ()->data(); } size_type length () const { return rep ()->len; } size_type size () const { return rep ()->len; } size_type capacity () const { return rep ()->res; } size_type max_size () const { return (npos - 1)/sizeof (charT); } // XXX bool empty () const { return size () == 0; } // _lib.string.cons_ construct/copy/destroy: basic_string& operator= (const basic_string& str) { if (&str != this) { rep ()->release (); dat = str.rep ()->grab (); } return *this; } explicit basic_string (): dat (nilRep.grab ()) { } basic_string (const basic_string& str): dat (str.rep ()->grab ()) { } basic_string (const basic_string& str, size_type pos, size_type n = npos) : dat (nilRep.grab ()) { assign (str, pos, n); } basic_string (const charT* s, size_type n) : dat (nilRep.grab ()) { assign (s, n); } basic_string (const charT* s) : dat (nilRep.grab ()) { assign (s); } basic_string (size_type n, charT c) : dat (nilRep.grab ()) { assign (n, c); } #ifdef __STL_MEMBER_TEMPLATES template basic_string(InputIterator begin, InputIterator end) #else basic_string(const_iterator begin, const_iterator end) #endif : dat (nilRep.grab ()) { assign (begin, end); } ~basic_string () { rep ()->release (); } void swap (basic_string &s) { charT *d = dat; dat = s.dat; s.dat = d; } basic_string& append (const basic_string& str, size_type pos = 0, size_type n = npos) { return replace (length (), 0, str, pos, n); } basic_string& append (const charT* s, size_type n) { return replace (length (), 0, s, n); } basic_string& append (const charT* s) { return append (s, traits::length (s)); } basic_string& append (size_type n, charT c) { return replace (length (), 0, n, c); } #ifdef __STL_MEMBER_TEMPLATES template basic_string& append(InputIterator first, InputIterator last) #else basic_string& append(const_iterator first, const_iterator last) #endif { return replace (iend (), iend (), first, last); } basic_string& assign (const basic_string& str, size_type pos = 0, size_type n = npos) { return replace (0, npos, str, pos, n); } basic_string& assign (const charT* s, size_type n) { return replace (0, npos, s, n); } basic_string& assign (const charT* s) { return assign (s, traits::length (s)); } basic_string& assign (size_type n, charT c) { return replace (0, npos, n, c); } #ifdef __STL_MEMBER_TEMPLATES template basic_string& assign(InputIterator first, InputIterator last) #else basic_string& assign(const_iterator first, const_iterator last) #endif { return replace (ibegin (), iend (), first, last); } basic_string& operator= (const charT* s) { return assign (s); } basic_string& operator= (charT c) { return assign (1, c); } basic_string& operator+= (const basic_string& rhs) { return append (rhs); } basic_string& operator+= (const charT* s) { return append (s); } basic_string& operator+= (charT c) { return append (1, c); } basic_string& insert (size_type pos1, const basic_string& str, size_type pos2 = 0, size_type n = npos) { return replace (pos1, 0, str, pos2, n); } basic_string& insert (size_type pos, const charT* s, size_type n) { return replace (pos, 0, s, n); } basic_string& insert (size_type pos, const charT* s) { return insert (pos, s, traits::length (s)); } basic_string& insert (size_type pos, size_type n, charT c) { return replace (pos, 0, n, c); } iterator insert(iterator p, charT c) { size_type __o = p - ibegin (); insert (p - ibegin (), 1, c); selfish (); return ibegin () + __o; } iterator insert(iterator p, size_type n, charT c) { size_type __o = p - ibegin (); insert (p - ibegin (), n, c); selfish (); return ibegin () + __o; } #ifdef __STL_MEMBER_TEMPLATES template void insert(iterator p, InputIterator first, InputIterator last) #else void insert(iterator p, const_iterator first, const_iterator last) #endif { replace (p, p, first, last); } basic_string& erase (size_type pos = 0, size_type n = npos) { return replace (pos, n, (size_type)0, (charT)0); } iterator erase(iterator p) { size_type __o = p - begin(); replace (__o, 1, (size_type)0, (charT)0); selfish (); return ibegin() + __o; } iterator erase(iterator f, iterator l) { size_type __o = f - ibegin(); replace (__o, l-f, (size_type)0, (charT)0);selfish (); return ibegin() + __o; } basic_string& replace (size_type pos1, size_type n1, const basic_string& str, size_type pos2 = 0, size_type n2 = npos); basic_string& replace (size_type pos, size_type n1, const charT* s, size_type n2); basic_string& replace (size_type pos, size_type n1, const charT* s) { return replace (pos, n1, s, traits::length (s)); } basic_string& replace (size_type pos, size_type n1, size_type n2, charT c); basic_string& replace (size_type pos, size_type n, charT c) { return replace (pos, n, 1, c); } basic_string& replace (iterator i1, iterator i2, const basic_string& str) { return replace (i1 - ibegin (), i2 - i1, str); } basic_string& replace (iterator i1, iterator i2, const charT* s, size_type n) { return replace (i1 - ibegin (), i2 - i1, s, n); } basic_string& replace (iterator i1, iterator i2, const charT* s) { return replace (i1 - ibegin (), i2 - i1, s); } basic_string& replace (iterator i1, iterator i2, size_type n, charT c) { return replace (i1 - ibegin (), i2 - i1, n, c); } #ifdef __STL_MEMBER_TEMPLATES template basic_string& replace(iterator i1, iterator i2, InputIterator j1, InputIterator j2); #else basic_string& replace(iterator i1, iterator i2, const_iterator j1, const_iterator j2); #endif private: static charT eos () { return traits::eos (); } void unique () { if (rep ()->ref > 1) alloc (length (), true); } void selfish () { unique (); rep ()->selfish = true; } public: charT operator[] (size_type pos) const { if (pos == length ()) return eos (); return data ()[pos]; } reference operator[] (size_type pos) { selfish (); return (*rep ())[pos]; } reference at (size_type pos) { OUTOFRANGE (pos >= length ()); return (*this)[pos]; } const_reference at (size_type pos) const { OUTOFRANGE (pos >= length ()); return data ()[pos]; } private: void terminate () const { traits::assign ((*rep ())[length ()], eos ()); } public: const charT* c_str () const { if (length () == 0) return ""; terminate (); return data (); } void resize (size_type n, charT c); void resize (size_type n) { resize (n, eos ()); } void reserve (size_type) { } size_type copy (charT* s, size_type n, size_type pos = 0) const; size_type find (const basic_string& str, size_type pos = 0) const { return find (str.data(), pos, str.length()); } size_type find (const charT* s, size_type pos, size_type n) const; size_type find (const charT* s, size_type pos = 0) const { return find (s, pos, traits::length (s)); } size_type find (charT c, size_type pos = 0) const; size_type rfind (const basic_string& str, size_type pos = npos) const { return rfind (str.data(), pos, str.length()); } size_type rfind (const charT* s, size_type pos, size_type n) const; size_type rfind (const charT* s, size_type pos = npos) const { return rfind (s, pos, traits::length (s)); } size_type rfind (charT c, size_type pos = npos) const; size_type find_first_of (const basic_string& str, size_type pos = 0) const { return find_first_of (str.data(), pos, str.length()); } size_type find_first_of (const charT* s, size_type pos, size_type n) const; size_type find_first_of (const charT* s, size_type pos = 0) const { return find_first_of (s, pos, traits::length (s)); } size_type find_first_of (charT c, size_type pos = 0) const { return find (c, pos); } size_type find_last_of (const basic_string& str, size_type pos = npos) const { return find_last_of (str.data(), pos, str.length()); } size_type find_last_of (const charT* s, size_type pos, size_type n) const; size_type find_last_of (const charT* s, size_type pos = npos) const { return find_last_of (s, pos, traits::length (s)); } size_type find_last_of (charT c, size_type pos = npos) const { return rfind (c, pos); } size_type find_first_not_of (const basic_string& str, size_type pos = 0) const { return find_first_not_of (str.data(), pos, str.length()); } size_type find_first_not_of (const charT* s, size_type pos, size_type n) const; size_type find_first_not_of (const charT* s, size_type pos = 0) const { return find_first_not_of (s, pos, traits::length (s)); } size_type find_first_not_of (charT c, size_type pos = 0) const; size_type find_last_not_of (const basic_string& str, size_type pos = npos) const { return find_last_not_of (str.data(), pos, str.length()); } size_type find_last_not_of (const charT* s, size_type pos, size_type n) const; size_type find_last_not_of (const charT* s, size_type pos = npos) const { return find_last_not_of (s, pos, traits::length (s)); } size_type find_last_not_of (charT c, size_type pos = npos) const; basic_string substr (size_type pos = 0, size_type n = npos) const { return basic_string (*this, pos, n); } int compare (const basic_string& str, size_type pos = 0, size_type n = npos) const; // There is no 'strncmp' equivalent for charT pointers. int compare (const charT* s, size_type pos, size_type n) const; int compare (const charT* s, size_type pos = 0) const { return compare (s, pos, traits::length (s)); } iterator begin () { selfish (); return &(*this)[0]; } iterator end () { selfish (); return &(*this)[length ()]; } private: iterator ibegin () const { return &(*rep ())[0]; } iterator iend () const { return &(*rep ())[length ()]; } public: const_iterator begin () const { return ibegin (); } const_iterator end () const { return iend (); } 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 ()); } private: void alloc (size_type size, bool save); static size_type _find (const charT* ptr, charT c, size_type xpos, size_type len); inline bool check_realloc (size_type s) const; static Rep nilRep; charT *dat; }; #ifdef __STL_MEMBER_TEMPLATES template template basic_string & basic_string :: replace (iterator i1, iterator i2, InputIterator j1, InputIterator j2) #else template basic_string & basic_string :: replace (iterator i1, iterator i2, const_iterator j1, const_iterator j2) #endif { const size_type len = length (); size_type pos = i1 - ibegin (); size_type n1 = i2 - i1; size_type n2 = j2 - j1; OUTOFRANGE (pos > len); if (n1 > len - pos) n1 = len - pos; LENGTHERROR (len - n1 > max_size () - n2); size_t newlen = len - n1 + n2; if (check_realloc (newlen)) { Rep *p = Rep::create (newlen); p->copy (0, data (), pos); p->copy (pos + n2, data () + pos + n1, len - (pos + n1)); for (; j1 != j2; ++j1, ++pos) traits::assign ((*p)[pos], *j1); repup (p); } else { rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1)); for (; j1 != j2; ++j1, ++pos) traits::assign ((*rep ())[pos], *j1); } rep ()->len = newlen; return *this; } template inline basic_string operator+ (const basic_string & lhs, const basic_string & rhs) { basic_string str (lhs); str.append (rhs); return str; } template inline basic_string operator+ (const charT* lhs, const basic_string & rhs) { basic_string str (lhs); str.append (rhs); return str; } template inline basic_string operator+ (charT lhs, const basic_string & rhs) { basic_string str (1, lhs); str.append (rhs); return str; } template inline basic_string operator+ (const basic_string & lhs, const charT* rhs) { basic_string str (lhs); str.append (rhs); return str; } template inline basic_string operator+ (const basic_string & lhs, charT rhs) { basic_string str (lhs); str.append (1, rhs); return str; } template inline bool operator== (const basic_string & lhs, const basic_string & rhs) { return (lhs.compare (rhs) == 0); } template inline bool operator== (const charT* lhs, const basic_string & rhs) { return (rhs.compare (lhs) == 0); } template inline bool operator== (const basic_string & lhs, const charT* rhs) { return (lhs.compare (rhs) == 0); } template inline bool operator!= (const charT* lhs, const basic_string & rhs) { return (rhs.compare (lhs) != 0); } template inline bool operator!= (const basic_string & lhs, const charT* rhs) { return (lhs.compare (rhs) != 0); } template inline bool operator< (const basic_string & lhs, const basic_string & rhs) { return (lhs.compare (rhs) < 0); } template inline bool operator< (const charT* lhs, const basic_string & rhs) { return (rhs.compare (lhs) > 0); } template inline bool operator< (const basic_string & lhs, const charT* rhs) { return (lhs.compare (rhs) < 0); } template inline bool operator> (const charT* lhs, const basic_string & rhs) { return (rhs.compare (lhs) < 0); } template inline bool operator> (const basic_string & lhs, const charT* rhs) { return (lhs.compare (rhs) > 0); } template inline bool operator<= (const charT* lhs, const basic_string & rhs) { return (rhs.compare (lhs) >= 0); } template inline bool operator<= (const basic_string & lhs, const charT* rhs) { return (lhs.compare (rhs) <= 0); } template inline bool operator>= (const charT* lhs, const basic_string & rhs) { return (rhs.compare (lhs) <= 0); } template inline bool operator>= (const basic_string & lhs, const charT* rhs) { return (lhs.compare (rhs) >= 0); } template inline bool operator!= (const basic_string & lhs, const basic_string & rhs) { return (lhs.compare (rhs) != 0); } template inline bool operator> (const basic_string & lhs, const basic_string & rhs) { return (lhs.compare (rhs) > 0); } template inline bool operator<= (const basic_string & lhs, const basic_string & rhs) { return (lhs.compare (rhs) <= 0); } template inline bool operator>= (const basic_string & lhs, const basic_string & rhs) { return (lhs.compare (rhs) >= 0); } class istream; class ostream; template istream& operator>> (istream&, basic_string &); template ostream& operator<< (ostream&, const basic_string &); template istream& getline (istream&, basic_string &, charT delim = '\n'); } // extern "C++" #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/std/complext.cc ================================================ // Member templates for the -*- C++ -*- complex number classes. // Copyright (C) 1994 Free Software Foundation // This file is part of the GNU ANSI C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // As a special exception, if you link this library with files // compiled with a GNU compiler to produce an executable, this does not cause // the resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. // Written by Jason Merrill based upon the specification in the 27 May 1994 // C++ working paper, ANSI document X3J16/94-0098. #include extern "C++" { template complex cos (const complex& x) { return complex (cos (real (x)) * cosh (imag (x)), - sin (real (x)) * sinh (imag (x))); } template complex cosh (const complex& x) { return complex (cosh (real (x)) * cos (imag (x)), sinh (real (x)) * sin (imag (x))); } template complex exp (const complex& x) { return polar (FLOAT (exp (real (x))), imag (x)); } template complex log (const complex& x) { return complex (log (abs (x)), arg (x)); } template complex pow (const complex& x, const complex& y) { FLOAT logr = log (abs (x)); FLOAT t = arg (x); return polar (FLOAT (exp (logr * real (y) - imag (y) * t)), FLOAT (imag (y) * logr + real (y) * t)); } template complex pow (const complex& x, FLOAT y) { return exp (FLOAT (y) * log (x)); } template complex pow (FLOAT x, const complex& y) { return exp (y * FLOAT (log (x))); } template complex sin (const complex& x) { return complex (sin (real (x)) * cosh (imag (x)), cos (real (x)) * sinh (imag (x))); } template complex sinh (const complex& x) { return complex (sinh (real (x)) * cos (imag (x)), cosh (real (x)) * sin (imag (x))); } #include template istream& operator >> (istream& is, complex& x) { FLOAT re, im = 0; char ch = 0; if (is.ipfx0 ()) { if (is.peek () == '(') is >> ch; is >> re; if (ch == '(') { is >> ch; if (ch == ',') is >> im >> ch; } } is.isfx (); if (ch != 0 && ch != ')') is.setstate (ios::failbit); else if (is.good ()) x = complex (re, im); return is; } template ostream& operator << (ostream& os, const complex& x) { return os << '(' << real (x) << ',' << imag (x) << ')'; } // The code below is adapted from f2c's libF77, and is subject to this // copyright: /**************************************************************** Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the names of AT&T Bell Laboratories or Bellcore or any of their entities not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. AT&T and Bellcore disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall AT&T or Bellcore be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. ****************************************************************/ template complex& __doadv (complex* ths, const complex& y) { FLOAT ar = abs (y.re); FLOAT ai = abs (y.im); FLOAT nr, ni; FLOAT t, d; if (ar <= ai) { t = y.re / y.im; d = y.im * (1 + t*t); nr = (ths->re * t + ths->im) / d; ni = (ths->im * t - ths->re) / d; } else { t = y.im / y.re; d = y.re * (1 + t*t); nr = (ths->re + ths->im * t) / d; ni = (ths->im - ths->re * t) / d; } ths->re = nr; ths->im = ni; return *ths; } template complex operator / (const complex& x, const complex& y) { FLOAT ar = abs (real (y)); FLOAT ai = abs (imag (y)); FLOAT nr, ni; FLOAT t, d; if (ar <= ai) { t = real (y) / imag (y); d = imag (y) * (1 + t*t); nr = (real (x) * t + imag (x)) / d; ni = (imag (x) * t - real (x)) / d; } else { t = imag (y) / real (y); d = real (y) * (1 + t*t); nr = (real (x) + imag (x) * t) / d; ni = (imag (x) - real (x) * t) / d; } return complex (nr, ni); } template complex operator / (FLOAT x, const complex& y) { FLOAT ar = abs (real (y)); FLOAT ai = abs (imag (y)); FLOAT nr, ni; FLOAT t, d; if (ar <= ai) { t = real (y) / imag (y); d = imag (y) * (1 + t*t); nr = x * t / d; ni = -x / d; } else { t = imag (y) / real (y); d = real (y) * (1 + t*t); nr = x / d; ni = -x * t / d; } return complex (nr, ni); } template complex pow (const complex& xin, int y) { if (y == 0) return complex (1.0); complex r (1.0); complex x (xin); if (y < 0) { y = -y; x = 1/x; } for (;;) { if (y & 1) r *= x; if (y >>= 1) x *= x; else return r; } } template complex sqrt (const complex& x) { FLOAT r = abs (x); FLOAT nr, ni; if (r == 0.0) nr = ni = r; else if (real (x) > 0) { nr = sqrt (0.5 * (r + real (x))); ni = imag (x) / nr / 2; } else { ni = sqrt (0.5 * (r - real (x))); if (imag (x) < 0) ni = - ni; nr = imag (x) / ni / 2; } return complex (nr, ni); } } // extern "C++" ================================================ FILE: tass-sgi-stl-2.91.57-source/std/complext.h ================================================ // The template and inlines for the -*- C++ -*- complex number classes. // Copyright (C) 1994 Free Software Foundation // This file is part of the GNU ANSI C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms of // the GNU General Public License as published by the Free Software // Foundation; either version 2, or (at your option) any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // As a special exception, if you link this library with files compiled // with a GNU compiler to produce an executable, this does not cause the // resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. // Written by Jason Merrill based upon the specification in the 27 May 1994 // C++ working paper, ANSI document X3J16/94-0098. #ifndef __COMPLEXT__ #define __COMPLEXT__ #ifdef __GNUG__ #pragma interface #endif #include #if ! defined (__GNUG__) && ! defined (__attribute__) #define __attribute__(foo) /* Ignore. */ #endif class istream; class ostream; extern "C++" { template class complex; template complex<_FLT>& __doapl (complex<_FLT>* ths, const complex<_FLT>& r); template complex<_FLT>& __doami (complex<_FLT>* ths, const complex<_FLT>& r); template complex<_FLT>& __doaml (complex<_FLT>* ths, const complex<_FLT>& r); template complex<_FLT>& __doadv (complex<_FLT>* ths, const complex<_FLT>& r); template class complex { public: complex (_FLT r = 0, _FLT i = 0): re (r), im (i) { } complex& operator += (const complex&); complex& operator -= (const complex&); complex& operator *= (const complex&); complex& operator /= (const complex&); _FLT real () const { return re; } _FLT imag () const { return im; } private: _FLT re, im; friend complex& __doapl<> (complex *, const complex&); friend complex& __doami<> (complex *, const complex&); friend complex& __doaml<> (complex *, const complex&); friend complex& __doadv<> (complex *, const complex&); }; // Declare specializations. class complex; class complex; class complex; template inline complex<_FLT>& __doapl (complex<_FLT>* ths, const complex<_FLT>& r) { ths->re += r.re; ths->im += r.im; return *ths; } template inline complex<_FLT>& complex<_FLT>::operator += (const complex<_FLT>& r) { return __doapl (this, r); } template inline complex<_FLT>& __doami (complex<_FLT>* ths, const complex<_FLT>& r) { ths->re -= r.re; ths->im -= r.im; return *ths; } template inline complex<_FLT>& complex<_FLT>::operator -= (const complex<_FLT>& r) { return __doami (this, r); } template inline complex<_FLT>& __doaml (complex<_FLT>* ths, const complex<_FLT>& r) { _FLT f = ths->re * r.re - ths->im * r.im; ths->im = ths->re * r.im + ths->im * r.re; ths->re = f; return *ths; } template inline complex<_FLT>& complex<_FLT>::operator *= (const complex<_FLT>& r) { return __doaml (this, r); } template inline complex<_FLT>& complex<_FLT>::operator /= (const complex<_FLT>& r) { return __doadv (this, r); } template inline _FLT imag (const complex<_FLT>& x) __attribute__ ((const)); template inline _FLT imag (const complex<_FLT>& x) { return x.imag (); } template inline _FLT real (const complex<_FLT>& x) __attribute__ ((const)); template inline _FLT real (const complex<_FLT>& x) { return x.real (); } template inline complex<_FLT> operator + (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); template inline complex<_FLT> operator + (const complex<_FLT>& x, const complex<_FLT>& y) { return complex<_FLT> (real (x) + real (y), imag (x) + imag (y)); } template inline complex<_FLT> operator + (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); template inline complex<_FLT> operator + (const complex<_FLT>& x, _FLT y) { return complex<_FLT> (real (x) + y, imag (x)); } template inline complex<_FLT> operator + (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); template inline complex<_FLT> operator + (_FLT x, const complex<_FLT>& y) { return complex<_FLT> (x + real (y), imag (y)); } template inline complex<_FLT> operator - (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); template inline complex<_FLT> operator - (const complex<_FLT>& x, const complex<_FLT>& y) { return complex<_FLT> (real (x) - real (y), imag (x) - imag (y)); } template inline complex<_FLT> operator - (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); template inline complex<_FLT> operator - (const complex<_FLT>& x, _FLT y) { return complex<_FLT> (real (x) - y, imag (x)); } template inline complex<_FLT> operator - (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); template inline complex<_FLT> operator - (_FLT x, const complex<_FLT>& y) { return complex<_FLT> (x - real (y), - imag (y)); } template inline complex<_FLT> operator * (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); template inline complex<_FLT> operator * (const complex<_FLT>& x, const complex<_FLT>& y) { return complex<_FLT> (real (x) * real (y) - imag (x) * imag (y), real (x) * imag (y) + imag (x) * real (y)); } template inline complex<_FLT> operator * (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); template inline complex<_FLT> operator * (const complex<_FLT>& x, _FLT y) { return complex<_FLT> (real (x) * y, imag (x) * y); } template inline complex<_FLT> operator * (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); template inline complex<_FLT> operator * (_FLT x, const complex<_FLT>& y) { return complex<_FLT> (x * real (y), x * imag (y)); } template complex<_FLT> operator / (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); template complex<_FLT> operator / (const complex<_FLT>& x, _FLT y) { return complex<_FLT> (real (x) / y, imag (x) / y); } template inline complex<_FLT> operator + (const complex<_FLT>& x) __attribute__ ((const)); template inline complex<_FLT> operator + (const complex<_FLT>& x) { return x; } template inline complex<_FLT> operator - (const complex<_FLT>& x) __attribute__ ((const)); template inline complex<_FLT> operator - (const complex<_FLT>& x) { return complex<_FLT> (-real (x), -imag (x)); } template inline bool operator == (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); template inline bool operator == (const complex<_FLT>& x, const complex<_FLT>& y) { return real (x) == real (y) && imag (x) == imag (y); } template inline bool operator == (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); template inline bool operator == (const complex<_FLT>& x, _FLT y) { return real (x) == y && imag (x) == 0; } template inline bool operator == (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); template inline bool operator == (_FLT x, const complex<_FLT>& y) { return x == real (y) && imag (y) == 0; } template inline bool operator != (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); template inline bool operator != (const complex<_FLT>& x, const complex<_FLT>& y) { return real (x) != real (y) || imag (x) != imag (y); } template inline bool operator != (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); template inline bool operator != (const complex<_FLT>& x, _FLT y) { return real (x) != y || imag (x) != 0; } template inline bool operator != (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); template inline bool operator != (_FLT x, const complex<_FLT>& y) { return x != real (y) || imag (y) != 0; } // Some targets don't provide a prototype for hypot when -ansi. extern "C" double hypot (double, double) __attribute__ ((const)); template inline _FLT abs (const complex<_FLT>& x) __attribute__ ((const)); template inline _FLT abs (const complex<_FLT>& x) { return hypot (real (x), imag (x)); } template inline _FLT arg (const complex<_FLT>& x) __attribute__ ((const)); template inline _FLT arg (const complex<_FLT>& x) { return atan2 (imag (x), real (x)); } template inline complex<_FLT> polar (_FLT r, _FLT t) __attribute__ ((const)); template inline complex<_FLT> polar (_FLT r, _FLT t) { return complex<_FLT> (r * cos (t), r * sin (t)); } template inline complex<_FLT> conj (const complex<_FLT>& x) __attribute__ ((const)); template inline complex<_FLT> conj (const complex<_FLT>& x) { return complex<_FLT> (real (x), -imag (x)); } template inline _FLT norm (const complex<_FLT>& x) __attribute__ ((const)); template inline _FLT norm (const complex<_FLT>& x) { return real (x) * real (x) + imag (x) * imag (x); } // Declarations of templates in complext.ccI template complex<_FLT> operator / (const complex<_FLT>&, const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> operator / (_FLT, const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> cos (const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> cosh (const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> exp (const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> log (const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> pow (const complex<_FLT>&, const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> pow (const complex<_FLT>&, _FLT) __attribute__ ((const)); template complex<_FLT> pow (const complex<_FLT>&, int) __attribute__ ((const)); template complex<_FLT> pow (_FLT, const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> sin (const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> sinh (const complex<_FLT>&) __attribute__ ((const)); template complex<_FLT> sqrt (const complex<_FLT>&) __attribute__ ((const)); template istream& operator >> (istream&, complex<_FLT>&); template ostream& operator << (ostream&, const complex<_FLT>&); } // extern "C++" // Specializations and such #include #include #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/std/dcomplex.h ================================================ // The -*- C++ -*- double_complex class. // Copyright (C) 1994 Free Software Foundation // This file is part of the GNU ANSI C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // As a special exception, if you link this library with files // compiled with a GNU compiler to produce an executable, this does not cause // the resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. // Written by Jason Merrill based upon the specification in the 27 May 1994 // C++ working paper, ANSI document X3J16/94-0098. #ifndef __DCOMPLEX__ #define __DCOMPLEX__ #ifdef __GNUG__ #pragma interface "dcomplex" #endif extern "C++" { class complex { public: complex (double r = 0, double i = 0): re (r), im (i) { } complex (const complex& r): re (r.real ()), im (r.imag ()) { } explicit complex (const complex& r); complex& operator+= (const complex& r) { return __doapl (this, r); } complex& operator-= (const complex& r) { return __doami (this, r); } complex& operator*= (const complex& r) { return __doaml (this, r); } complex& operator/= (const complex& r) { return __doadv (this, r); } double real () const { return re; } double imag () const { return im; } private: double re, im; friend complex& __doapl<> (complex *, const complex&); friend complex& __doami<> (complex *, const complex&); friend complex& __doaml<> (complex *, const complex&); friend complex& __doadv<> (complex *, const complex&); #ifndef __STRICT_ANSI__ friend inline complex operator + (const complex& x, double y) { return operator+<> (x, y); } friend inline complex operator + (double x, const complex& y) { return operator+<> (x, y); } friend inline complex operator - (const complex& x, double y) { return operator-<> (x, y); } friend inline complex operator - (double x, const complex& y) { return operator-<> (x, y); } friend inline complex operator * (const complex& x, double y) { return operator*<> (x, y); } friend inline complex operator * (double x, const complex& y) { return operator*<> (x, y); } friend inline complex operator / (const complex& x, double y) { return operator/<> (x, y); } friend inline complex operator / (double x, const complex& y) { return operator/<> (x, y); } friend inline bool operator == (const complex& x, double y) { return operator==<> (x, y); } friend inline bool operator == (double x, const complex& y) { return operator==<> (x, y); } friend inline bool operator != (const complex& x, double y) { return operator!=<> (x, y); } friend inline bool operator != (double x, const complex& y) { return operator!=<> (x, y); } #endif /* __STRICT_ANSI__ */ }; inline complex::complex (const complex& r) : re (r.real ()), im (r.imag ()) { } } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/std/fcomplex.h ================================================ // The -*- C++ -*- float_complex class. // Copyright (C) 1994 Free Software Foundation // This file is part of the GNU ANSI C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // As a special exception, if you link this library with files // compiled with a GNU compiler to produce an executable, this does not cause // the resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. // Written by Jason Merrill based upon the specification in the 27 May 1994 // C++ working paper, ANSI document X3J16/94-0098. #ifndef __FCOMPLEX__ #define __FCOMPLEX__ #ifdef __GNUG__ #pragma interface "fcomplex" #endif extern "C++" { class complex { public: complex (float r = 0, float i = 0): re (r), im (i) { } explicit complex (const complex& r); explicit complex (const complex& r); complex& operator+= (const complex& r) { return __doapl (this, r); } complex& operator-= (const complex& r) { return __doami (this, r); } complex& operator*= (const complex& r) { return __doaml (this, r); } complex& operator/= (const complex& r) { return __doadv (this, r); } float real () const { return re; } float imag () const { return im; } private: float re, im; friend complex& __doapl<> (complex *, const complex&); friend complex& __doami<> (complex *, const complex&); friend complex& __doaml<> (complex *, const complex&); friend complex& __doadv<> (complex *, const complex&); #ifndef __STRICT_ANSI__ friend inline complex operator + (const complex& x, float y) { return operator+<> (x, y); } friend inline complex operator + (float x, const complex& y) { return operator+<> (x, y); } friend inline complex operator - (const complex& x, float y) { return operator-<> (x, y); } friend inline complex operator - (float x, const complex& y) { return operator-<> (x, y); } friend inline complex operator * (const complex& x, float y) { return operator*<> (x, y); } friend inline complex operator * (float x, const complex& y) { return operator*<> (x, y); } friend inline complex operator / (const complex& x, float y) { return operator/<> (x, y); } friend inline complex operator / (float x, const complex& y) { return operator/<> (x, y); } friend inline bool operator == (const complex& x, float y) { return operator==<> (x, y); } friend inline bool operator == (float x, const complex& y) { return operator==<> (x, y); } friend inline bool operator != (const complex& x, float y) { return operator!=<> (x, y); } friend inline bool operator != (float x, const complex& y) { return operator!=<> (x, y); } #endif /* __STRICT_ANSI__ */ }; } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/std/ldcomplex.h ================================================ // The -*- C++ -*- long_double_complex class. // Copyright (C) 1994 Free Software Foundation // This file is part of the GNU ANSI C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // As a special exception, if you link this library with files // compiled with a GNU compiler to produce an executable, this does not cause // the resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. // Written by Jason Merrill based upon the specification in the 27 May 1994 // C++ working paper, ANSI document X3J16/94-0098. #ifndef __LDCOMPLEX__ #define __LDCOMPLEX__ #ifdef __GNUG__ #pragma interface "ldcomplex" #endif extern "C++" { class complex { public: complex (long double r = 0, long double i = 0): re (r), im (i) { } complex (const complex& r): re (r.real ()), im (r.imag ()) { } complex (const complex& r): re (r.real ()), im (r.imag ()) { } complex& operator+= (const complex& r) { return __doapl (this, r); } complex& operator-= (const complex& r) { return __doami (this, r); } complex& operator*= (const complex& r) { return __doaml (this, r); } complex& operator/= (const complex& r) { return __doadv (this, r); } long double real () const { return re; } long double imag () const { return im; } private: long double re, im; friend complex& __doapl<> (complex *, const complex&); friend complex& __doami<> (complex *, const complex&); friend complex& __doaml<> (complex *, const complex&); friend complex& __doadv<> (complex *, const complex&); #ifndef __STRICT_ANSI__ friend inline complex operator + (const complex& x, long double y) { return operator+<> (x, y); } friend inline complex operator + (long double x, const complex& y) { return operator+<> (x, y); } friend inline complex operator - (const complex& x, long double y) { return operator-<> (x, y); } friend inline complex operator - (long double x, const complex& y) { return operator-<> (x, y); } friend inline complex operator * (const complex& x, long double y) { return operator*<> (x, y); } friend inline complex operator * (long double x, const complex& y) { return operator*<> (x, y); } friend inline complex operator / (const complex& x, long double y) { return operator/<> (x, y); } friend inline complex operator / (long double x, const complex& y) { return operator/<> (x, y); } friend inline bool operator == (const complex& x, long double y) { return operator==<> (x, y); } friend inline bool operator == (long double x, const complex& y) { return operator==<> (x, y); } friend inline bool operator != (const complex& x, long double y) { return operator!=<> (x, y); } friend inline bool operator != (long double x, const complex& y) { return operator!=<> (x, y); } #endif /* __STRICT_ANSI__ */ }; inline complex::complex (const complex& r) : re (r.real ()), im (r.imag ()) { } inline complex::complex (const complex& r) : re (r.real ()), im (r.imag ()) { } } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/std/straits.h ================================================ // Character traits template for the -*- C++ -*- string classes. // Copyright (C) 1994 Free Software Foundation // This file is part of the GNU ANSI C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // As a special exception, if you link this library with files // compiled with a GNU compiler to produce an executable, this does not cause // the resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. // Written by Jason Merrill based upon the specification by Takanori Adachi // in ANSI X3J16/94-0013R2. #ifndef __STRING_CHAR_TRAITS__ #define __STRING_CHAR_TRAITS__ #ifdef __GNUG__ // For string_char_traits #pragma interface "std/straits.h" #endif #include extern "C++" { template struct string_char_traits { typedef charT char_type; // for users to acquire the basic character type // constraints 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 ne (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 char_type eos () { return char_type(); } // the null character static bool is_del(char_type a) { return 0; } // characteristic function for delimiters of charT // speed-up functions static int compare (const char_type* s1, const char_type* s2, size_t n) { size_t i; for (i = 0; i < n; ++i) if (ne (s1[i], s2[i])) return lt (s1[i], s2[i]) ? -1 : 1; return 0; } static size_t length (const char_type* s) { size_t l = 0; while (ne (*s++, eos ())) ++l; return l; } static char_type* copy (char_type* s1, const char_type* s2, size_t n) { for (; n--; ) assign (s1[n], s2[n]); return s1; } static char_type* move (char_type* s1, const char_type* s2, size_t n) { char_type a[n]; size_t i; for (i = 0; i < n; ++i) assign (a[i], s2[i]); for (i = 0; i < n; ++i) assign (s1[i], a[i]); return s1; } static char_type* set (char_type* s1, const char_type& c, size_t n) { for (; n--; ) assign (s1[n], c); return s1; } }; class istream; class ostream; #include #include struct string_char_traits { typedef char char_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 ne (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 char_type eos () { return 0; } static bool is_del(char_type a) { return isspace(a); } 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 char_type* copy (char_type* s1, const char_type* s2, size_t n) { return (char_type*) memcpy (s1, s2, n); } static char_type* move (char_type* s1, const char_type* s2, size_t n) { return (char_type*) memmove (s1, s2, n); } static char_type* set (char_type* s1, const char_type& c, size_t n) { return (char_type*) memset (s1, c, n); } }; #if 0 #include struct string_char_traits { typedef wchar_t char_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 ne (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 char_type eos () { return 0; } static bool is_del(char_type a) { return iswspace(a); } 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 char_type* copy (char_type* s1, const char_type* s2, size_t n) { return wmemcpy (s1, s2, n); } static char_type* set (char_type* s1, const char_type& c, size_t n) { return wmemset (s1, c, n); } }; #endif } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/stdexcept ================================================ // Methods for Exception Support for -*- C++ -*- // Copyright (C) 1994, 1995, 1997 Free Software Foundation // This file is part of the GNU ANSI C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // As a special exception, if you link this library with files // compiled with a GNU compiler to produce an executable, this does not cause // the resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. // Written by Mike Stump based upon the specification in the 20 September 1994 // C++ working paper, ANSI document X3J16/94-0158. #ifndef __STDEXCEPT__ #define __STDEXCEPT__ #ifdef __GNUG__ #pragma interface "stdexcept" #endif #include #include extern "C++" { #ifdef __HONOR_STD namespace std { #endif class logic_error : public exception { string _what; public: logic_error(const string& what_arg): _what (what_arg) { } virtual const char* what () const { return _what.c_str (); } }; class domain_error : public logic_error { public: domain_error (const string& what_arg): logic_error (what_arg) { } }; class invalid_argument : public logic_error { public: invalid_argument (const string& what_arg): logic_error (what_arg) { } }; class length_error : public logic_error { public: length_error (const string& what_arg): logic_error (what_arg) { } }; class out_of_range : public logic_error { public: out_of_range (const string& what_arg): logic_error (what_arg) { } }; class runtime_error : public exception { string _what; public: runtime_error(const string& what_arg): _what (what_arg) { } virtual const char* what () const { return _what.c_str (); } protected: runtime_error(): exception () { } }; class range_error : public runtime_error { public: range_error (const string& what_arg): runtime_error (what_arg) { } }; class overflow_error : public runtime_error { public: overflow_error (const string& what_arg): runtime_error (what_arg) { } }; class underflow_error : public runtime_error { public: underflow_error (const string& what_arg): runtime_error (what_arg) { } }; #ifdef __HONOR_STD } // namespace std #endif } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/stdiostream.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Written by Per Bothner (bothner@cygnus.com). */ #ifndef _STDIOSTREAM_H #define _STDIOSTREAM_H #ifdef __GNUG__ #pragma interface #endif #include #include extern "C++" { class stdiobuf : public filebuf { protected: FILE *_file; public: FILE* stdiofile() const { return _file; } stdiobuf(FILE *); ~stdiobuf(); int buffered () const { return _flags & _IO_UNBUFFERED ? 0 : 1; } void buffered (int); virtual streamsize sys_read(char*, streamsize); virtual streampos sys_seek(streamoff, _seek_dir); virtual streamsize sys_write(const char*, streamsize); virtual int sys_close(); virtual int sync(); virtual int overflow(int c = EOF); streamsize xsputn(const char* s, streamsize n); }; class istdiostream : public istream { private: stdiobuf _file; public: istdiostream (FILE* __f) : istream(), _file(__f) { init(&_file); } stdiobuf* rdbuf()/* const */ { return &_file; } int buffered () const { return _file.buffered (); } void buffered (int _i) { _file.buffered (_i); } }; class ostdiostream : public ostream { private: stdiobuf _file; public: ostdiostream (FILE* __f) : ostream(), _file(__f) { init(&_file); } stdiobuf* rdbuf() /* const */ { return &_file; } int buffered () const { return _file.buffered (); } void buffered (int _i) { _file.buffered (_i); } }; } // extern "C++" #endif /* !_STDIOSTREAM_H */ ================================================ FILE: tass-sgi-stl-2.91.57-source/stl.h ================================================ // -*- C++ -*- compatibility header. // This file is part of the GNU ANSI C++ Library. #include #include #include #include #include #include #include #include #include #include #include #include ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_algo.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ALGO_H #define __SGI_STL_INTERNAL_ALGO_H #include __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1209 #endif template inline const T& __median(const T& a, const T& b, const T& c) { 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; } template inline const T& __median(const T& a, const T& b, const T& c, Compare comp) { 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; } template Function for_each(InputIterator first, InputIterator last, Function f) { for ( ; first != last; ++first) f(*first); return f; } template InputIterator find(InputIterator first, InputIterator last, const T& value) { while (first != last && *first != value) ++first; return first; } template InputIterator find_if(InputIterator first, InputIterator last, Predicate pred) { while (first != last && !pred(*first)) ++first; return first; } template ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) { if (first == last) return last; ForwardIterator next = first; while(++next != last) { if (*first == *next) return first; first = next; } return last; } template ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred) { if (first == last) return last; ForwardIterator next = first; while(++next != last) { if (binary_pred(*first, *next)) return first; first = next; } return last; } template void count(InputIterator first, InputIterator last, const T& value, Size& n) { for ( ; first != last; ++first) if (*first == value) ++n; } template void count_if(InputIterator first, InputIterator last, Predicate pred, Size& n) { for ( ; first != last; ++first) if (pred(*first)) ++n; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template typename iterator_traits::difference_type count(InputIterator first, InputIterator last, const T& value) { typename iterator_traits::difference_type n = 0; for ( ; first != last; ++first) if (*first == value) ++n; return n; } template typename iterator_traits::difference_type count_if(InputIterator first, InputIterator last, Predicate pred) { typename iterator_traits::difference_type n = 0; for ( ; first != last; ++first) if (pred(*first)) ++n; return n; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Distance1*, Distance2*) { Distance1 d1 = 0; distance(first1, last1, d1); Distance2 d2 = 0; distance(first2, last2, d2); if (d1 < d2) return last1; ForwardIterator1 current1 = first1; ForwardIterator2 current2 = first2; while (current2 != last2) if (*current1 == *current2) { ++current1; ++current2; } else { if (d1 == d2) return last1; else { current1 = ++first1; current2 = first2; --d1; } } return first1; } template inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { return __search(first1, last1, first2, last2, distance_type(first1), distance_type(first2)); } template ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate binary_pred, Distance1*, Distance2*) { Distance1 d1 = 0; distance(first1, last1, d1); Distance2 d2 = 0; distance(first2, last2, d2); if (d1 < d2) return last1; ForwardIterator1 current1 = first1; ForwardIterator2 current2 = first2; while (current2 != last2) if (binary_pred(*current1, *current2)) { ++current1; ++current2; } else { if (d1 == d2) return last1; else { current1 = ++first1; current2 = first2; --d1; } } return first1; } template inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate binary_pred) { return __search(first1, last1, first2, last2, binary_pred, distance_type(first1), distance_type(first2)); } template ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Integer count, const T& value) { if (count <= 0) return first; else { first = find(first, last, value); while (first != last) { Integer n = count - 1; ForwardIterator i = first; ++i; while (i != last && n != 0 && *i == value) { ++i; --n; } if (n == 0) return first; else first = find(i, last, value); } return last; } } template ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Integer count, const T& value, BinaryPredicate binary_pred) { if (count <= 0) return first; else { while (first != last) { if (binary_pred(*first, value)) break; ++first; } while (first != last) { Integer n = count - 1; ForwardIterator i = first; ++i; while (i != last && n != 0 && binary_pred(*i, value)) { ++i; --n; } if (n == 0) return first; else { while (i != last) { if (binary_pred(*i, value)) break; ++i; } first = i; } } return last; } } template ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { for ( ; first1 != last1; ++first1, ++first2) iter_swap(first1, first2); return first2; } template OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op) { for ( ; first != last; ++first, ++result) *result = op(*first); return result; } template OutputIterator transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op) { for ( ; first1 != last1; ++first1, ++first2, ++result) *result = binary_op(*first1, *first2); return result; } template void replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value) { for ( ; first != last; ++first) if (*first == old_value) *first = new_value; } template void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value) { for ( ; first != last; ++first) if (pred(*first)) *first = new_value; } template OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value) { for ( ; first != last; ++first, ++result) *result = *first == old_value ? new_value : *first; return result; } template OutputIterator replace_copy_if(Iterator first, Iterator last, OutputIterator result, Predicate pred, const T& new_value) { for ( ; first != last; ++first, ++result) *result = pred(*first) ? new_value : *first; return result; } template void generate(ForwardIterator first, ForwardIterator last, Generator gen) { for ( ; first != last; ++first) *first = gen(); } template OutputIterator generate_n(OutputIterator first, Size n, Generator gen) { for ( ; n > 0; --n, ++first) *first = gen(); return first; } template OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value) { for ( ; first != last; ++first) if (*first != value) { *result = *first; ++result; } return result; } template OutputIterator remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred) { for ( ; first != last; ++first) if (!pred(*first)) { *result = *first; ++result; } return result; } template ForwardIterator remove(ForwardIterator first, ForwardIterator last, const T& value) { first = find(first, last, value); ForwardIterator next = first; return first == last ? first : remove_copy(++next, last, first, value); } template ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, Predicate pred) { first = find_if(first, last, pred); ForwardIterator next = first; return first == last ? first : remove_copy_if(++next, last, first, pred); } template ForwardIterator __unique_copy(InputIterator first, InputIterator last, ForwardIterator result, forward_iterator_tag) { *result = *first; while (++first != last) if (*result != *first) *++result = *first; return ++result; } template OutputIterator __unique_copy(InputIterator first, InputIterator last, OutputIterator result, T*) { T value = *first; *result = value; while (++first != last) if (value != *first) { value = *first; *++result = value; } return ++result; } template inline OutputIterator __unique_copy(InputIterator first, InputIterator last, OutputIterator result, output_iterator_tag) { return __unique_copy(first, last, result, value_type(first)); } template inline OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result) { if (first == last) return result; return __unique_copy(first, last, result, iterator_category(result)); } template ForwardIterator __unique_copy(InputIterator first, InputIterator last, ForwardIterator result, BinaryPredicate binary_pred, forward_iterator_tag) { *result = *first; while (++first != last) if (!binary_pred(*result, *first)) *++result = *first; return ++result; } template OutputIterator __unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate binary_pred, T*) { T value = *first; *result = value; while (++first != last) if (!binary_pred(value, *first)) { value = *first; *++result = value; } return ++result; } template inline OutputIterator __unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate binary_pred, output_iterator_tag) { return __unique_copy(first, last, result, binary_pred, value_type(first)); } template inline OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate binary_pred) { if (first == last) return result; return __unique_copy(first, last, result, binary_pred, iterator_category(result)); } template ForwardIterator unique(ForwardIterator first, ForwardIterator last) { first = adjacent_find(first, last); return unique_copy(first, last, first); } template ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred) { first = adjacent_find(first, last, binary_pred); return unique_copy(first, last, first, binary_pred); } template void __reverse(BidirectionalIterator first, BidirectionalIterator last, bidirectional_iterator_tag) { while (true) if (first == last || first == --last) return; else iter_swap(first++, last); } template void __reverse(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag) { while (first < last) iter_swap(first++, --last); } template inline void reverse(BidirectionalIterator first, BidirectionalIterator last) { __reverse(first, last, iterator_category(first)); } template OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result) { while (first != last) { --last; *result = *last; ++result; } return result; } template void __rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last, Distance*, forward_iterator_tag) { for (ForwardIterator i = middle; ;) { iter_swap(first, i); ++first; ++i; if (first == middle) { if (i == last) return; middle = i; } else if (i == last) i = middle; } } template void __rotate(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Distance*, bidirectional_iterator_tag) { reverse(first, middle); reverse(middle, last); reverse(first, last); } template EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n) { while (n != 0) { EuclideanRingElement t = m % n; m = n; n = t; } return m; } template void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator initial, Distance shift, T*) { T value = *initial; RandomAccessIterator ptr1 = initial; RandomAccessIterator ptr2 = ptr1 + shift; while (ptr2 != initial) { *ptr1 = *ptr2; ptr1 = ptr2; if (last - ptr2 > shift) ptr2 += shift; else ptr2 = first + (shift - (last - ptr2)); } *ptr1 = value; } template void __rotate(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Distance*, random_access_iterator_tag) { Distance n = __gcd(last - first, middle - first); while (n--) __rotate_cycle(first, last, first + n, middle - first, value_type(first)); } template inline void rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last) { if (first == middle || middle == last) return; __rotate(first, middle, last, distance_type(first), iterator_category(first)); } template OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result) { return copy(first, middle, copy(middle, last, result)); } template void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last, Distance*) { if (first == last) return; for (RandomAccessIterator i = first + 1; i != last; ++i) #ifdef __STL_NO_DRAND48 iter_swap(i, first + Distance(rand() % ((i - first) + 1))); #else iter_swap(i, first + Distance(lrand48() % ((i - first) + 1))); #endif } template inline void random_shuffle(RandomAccessIterator first, RandomAccessIterator last) { __random_shuffle(first, last, distance_type(first)); } template void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rand) { if (first == last) return; for (RandomAccessIterator i = first + 1; i != last; ++i) iter_swap(i, first + rand((i - first) + 1)); } template OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, OutputIterator out, const Distance n) { Distance remaining = 0; distance(first, last, remaining); Distance m = min(n, remaining); while (m > 0) { #ifdef __STL_NO_DRAND48 if (rand() % remaining < m) { #else if (lrand48() % remaining < m) { #endif *out = *first; ++out; --m; } --remaining; ++first; } return out; } template OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, OutputIterator out, const Distance n, RandomNumberGenerator& rand) { Distance remaining = 0; distance(first, last, remaining); Distance m = min(n, remaining); while (m > 0) { if (rand(remaining) < m) { *out = *first; ++out; --m; } --remaining; ++first; } return out; } template 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; #ifdef __STL_NO_DRAND48 Distance M = rand() % t; #else Distance M = lrand48() % t; #endif if (M < n) out[M] = *first; ++first; } return out + m; } template RandomAccessIterator __random_sample(InputIterator first, InputIterator last, RandomAccessIterator out, RandomNumberGenerator& rand, 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 = rand(t); if (M < n) out[M] = *first; ++first; } return out + m; } template inline RandomAccessIterator random_sample(InputIterator first, InputIterator last, RandomAccessIterator out_first, RandomAccessIterator out_last) { return __random_sample(first, last, out_first, out_last - out_first); } template inline RandomAccessIterator random_sample(InputIterator first, InputIterator last, RandomAccessIterator out_first, RandomAccessIterator out_last, RandomNumberGenerator& rand) { return __random_sample(first, last, out_first, rand, out_last - out_first); } template BidirectionalIterator partition(BidirectionalIterator first, BidirectionalIterator last, Predicate pred) { 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; iter_swap(first, last); ++first; } } template ForwardIterator __inplace_stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred, Distance len) { if (len == 1) return pred(*first) ? last : first; ForwardIterator middle = first; advance(middle, len / 2); ForwardIterator first_cut = __inplace_stable_partition(first, middle, pred, len / 2); ForwardIterator second_cut = __inplace_stable_partition(middle, last, pred, len - len / 2); rotate(first_cut, middle, second_cut); len = 0; distance(middle, second_cut, len); advance(first_cut, len); return first_cut; } template 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; } copy(buffer, result2, result1); return result1; } else { ForwardIterator middle = first; advance(middle, len / 2); ForwardIterator first_cut = __stable_partition_adaptive(first, middle, pred, len / 2, buffer, buffer_size); ForwardIterator second_cut = __stable_partition_adaptive(middle, last, pred, len - len / 2, buffer, buffer_size); rotate(first_cut, middle, second_cut); len = 0; distance(middle, second_cut, len); advance(first_cut, len); return first_cut; } } template inline ForwardIterator __stable_partition_aux(ForwardIterator first, ForwardIterator last, Predicate pred, T*, Distance*) { temporary_buffer buf(first, last); if (buf.size() > 0) return __stable_partition_adaptive(first, last, pred, Distance(buf.requested_size()), buf.begin(), buf.size()); else return __inplace_stable_partition(first, last, pred, Distance(buf.requested_size())); } template inline ForwardIterator stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred) { if (first == last) return first; else return __stable_partition_aux(first, last, pred, value_type(first), distance_type(first)); } template RandomAccessIterator __unguarded_partition(RandomAccessIterator first, RandomAccessIterator last, T pivot) { while (true) { while (*first < pivot) ++first; --last; while (pivot < *last) --last; if (!(first < last)) return first; iter_swap(first, last); ++first; } } template RandomAccessIterator __unguarded_partition(RandomAccessIterator first, RandomAccessIterator last, T pivot, Compare comp) { while (1) { while (comp(*first, pivot)) ++first; --last; while (comp(pivot, *last)) --last; if (!(first < last)) return first; iter_swap(first, last); ++first; } } const int __stl_threshold = 16; template void __unguarded_linear_insert(RandomAccessIterator last, T value) { RandomAccessIterator next = last; --next; while (value < *next) { *last = *next; last = next; --next; } *last = value; } template void __unguarded_linear_insert(RandomAccessIterator last, T value, Compare comp) { RandomAccessIterator next = last; --next; while (comp(value , *next)) { *last = *next; last = next; --next; } *last = value; } template inline void __linear_insert(RandomAccessIterator first, RandomAccessIterator last, T*) { T value = *last; if (value < *first) { copy_backward(first, last, last + 1); *first = value; } else __unguarded_linear_insert(last, value); } template inline void __linear_insert(RandomAccessIterator first, RandomAccessIterator last, T*, Compare comp) { T value = *last; if (comp(value, *first)) { copy_backward(first, last, last + 1); *first = value; } else __unguarded_linear_insert(last, value, comp); } template void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) { if (first == last) return; for (RandomAccessIterator i = first + 1; i != last; ++i) __linear_insert(first, i, value_type(first)); } template void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { if (first == last) return; for (RandomAccessIterator i = first + 1; i != last; ++i) __linear_insert(first, i, value_type(first), comp); } template void __unguarded_insertion_sort_aux(RandomAccessIterator first, RandomAccessIterator last, T*) { for (RandomAccessIterator i = first; i != last; ++i) __unguarded_linear_insert(i, T(*i)); } template inline void __unguarded_insertion_sort(RandomAccessIterator first, RandomAccessIterator last) { __unguarded_insertion_sort_aux(first, last, value_type(first)); } template void __unguarded_insertion_sort_aux(RandomAccessIterator first, RandomAccessIterator last, T*, Compare comp) { for (RandomAccessIterator i = first; i != last; ++i) __unguarded_linear_insert(i, T(*i), comp); } template inline void __unguarded_insertion_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { __unguarded_insertion_sort_aux(first, last, value_type(first), comp); } template void __final_insertion_sort(RandomAccessIterator first, RandomAccessIterator last) { if (last - first > __stl_threshold) { __insertion_sort(first, first + __stl_threshold); __unguarded_insertion_sort(first + __stl_threshold, last); } else __insertion_sort(first, last); } template void __final_insertion_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { if (last - first > __stl_threshold) { __insertion_sort(first, first + __stl_threshold, comp); __unguarded_insertion_sort(first + __stl_threshold, last, comp); } else __insertion_sort(first, last, comp); } template inline Size __lg(Size n) { Size k; for (k = 0; n > 1; n >>= 1) ++k; return k; } template void __introsort_loop(RandomAccessIterator first, RandomAccessIterator last, T*, Size depth_limit) { while (last - first > __stl_threshold) { if (depth_limit == 0) { partial_sort(first, last, last); return; } --depth_limit; RandomAccessIterator cut = __unguarded_partition (first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1)))); __introsort_loop(cut, last, value_type(first), depth_limit); last = cut; } } template void __introsort_loop(RandomAccessIterator first, RandomAccessIterator last, T*, Size depth_limit, Compare comp) { while (last - first > __stl_threshold) { if (depth_limit == 0) { partial_sort(first, last, last, comp); return; } --depth_limit; RandomAccessIterator cut = __unguarded_partition (first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1), comp)), comp); __introsort_loop(cut, last, value_type(first), depth_limit, comp); last = cut; } } template inline void sort(RandomAccessIterator first, RandomAccessIterator last) { if (first != last) { __introsort_loop(first, last, value_type(first), __lg(last - first) * 2); __final_insertion_sort(first, last); } } template inline void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { if (first != last) { __introsort_loop(first, last, value_type(first), __lg(last - first) * 2, comp); __final_insertion_sort(first, last, comp); } } template void __inplace_stable_sort(RandomAccessIterator first, RandomAccessIterator last) { if (last - first < 15) { __insertion_sort(first, last); return; } RandomAccessIterator middle = first + (last - first) / 2; __inplace_stable_sort(first, middle); __inplace_stable_sort(middle, last); __merge_without_buffer(first, middle, last, middle - first, last - middle); } template void __inplace_stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { if (last - first < 15) { __insertion_sort(first, last, comp); return; } RandomAccessIterator middle = first + (last - first) / 2; __inplace_stable_sort(first, middle, comp); __inplace_stable_sort(middle, last, comp); __merge_without_buffer(first, middle, last, middle - first, last - middle, comp); } template void __merge_sort_loop(RandomAccessIterator1 first, RandomAccessIterator1 last, RandomAccessIterator2 result, Distance step_size) { Distance two_step = 2 * step_size; while (last - first >= two_step) { result = merge(first, first + step_size, first + step_size, first + two_step, result); first += two_step; } step_size = min(Distance(last - first), step_size); merge(first, first + step_size, first + step_size, last, result); } template void __merge_sort_loop(RandomAccessIterator1 first, RandomAccessIterator1 last, RandomAccessIterator2 result, Distance step_size, Compare comp) { Distance two_step = 2 * step_size; while (last - first >= two_step) { result = merge(first, first + step_size, first + step_size, first + two_step, result, comp); first += two_step; } step_size = min(Distance(last - first), step_size); merge(first, first + step_size, first + step_size, last, result, comp); } const int __stl_chunk_size = 7; template void __chunk_insertion_sort(RandomAccessIterator first, RandomAccessIterator last, Distance chunk_size) { while (last - first >= chunk_size) { __insertion_sort(first, first + chunk_size); first += chunk_size; } __insertion_sort(first, last); } template void __chunk_insertion_sort(RandomAccessIterator first, RandomAccessIterator last, Distance chunk_size, Compare comp) { while (last - first >= chunk_size) { __insertion_sort(first, first + chunk_size, comp); first += chunk_size; } __insertion_sort(first, last, comp); } template void __merge_sort_with_buffer(RandomAccessIterator first, RandomAccessIterator last, Pointer buffer, Distance*) { Distance len = last - first; Pointer buffer_last = buffer + len; Distance step_size = __stl_chunk_size; __chunk_insertion_sort(first, last, step_size); while (step_size < len) { __merge_sort_loop(first, last, buffer, step_size); step_size *= 2; __merge_sort_loop(buffer, buffer_last, first, step_size); step_size *= 2; } } template void __merge_sort_with_buffer(RandomAccessIterator first, RandomAccessIterator last, Pointer buffer, Distance*, Compare comp) { Distance len = last - first; Pointer buffer_last = buffer + len; Distance step_size = __stl_chunk_size; __chunk_insertion_sort(first, last, step_size, comp); while (step_size < len) { __merge_sort_loop(first, last, buffer, step_size, comp); step_size *= 2; __merge_sort_loop(buffer, buffer_last, first, step_size, comp); step_size *= 2; } } template void __stable_sort_adaptive(RandomAccessIterator first, RandomAccessIterator last, Pointer buffer, Distance buffer_size) { Distance len = (last - first + 1) / 2; RandomAccessIterator middle = first + len; if (len > buffer_size) { __stable_sort_adaptive(first, middle, buffer, buffer_size); __stable_sort_adaptive(middle, last, buffer, buffer_size); } else { __merge_sort_with_buffer(first, middle, buffer, (Distance*)0); __merge_sort_with_buffer(middle, last, buffer, (Distance*)0); } __merge_adaptive(first, middle, last, Distance(middle - first), Distance(last - middle), buffer, buffer_size); } template void __stable_sort_adaptive(RandomAccessIterator first, RandomAccessIterator last, Pointer buffer, Distance buffer_size, Compare comp) { Distance len = (last - first + 1) / 2; RandomAccessIterator middle = first + len; if (len > buffer_size) { __stable_sort_adaptive(first, middle, buffer, buffer_size, comp); __stable_sort_adaptive(middle, last, buffer, buffer_size, comp); } else { __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, comp); __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, comp); } __merge_adaptive(first, middle, last, Distance(middle - first), Distance(last - middle), buffer, buffer_size, comp); } template inline void __stable_sort_aux(RandomAccessIterator first, RandomAccessIterator last, T*, Distance*) { temporary_buffer buf(first, last); if (buf.begin() == 0) __inplace_stable_sort(first, last); else __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size())); } template inline void __stable_sort_aux(RandomAccessIterator first, RandomAccessIterator last, T*, Distance*, Compare comp) { temporary_buffer buf(first, last); if (buf.begin() == 0) __inplace_stable_sort(first, last, comp); else __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()), comp); } template inline void stable_sort(RandomAccessIterator first, RandomAccessIterator last) { __stable_sort_aux(first, last, value_type(first), distance_type(first)); } template inline void stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { __stable_sort_aux(first, last, value_type(first), distance_type(first), comp); } template void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, T*) { make_heap(first, middle); for (RandomAccessIterator i = middle; i < last; ++i) if (*i < *first) __pop_heap(first, middle, i, T(*i), distance_type(first)); sort_heap(first, middle); } template inline void partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last) { __partial_sort(first, middle, last, value_type(first)); } template void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, T*, Compare comp) { make_heap(first, middle, comp); for (RandomAccessIterator i = middle; i < last; ++i) if (comp(*i, *first)) __pop_heap(first, middle, i, T(*i), comp, distance_type(first)); sort_heap(first, middle, comp); } template inline void partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp) { __partial_sort(first, middle, last, value_type(first), comp); } template RandomAccessIterator __partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Distance*, T*) { 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; } make_heap(result_first, result_real_last); while (first != last) { if (*first < *result_first) __adjust_heap(result_first, Distance(0), Distance(result_real_last - result_first), T(*first)); ++first; } sort_heap(result_first, result_real_last); return result_real_last; } template inline RandomAccessIterator partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last) { return __partial_sort_copy(first, last, result_first, result_last, distance_type(result_first), value_type(first)); } template RandomAccessIterator __partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp, Distance*, T*) { 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; } make_heap(result_first, result_real_last, comp); while (first != last) { if (comp(*first, *result_first)) __adjust_heap(result_first, Distance(0), Distance(result_real_last - result_first), T(*first), comp); ++first; } sort_heap(result_first, result_real_last, comp); return result_real_last; } template inline RandomAccessIterator partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp) { return __partial_sort_copy(first, last, result_first, result_last, comp, distance_type(result_first), value_type(first)); } template void __nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, T*) { while (last - first > 3) { RandomAccessIterator cut = __unguarded_partition (first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1)))); if (cut <= nth) first = cut; else last = cut; } __insertion_sort(first, last); } template inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last) { __nth_element(first, nth, last, value_type(first)); } template void __nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, T*, Compare comp) { while (last - first > 3) { RandomAccessIterator cut = __unguarded_partition (first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1), comp)), comp); if (cut <= nth) first = cut; else last = cut; } __insertion_sort(first, last, comp); } template inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp) { __nth_element(first, nth, last, value_type(first), comp); } template ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Distance*, forward_iterator_tag) { Distance len = 0; distance(first, last, len); Distance half; ForwardIterator middle; while (len > 0) { half = len >> 1; middle = first; advance(middle, half); if (*middle < value) { first = middle; ++first; len = len - half - 1; } else len = half; } return first; } template RandomAccessIterator __lower_bound(RandomAccessIterator first, RandomAccessIterator last, const T& value, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle; while (len > 0) { half = len >> 1; middle = first + half; if (*middle < value) { first = middle + 1; len = len - half - 1; } else len = half; } return first; } template inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value) { return __lower_bound(first, last, value, distance_type(first), iterator_category(first)); } template ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp, Distance*, forward_iterator_tag) { Distance len = 0; distance(first, last, len); Distance half; ForwardIterator middle; while (len > 0) { half = len >> 1; middle = first; advance(middle, half); if (comp(*middle, value)) { first = middle; ++first; len = len - half - 1; } else len = half; } return first; } template RandomAccessIterator __lower_bound(RandomAccessIterator first, RandomAccessIterator last, const T& value, Compare comp, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle; while (len > 0) { half = len >> 1; middle = first + half; if (comp(*middle, value)) { first = middle + 1; len = len - half - 1; } else len = half; } return first; } template inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp) { return __lower_bound(first, last, value, comp, distance_type(first), iterator_category(first)); } template ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Distance*, forward_iterator_tag) { Distance len = 0; distance(first, last, len); Distance half; ForwardIterator middle; while (len > 0) { half = len >> 1; middle = first; advance(middle, half); if (value < *middle) len = half; else { first = middle; ++first; len = len - half - 1; } } return first; } template RandomAccessIterator __upper_bound(RandomAccessIterator first, RandomAccessIterator last, const T& value, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle; while (len > 0) { half = len >> 1; middle = first + half; if (value < *middle) len = half; else { first = middle + 1; len = len - half - 1; } } return first; } template inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value) { return __upper_bound(first, last, value, distance_type(first), iterator_category(first)); } template ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp, Distance*, forward_iterator_tag) { Distance len = 0; distance(first, last, len); Distance half; ForwardIterator middle; while (len > 0) { half = len >> 1; middle = first; advance(middle, half); if (comp(value, *middle)) len = half; else { first = middle; ++first; len = len - half - 1; } } return first; } template RandomAccessIterator __upper_bound(RandomAccessIterator first, RandomAccessIterator last, const T& value, Compare comp, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle; while (len > 0) { half = len >> 1; middle = first + half; if (comp(value, *middle)) len = half; else { first = middle + 1; len = len - half - 1; } } return first; } template inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp) { return __upper_bound(first, last, value, comp, distance_type(first), iterator_category(first)); } template pair __equal_range(ForwardIterator first, ForwardIterator last, const T& value, Distance*, forward_iterator_tag) { Distance len = 0; distance(first, last, len); Distance half; ForwardIterator middle, left, right; while (len > 0) { half = len >> 1; middle = first; advance(middle, half); if (*middle < value) { first = middle; ++first; len = len - half - 1; } else if (value < *middle) len = half; else { left = lower_bound(first, middle, value); advance(first, len); right = upper_bound(++middle, first, value); return pair(left, right); } } return pair(first, first); } template pair __equal_range(RandomAccessIterator first, RandomAccessIterator last, const T& value, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle, left, right; while (len > 0) { half = len >> 1; middle = first + half; if (*middle < value) { first = middle + 1; len = len - half - 1; } else if (value < *middle) len = half; else { left = lower_bound(first, middle, value); right = upper_bound(++middle, first + len, value); return pair(left, right); } } return pair(first, first); } template inline pair equal_range(ForwardIterator first, ForwardIterator last, const T& value) { return __equal_range(first, last, value, distance_type(first), iterator_category(first)); } template pair __equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp, Distance*, forward_iterator_tag) { Distance len = 0; distance(first, last, len); Distance half; ForwardIterator middle, left, right; while (len > 0) { half = len >> 1; middle = first; advance(middle, half); if (comp(*middle, value)) { first = middle; ++first; len = len - half - 1; } else if (comp(value, *middle)) len = half; else { left = lower_bound(first, middle, value, comp); advance(first, len); right = upper_bound(++middle, first, value, comp); return pair(left, right); } } return pair(first, first); } template pair __equal_range(RandomAccessIterator first, RandomAccessIterator last, const T& value, Compare comp, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle, left, right; while (len > 0) { half = len >> 1; middle = first + half; if (comp(*middle, value)) { first = middle + 1; len = len - half - 1; } else if (comp(value, *middle)) len = half; else { left = lower_bound(first, middle, value, comp); right = upper_bound(++middle, first + len, value, comp); return pair(left, right); } } return pair(first, first); } template inline pair equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp) { return __equal_range(first, last, value, comp, distance_type(first), iterator_category(first)); } template bool binary_search(ForwardIterator first, ForwardIterator last, const T& value) { ForwardIterator i = lower_bound(first, last, value); return i != last && !(value < *i); } template bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp) { ForwardIterator i = lower_bound(first, last, value, comp); return i != last && !comp(value, *i); } template OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { while (first1 != last1 && first2 != last2) { if (*first2 < *first1) { *result = *first2; ++first2; } else { *result = *first1; ++first1; } ++result; } return copy(first2, last2, copy(first1, last1, result)); } template OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp) { while (first1 != last1 && first2 != last2) { if (comp(*first2, *first1)) { *result = *first2; ++first2; } else { *result = *first1; ++first1; } ++result; } return copy(first2, last2, copy(first1, last1, result)); } template 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) 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; advance(first_cut, len11); second_cut = lower_bound(middle, last, *first_cut); distance(middle, second_cut, len22); } else { len22 = len2 / 2; advance(second_cut, len22); first_cut = upper_bound(first, middle, *second_cut); distance(first, first_cut, len11); } rotate(first_cut, middle, second_cut); BidirectionalIterator new_middle = first_cut; advance(new_middle, len22); __merge_without_buffer(first, first_cut, new_middle, len11, len22); __merge_without_buffer(new_middle, second_cut, last, len1 - len11, len2 - len22); } template 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)) 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; advance(first_cut, len11); second_cut = lower_bound(middle, last, *first_cut, comp); distance(middle, second_cut, len22); } else { len22 = len2 / 2; advance(second_cut, len22); first_cut = upper_bound(first, middle, *second_cut, comp); distance(first, first_cut, len11); } rotate(first_cut, middle, second_cut); BidirectionalIterator new_middle = first_cut; advance(new_middle, len22); __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp); __merge_without_buffer(new_middle, second_cut, last, len1 - len11, len2 - len22, comp); } template 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 = copy(middle, last, buffer); copy_backward(first, middle, last); return copy(buffer, buffer_end, first); } else if (len1 <= buffer_size) { buffer_end = copy(first, middle, buffer); copy(middle, last, first); return copy_backward(buffer, buffer_end, last); } else { rotate(first, middle, last); advance(first, len2); return first; } } template BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1, BidirectionalIterator1 last1, BidirectionalIterator2 first2, BidirectionalIterator2 last2, BidirectionalIterator3 result) { if (first1 == last1) return copy_backward(first2, last2, result); if (first2 == last2) return copy_backward(first1, last1, result); --last1; --last2; while (true) { if (*last2 < *last1) { *--result = *last1; if (first1 == last1) return copy_backward(first2, ++last2, result); --last1; } else { *--result = *last2; if (first2 == last2) return copy_backward(first1, ++last1, result); --last2; } } } template BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1, BidirectionalIterator1 last1, BidirectionalIterator2 first2, BidirectionalIterator2 last2, BidirectionalIterator3 result, Compare comp) { if (first1 == last1) return copy_backward(first2, last2, result); if (first2 == last2) return copy_backward(first1, last1, result); --last1; --last2; while (true) { if (comp(*last2, *last1)) { *--result = *last1; if (first1 == last1) return copy_backward(first2, ++last2, result); --last1; } else { *--result = *last2; if (first2 == last2) return copy_backward(first1, ++last1, result); --last2; } } } template 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 end_buffer = copy(first, middle, buffer); merge(buffer, end_buffer, middle, last, first); } else if (len2 <= buffer_size) { Pointer end_buffer = copy(middle, last, buffer); __merge_backward(first, middle, buffer, end_buffer, last); } else { BidirectionalIterator first_cut = first; BidirectionalIterator second_cut = middle; Distance len11 = 0; Distance len22 = 0; if (len1 > len2) { len11 = len1 / 2; advance(first_cut, len11); second_cut = lower_bound(middle, last, *first_cut); distance(middle, second_cut, len22); } else { len22 = len2 / 2; advance(second_cut, len22); first_cut = upper_bound(first, middle, *second_cut); distance(first, first_cut, len11); } BidirectionalIterator new_middle = __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, len22, buffer, buffer_size); __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, buffer_size); __merge_adaptive(new_middle, second_cut, last, len1 - len11, len2 - len22, buffer, buffer_size); } } template 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 end_buffer = copy(first, middle, buffer); merge(buffer, end_buffer, middle, last, first, comp); } else if (len2 <= buffer_size) { Pointer end_buffer = copy(middle, last, buffer); __merge_backward(first, middle, buffer, end_buffer, last, comp); } else { BidirectionalIterator first_cut = first; BidirectionalIterator second_cut = middle; Distance len11 = 0; Distance len22 = 0; if (len1 > len2) { len11 = len1 / 2; advance(first_cut, len11); second_cut = lower_bound(middle, last, *first_cut, comp); distance(middle, second_cut, len22); } else { len22 = len2 / 2; advance(second_cut, len22); first_cut = upper_bound(first, middle, *second_cut, comp); distance(first, first_cut, len11); } BidirectionalIterator new_middle = __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, len22, buffer, buffer_size); __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, buffer_size, comp); __merge_adaptive(new_middle, second_cut, last, len1 - len11, len2 - len22, buffer, buffer_size, comp); } } template inline void __inplace_merge_aux(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, T*, Distance*) { Distance len1 = 0; distance(first, middle, len1); Distance len2 = 0; distance(middle, last, len2); temporary_buffer buf(first, last); if (buf.begin() == 0) __merge_without_buffer(first, middle, last, len1, len2); else __merge_adaptive(first, middle, last, len1, len2, buf.begin(), Distance(buf.size())); } template inline void __inplace_merge_aux(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, T*, Distance*, Compare comp) { Distance len1 = 0; distance(first, middle, len1); Distance len2 = 0; distance(middle, last, len2); temporary_buffer buf(first, last); if (buf.begin() == 0) __merge_without_buffer(first, middle, last, len1, len2, comp); else __merge_adaptive(first, middle, last, len1, len2, buf.begin(), Distance(buf.size()), comp); } template inline void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last) { if (first == middle || middle == last) return; __inplace_merge_aux(first, middle, last, value_type(first), distance_type(first)); } template inline void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp) { if (first == middle || middle == last) return; __inplace_merge_aux(first, middle, last, value_type(first), distance_type(first), comp); } template bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) { while (first1 != last1 && first2 != last2) if (*first2 < *first1) return false; else if(*first1 < *first2) ++first1; else ++first1, ++first2; return first2 == last2; } template bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp) { while (first1 != last1 && first2 != last2) if (comp(*first2, *first1)) return false; else if(comp(*first1, *first2)) ++first1; else ++first1, ++first2; return first2 == last2; } template OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { 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 copy(first2, last2, copy(first1, last1, result)); } template OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare 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 copy(first2, last2, copy(first1, last1, result)); } template OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { while (first1 != last1 && first2 != last2) if (*first1 < *first2) ++first1; else if (*first2 < *first1) ++first2; else { *result = *first1; ++first1; ++first2; ++result; } return result; } template OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare 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; } template OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { while (first1 != last1 && first2 != last2) if (*first1 < *first2) { *result = *first1; ++first1; ++result; } else if (*first2 < *first1) ++first2; else { ++first1; ++first2; } return copy(first1, last1, result); } template OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp) { while (first1 != last1 && first2 != last2) if (comp(*first1, *first2)) { *result = *first1; ++first1; ++result; } else if (comp(*first2, *first1)) ++first2; else { ++first1; ++first2; } return copy(first1, last1, result); } template OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { while (first1 != last1 && first2 != last2) if (*first1 < *first2) { *result = *first1; ++first1; ++result; } else if (*first2 < *first1) { *result = *first2; ++first2; ++result; } else { ++first1; ++first2; } return copy(first2, last2, copy(first1, last1, result)); } template OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare 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 copy(first2, last2, copy(first1, last1, result)); } template ForwardIterator max_element(ForwardIterator first, ForwardIterator last) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (*result < *first) result = first; return result; } template ForwardIterator max_element(ForwardIterator first, ForwardIterator last, Compare comp) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (comp(*result, *first)) result = first; return result; } template ForwardIterator min_element(ForwardIterator first, ForwardIterator last) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (*first < *result) result = first; return result; } template ForwardIterator min_element(ForwardIterator first, ForwardIterator last, Compare comp) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (comp(*first, *result)) result = first; return result; } template bool next_permutation(BidirectionalIterator first, BidirectionalIterator 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)); iter_swap(i, j); reverse(ii, last); return true; } if (i == first) { reverse(first, last); return false; } } } template bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp) { 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)); iter_swap(i, j); reverse(ii, last); return true; } if (i == first) { reverse(first, last); return false; } } } template bool prev_permutation(BidirectionalIterator first, BidirectionalIterator 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)); iter_swap(i, j); reverse(ii, last); return true; } if (i == first) { reverse(first, last); return false; } } } template bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp) { 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)); iter_swap(i, j); reverse(ii, last); return true; } if (i == first) { reverse(first, last); return false; } } } template InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2) { for ( ; first1 != last1; ++first1) for (ForwardIterator iter = first2; iter != last2; ++iter) if (*first1 == *iter) return first1; return last1; } template InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate comp) { for ( ; first1 != last1; ++first1) for (ForwardIterator iter = first2; iter != last2; ++iter) if (comp(*first1, *iter)) return first1; return last1; } // Search [first2, last2) as a subsequence in [first1, last1). // find_end for forward iterators. template 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 = search(first1, last1, first2, last2); if (new_result == last1) return result; else { result = new_result; first1 = new_result; ++first1; } } } } template 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 = 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. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template BidirectionalIterator1 __find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, BidirectionalIterator2 first2, BidirectionalIterator2 last2, bidirectional_iterator_tag, bidirectional_iterator_tag) { typedef reverse_iterator reviter1; typedef reverse_iterator reviter2; reviter1 rlast1(first1); reviter2 rlast2(first2); reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2); if (rresult == rlast1) return last1; else { BidirectionalIterator1 result = rresult.base(); advance(result, -distance(first2, last2)); return result; } } template BidirectionalIterator1 __find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, BidirectionalIterator2 first2, BidirectionalIterator2 last2, bidirectional_iterator_tag, bidirectional_iterator_tag, BinaryPredicate comp) { typedef reverse_iterator reviter1; typedef reverse_iterator reviter2; reviter1 rlast1(first1); reviter2 rlast2(first2); reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2, comp); if (rresult == rlast1) return last1; else { BidirectionalIterator1 result = rresult.base(); advance(result, -distance(first2, last2)); return result; } } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // Dispatching functions. template inline ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef typename iterator_traits::iterator_category category1; typedef typename iterator_traits::iterator_category category2; return __find_end(first1, last1, first2, last2, category1(), category2()); #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ return __find_end(first1, last1, first2, last2, forward_iterator_tag(), forward_iterator_tag()); #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ } template inline ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate comp) { #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef typename iterator_traits::iterator_category category1; typedef typename iterator_traits::iterator_category category2; return __find_end(first1, last1, first2, last2, category1(), category2(), comp); #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ return __find_end(first1, last1, first2, last2, forward_iterator_tag(), forward_iterator_tag(), comp); #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ } template bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, Distance*) { const Distance n = last - first; 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 inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last) { return __is_heap(first, last, distance_type(first)); } template bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering comp, Distance*) { const Distance n = last - first; 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 inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering comp) { return __is_heap(first, last, comp, distance_type(first)); } template bool is_sorted(ForwardIterator first, ForwardIterator last) { if (first == last) return true; ForwardIterator next = first; for (++next; next != last; first = next, ++next) { if (*next < *first) return false; } return true; } template bool is_sorted(ForwardIterator first, ForwardIterator last, StrictWeakOrdering comp) { if (first == last) return true; ForwardIterator next = first; for (++next; next != last; first = next, ++next) { if (comp(*next, *first)) return false; } return true; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1209 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ALGO_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_algobase.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ALGOBASE_H #define __SGI_STL_INTERNAL_ALGOBASE_H #ifndef __STL_CONFIG_H #include #endif #ifndef __SGI_STL_INTERNAL_RELOPS #include #endif #ifndef __SGI_STL_INTERNAL_PAIR_H #include #endif #ifndef __TYPE_TRAITS_H_ #include #endif #include #include #include #include #include #include #ifndef __SGI_STL_INTERNAL_ITERATOR_H #include #endif __STL_BEGIN_NAMESPACE template inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) { T tmp = *a; *a = *b; *b = tmp; } template inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) { __iter_swap(a, b, value_type(a)); } template inline void swap(T& a, T& b) { T tmp = a; a = b; b = tmp; } #ifndef __BORLANDC__ #undef min #undef max template inline const T& min(const T& a, const T& b) { return b < a ? b : a; } template inline const T& max(const T& a, const T& b) { return a < b ? b : a; } #endif /* __BORLANDC__ */ template inline const T& min(const T& a, const T& b, Compare comp) { return comp(b, a) ? b : a; } template inline const T& max(const T& a, const T& b, Compare comp) { return comp(a, b) ? b : a; } template inline OutputIterator __copy(InputIterator first, InputIterator last, OutputIterator result, input_iterator_tag) { for ( ; first != last; ++result, ++first) *result = *first; return result; } template inline OutputIterator __copy_d(RandomAccessIterator first, RandomAccessIterator last, OutputIterator result, Distance*) { for (Distance n = last - first; n > 0; --n, ++result, ++first) *result = *first; return result; } template inline OutputIterator __copy(RandomAccessIterator first, RandomAccessIterator last, OutputIterator result, random_access_iterator_tag) { return __copy_d(first, last, result, distance_type(first)); } template struct __copy_dispatch { OutputIterator operator()(InputIterator first, InputIterator last, OutputIterator result) { return __copy(first, last, result, iterator_category(first)); } }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template inline T* __copy_t(const T* first, const T* last, T* result, __true_type) { memmove(result, first, sizeof(T) * (last - first)); return result + (last - first); } template inline T* __copy_t(const T* first, const T* last, T* result, __false_type) { return __copy_d(first, last, result, (ptrdiff_t*) 0); } template struct __copy_dispatch { T* operator()(T* first, T* last, T* result) { typedef typename __type_traits::has_trivial_assignment_operator t; return __copy_t(first, last, result, t()); } }; template struct __copy_dispatch { T* operator()(const T* first, const T* last, T* result) { typedef typename __type_traits::has_trivial_assignment_operator t; return __copy_t(first, last, result, t()); } }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) { return __copy_dispatch()(first, last, result); } inline char* copy(const char* first, const char* last, char* result) { memmove(result, first, last - first); return result + (last - first); } inline wchar_t* copy(const wchar_t* first, const wchar_t* last, wchar_t* result) { memmove(result, first, sizeof(wchar_t) * (last - first)); return result + (last - first); } template inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result) { while (first != last) *--result = *--last; return result; } template struct __copy_backward_dispatch { BidirectionalIterator2 operator()(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result) { return __copy_backward(first, last, result); } }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template inline T* __copy_backward_t(const T* first, const T* last, T* result, __true_type) { const ptrdiff_t N = last - first; memmove(result - N, first, sizeof(T) * N); return result - N; } template inline T* __copy_backward_t(const T* first, const T* last, T* result, __false_type) { return __copy_backward(first, last, result); } template struct __copy_backward_dispatch { T* operator()(T* first, T* last, T* result) { typedef typename __type_traits::has_trivial_assignment_operator t; return __copy_backward_t(first, last, result, t()); } }; template struct __copy_backward_dispatch { T* operator()(const T* first, const T* last, T* result) { typedef typename __type_traits::has_trivial_assignment_operator t; return __copy_backward_t(first, last, result, t()); } }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result) { return __copy_backward_dispatch()(first, last, result); } template pair __copy_n(InputIterator first, Size count, OutputIterator result, input_iterator_tag) { for ( ; count > 0; --count, ++first, ++result) *result = *first; return pair(first, result); } template inline pair __copy_n(RandomAccessIterator first, Size count, OutputIterator result, random_access_iterator_tag) { RandomAccessIterator last = first + count; return pair(last, copy(first, last, result)); } template inline pair copy_n(InputIterator first, Size count, OutputIterator result) { return __copy_n(first, count, result, iterator_category(first)); } template void fill(ForwardIterator first, ForwardIterator last, const T& value) { for ( ; first != last; ++first) *first = value; } template OutputIterator fill_n(OutputIterator first, Size n, const T& value) { for ( ; n > 0; --n, ++first) *first = value; return first; } template pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) { while (first1 != last1 && *first1 == *first2) { ++first1; ++first2; } return pair(first1, first2); } template pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate binary_pred) { while (first1 != last1 && binary_pred(*first1, *first2)) { ++first1; ++first2; } return pair(first1, first2); } template inline bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) { for ( ; first1 != last1; ++first1, ++first2) if (*first1 != *first2) return false; return true; } template inline bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate binary_pred) { for ( ; first1 != last1; ++first1, ++first2) if (!binary_pred(*first1, *first2)) return false; return true; } template bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) { for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) { if (*first1 < *first2) return true; if (*first2 < *first1) return false; } return first1 == last1 && first2 != last2; } template bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp) { 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) { const size_t len1 = last1 - first1; const size_t len2 = last2 - first2; const int result = memcmp(first1, first2, 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) { #if CHAR_MAX == SCHAR_MAX return lexicographical_compare((const signed char*) first1, (const signed char*) last1, (const signed char*) first2, (const signed char*) last2); #else return lexicographical_compare((const unsigned char*) first1, (const unsigned char*) last1, (const unsigned char*) first2, (const unsigned char*) last2); #endif } template 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 = 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 } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ALGOBASE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_alloc.h ================================================ /* * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ALLOC_H #define __SGI_STL_INTERNAL_ALLOC_H #ifdef __SUNPRO_CC # define __PRIVATE public // Extra access restrictions prevent us from really making some things // private. #else # define __PRIVATE private #endif #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG # define __USE_MALLOC #endif // This implements some standard node allocators. These are // NOT the same as the allocators in the C++ draft standard or in // in the original STL. They do not encapsulate different pointer // types; indeed we assume that there is only one pointer type. // The allocation primitives are intended to allocate individual objects, // not larger arenas as with the original STL allocators. #if 0 # include # define __THROW_BAD_ALLOC throw bad_alloc #elif !defined(__THROW_BAD_ALLOC) # include # define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1) #endif #ifndef __ALLOC # define __ALLOC alloc #endif #ifdef __STL_WIN32THREADS # include #endif #include #include #include #include #ifndef __RESTRICT # define __RESTRICT #endif #if !defined(__STL_PTHREADS) && !defined(_NOTHREADS) \ && !defined(__STL_SGI_THREADS) && !defined(__STL_WIN32THREADS) # define _NOTHREADS #endif # ifdef __STL_PTHREADS // POSIX Threads // This is dubious, since this is likely to be a high contention // lock. Performance may not be adequate. # include # define __NODE_ALLOCATOR_LOCK \ if (threads) pthread_mutex_lock(&__node_allocator_lock) # define __NODE_ALLOCATOR_UNLOCK \ if (threads) pthread_mutex_unlock(&__node_allocator_lock) # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // Needed at -O3 on SGI # endif # ifdef __STL_WIN32THREADS // The lock needs to be initialized by constructing an allocator // objects of the right type. We do that here explicitly for alloc. # define __NODE_ALLOCATOR_LOCK \ EnterCriticalSection(&__node_allocator_lock) # define __NODE_ALLOCATOR_UNLOCK \ LeaveCriticalSection(&__node_allocator_lock) # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // may not be needed # endif /* WIN32THREADS */ # ifdef __STL_SGI_THREADS // This should work without threads, with sproc threads, or with // pthreads. It is suboptimal in all cases. // It is unlikely to even compile on nonSGI machines. extern "C" { extern int __us_rsthread_malloc; } // The above is copied from malloc.h. Including // would be cleaner but fails with certain levels of standard // conformance. # define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \ { __lock(&__node_allocator_lock); } # define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \ { __unlock(&__node_allocator_lock); } # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // Needed at -O3 on SGI # endif # ifdef _NOTHREADS // Thread-unsafe # define __NODE_ALLOCATOR_LOCK # define __NODE_ALLOCATOR_UNLOCK # define __NODE_ALLOCATOR_THREADS false # define __VOLATILE # endif __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif // Malloc-based allocator. Typically slower than default alloc below. // Typically thread-safe and more storage efficient. #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG # ifdef __DECLARE_GLOBALS_HERE void (* __malloc_alloc_oom_handler)() = 0; // g++ 2.7.2 does not handle static template data members. # else extern void (* __malloc_alloc_oom_handler)(); # endif #endif template class __malloc_alloc_template { private: static void *oom_malloc(size_t); static void *oom_realloc(void *, size_t); #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG static void (* __malloc_alloc_oom_handler)(); #endif public: static void * allocate(size_t n) { void *result = malloc(n); if (0 == result) result = oom_malloc(n); return result; } static void deallocate(void *p, size_t /* n */) { free(p); } static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz) { void * result = realloc(p, new_sz); if (0 == result) result = oom_realloc(p, new_sz); return result; } static void (* set_malloc_handler(void (*f)()))() { void (* old)() = __malloc_alloc_oom_handler; __malloc_alloc_oom_handler = f; return(old); } }; // malloc_alloc out-of-memory handling #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG template void (* __malloc_alloc_template::__malloc_alloc_oom_handler)() = 0; #endif template void * __malloc_alloc_template::oom_malloc(size_t n) { void (* my_malloc_handler)(); void *result; for (;;) { my_malloc_handler = __malloc_alloc_oom_handler; if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } (*my_malloc_handler)(); result = malloc(n); if (result) return(result); } } template void * __malloc_alloc_template::oom_realloc(void *p, size_t n) { void (* my_malloc_handler)(); void *result; for (;;) { my_malloc_handler = __malloc_alloc_oom_handler; if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } (*my_malloc_handler)(); result = realloc(p, n); if (result) return(result); } } typedef __malloc_alloc_template<0> malloc_alloc; template class simple_alloc { public: static T *allocate(size_t n) { return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); } static T *allocate(void) { return (T*) Alloc::allocate(sizeof (T)); } static void deallocate(T *p, size_t n) { if (0 != n) Alloc::deallocate(p, n * sizeof (T)); } static void deallocate(T *p) { Alloc::deallocate(p, sizeof (T)); } }; // Allocator adaptor to check size arguments for debugging. // Reports errors using assert. Checking can be disabled with // NDEBUG, but it's far better to just use the underlying allocator // instead when no checking is desired. // There is some evidence that this can confuse Purify. template class debug_alloc { private: enum {extra = 8}; // Size of space used to store size. Note // that this must be large enough to preserve // alignment. public: static void * allocate(size_t n) { char *result = (char *)Alloc::allocate(n + extra); *(size_t *)result = n; return result + extra; } static void deallocate(void *p, size_t n) { char * real_p = (char *)p - extra; assert(*(size_t *)real_p == n); Alloc::deallocate(real_p, n + extra); } static void * reallocate(void *p, size_t old_sz, size_t new_sz) { char * real_p = (char *)p - extra; assert(*(size_t *)real_p == old_sz); char * result = (char *) Alloc::reallocate(real_p, old_sz + extra, new_sz + extra); *(size_t *)result = new_sz; return result + extra; } }; # ifdef __USE_MALLOC typedef malloc_alloc alloc; typedef malloc_alloc single_client_alloc; # else // Default node allocator. // With a reasonable compiler, this should be roughly as fast as the // original STL class-specific allocators, but with less fragmentation. // Default_alloc_template parameters are experimental and MAY // DISAPPEAR in the future. Clients should just use alloc for now. // // Important implementation properties: // 1. If the client request an object of size > __MAX_BYTES, the resulting // object will be obtained directly from malloc. // 2. In all other cases, we allocate an object of size exactly // 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. // // The first template parameter specifies whether more than one thread // may use this allocator. It is safe to allocate an object from // one instance of a default_alloc and deallocate it with another // one. This effectively transfers its ownership to the second one. // This may have undesirable effects on reference locality. // The second parameter is unreferenced and serves only to allow the // creation of multiple default_alloc instances. // Node that containers built on different allocator instances have // different types, limiting the utility of this approach. #ifdef __SUNPRO_CC // breaks if we make these template class members: enum {__ALIGN = 8}; enum {__MAX_BYTES = 128}; enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; #endif template class __default_alloc_template { private: // Really we should use static const int x = N // instead of enum { x = N }, but few compilers accept the former. # ifndef __SUNPRO_CC enum {__ALIGN = 8}; enum {__MAX_BYTES = 128}; enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; # endif static size_t ROUND_UP(size_t bytes) { return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1)); } __PRIVATE: union obj { union obj * free_list_link; char client_data[1]; /* The client sees this. */ }; private: # ifdef __SUNPRO_CC static obj * __VOLATILE free_list[]; // Specifying a size results in duplicate def for 4.1 # else static obj * __VOLATILE free_list[__NFREELISTS]; # endif static size_t FREELIST_INDEX(size_t bytes) { return (((bytes) + __ALIGN-1)/__ALIGN - 1); } // Returns an object of size n, and optionally adds to size n free list. static void *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. static char *chunk_alloc(size_t size, int &nobjs); // Chunk allocation state. static char *start_free; static char *end_free; static size_t heap_size; # ifdef __STL_SGI_THREADS static volatile unsigned long __node_allocator_lock; static void __lock(volatile unsigned long *); static inline void __unlock(volatile unsigned long *); # endif # ifdef __STL_PTHREADS static pthread_mutex_t __node_allocator_lock; # endif # ifdef __STL_WIN32THREADS static CRITICAL_SECTION __node_allocator_lock; static bool __node_allocator_lock_initialized; public: __default_alloc_template() { // This assumes the first constructor is called before threads // are started. if (!__node_allocator_lock_initialized) { InitializeCriticalSection(&__node_allocator_lock); __node_allocator_lock_initialized = true; } } private: # endif class lock { public: lock() { __NODE_ALLOCATOR_LOCK; } ~lock() { __NODE_ALLOCATOR_UNLOCK; } }; friend class lock; public: /* n must be > 0 */ static void * allocate(size_t n) { obj * __VOLATILE * my_free_list; obj * __RESTRICT result; if (n > (size_t) __MAX_BYTES) { return(malloc_alloc::allocate(n)); } my_free_list = free_list + FREELIST_INDEX(n); // Acquire the lock here with a constructor call. // This ensures that it is released in exit or during stack // unwinding. # ifndef _NOTHREADS /*REFERENCED*/ lock lock_instance; # endif result = *my_free_list; if (result == 0) { void *r = refill(ROUND_UP(n)); return r; } *my_free_list = result -> free_list_link; return (result); }; /* p may not be 0 */ static void deallocate(void *p, size_t n) { obj *q = (obj *)p; obj * __VOLATILE * my_free_list; if (n > (size_t) __MAX_BYTES) { malloc_alloc::deallocate(p, n); return; } my_free_list = free_list + FREELIST_INDEX(n); // acquire lock # ifndef _NOTHREADS /*REFERENCED*/ lock lock_instance; # endif /* _NOTHREADS */ q -> free_list_link = *my_free_list; *my_free_list = q; // lock is released here } static void * reallocate(void *p, size_t old_sz, size_t new_sz); } ; typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc; typedef __default_alloc_template single_client_alloc; /* We allocate memory in large chunks in order to avoid fragmenting */ /* the malloc heap too much. */ /* We assume that size is properly aligned. */ /* We hold the allocation lock. */ template char* __default_alloc_template::chunk_alloc(size_t size, int& nobjs) { char * result; size_t total_bytes = size * nobjs; size_t bytes_left = end_free - start_free; if (bytes_left >= total_bytes) { result = start_free; start_free += total_bytes; return(result); } else if (bytes_left >= size) { nobjs = bytes_left/size; total_bytes = size * nobjs; result = start_free; start_free += total_bytes; return(result); } else { size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); // Try to make use of the left-over piece. if (bytes_left > 0) { obj * __VOLATILE * my_free_list = free_list + FREELIST_INDEX(bytes_left); ((obj *)start_free) -> free_list_link = *my_free_list; *my_free_list = (obj *)start_free; } start_free = (char *)malloc(bytes_to_get); if (0 == start_free) { int i; obj * __VOLATILE * my_free_list, *p; // Try to make do with what we have. That can't // hurt. We do not try smaller requests, since that tends // to result in disaster on multi-process machines. for (i = size; i <= __MAX_BYTES; i += __ALIGN) { my_free_list = free_list + FREELIST_INDEX(i); p = *my_free_list; if (0 != p) { *my_free_list = p -> free_list_link; start_free = (char *)p; end_free = start_free + i; return(chunk_alloc(size, nobjs)); // Any leftover piece will eventually make it to the // right free list. } } end_free = 0; // In case of exception. start_free = (char *)malloc_alloc::allocate(bytes_to_get); // This should either throw an // exception or remedy the situation. Thus we assume it // succeeded. } heap_size += bytes_to_get; end_free = start_free + bytes_to_get; return(chunk_alloc(size, nobjs)); } } /* Returns an object of size n, and optionally adds to size n free list.*/ /* We assume that n is properly aligned. */ /* We hold the allocation lock. */ template void* __default_alloc_template::refill(size_t n) { int nobjs = 20; char * chunk = chunk_alloc(n, nobjs); obj * __VOLATILE * my_free_list; obj * result; obj * current_obj, * next_obj; int i; if (1 == nobjs) return(chunk); my_free_list = free_list + FREELIST_INDEX(n); /* Build free list in chunk */ result = (obj *)chunk; *my_free_list = next_obj = (obj *)(chunk + n); for (i = 1; ; i++) { current_obj = next_obj; next_obj = (obj *)((char *)next_obj + n); if (nobjs - 1 == i) { current_obj -> free_list_link = 0; break; } else { current_obj -> free_list_link = next_obj; } } return(result); } template void* __default_alloc_template::reallocate(void *p, size_t old_sz, size_t new_sz) { void * result; size_t copy_sz; if (old_sz > (size_t) __MAX_BYTES && new_sz > (size_t) __MAX_BYTES) { return(realloc(p, new_sz)); } if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p); result = allocate(new_sz); copy_sz = new_sz > old_sz? old_sz : new_sz; memcpy(result, p, copy_sz); deallocate(p, old_sz); return(result); } #ifdef __STL_PTHREADS template pthread_mutex_t __default_alloc_template::__node_allocator_lock = PTHREAD_MUTEX_INITIALIZER; #endif #ifdef __STL_WIN32THREADS template CRITICAL_SECTION __default_alloc_template::__node_allocator_lock; template bool __default_alloc_template::__node_allocator_lock_initialized = false; #endif #ifdef __STL_SGI_THREADS __STL_END_NAMESPACE #include #include __STL_BEGIN_NAMESPACE // Somewhat generic lock implementations. We need only test-and-set // and some way to sleep. These should work with both SGI pthreads // and sproc threads. They may be useful on other systems. template volatile unsigned long __default_alloc_template::__node_allocator_lock = 0; #if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) || defined(__GNUC__) # define __test_and_set(l,v) test_and_set(l,v) #endif template void __default_alloc_template::__lock(volatile unsigned long *lock) { const unsigned low_spin_max = 30; // spin cycles if we suspect uniprocessor const unsigned high_spin_max = 1000; // spin cycles for multiprocessor static unsigned spin_max = low_spin_max; unsigned my_spin_max; static unsigned last_spins = 0; unsigned my_last_spins; static struct timespec ts = {0, 1000}; unsigned junk; # define __ALLOC_PAUSE junk *= junk; junk *= junk; junk *= junk; junk *= junk int i; if (!__test_and_set((unsigned long *)lock, 1)) { return; } my_spin_max = spin_max; my_last_spins = last_spins; for (i = 0; i < my_spin_max; i++) { if (i < my_last_spins/2 || *lock) { __ALLOC_PAUSE; continue; } if (!__test_and_set((unsigned long *)lock, 1)) { // got it! // Spinning worked. Thus we're probably not being scheduled // against the other process with which we were contending. // Thus it makes sense to spin longer the next time. last_spins = i; spin_max = high_spin_max; return; } } // We are probably being scheduled against the other process. Sleep. spin_max = low_spin_max; for (;;) { if (!__test_and_set((unsigned long *)lock, 1)) { return; } nanosleep(&ts, 0); } } template inline void __default_alloc_template::__unlock(volatile unsigned long *lock) { # if defined(__GNUC__) && __mips >= 3 asm("sync"); *lock = 0; # elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) __lock_release(lock); # else *lock = 0; // This is not sufficient on many multiprocessors, since // writes to protected variables and the lock may be reordered. # endif } #endif template char *__default_alloc_template::start_free = 0; template char *__default_alloc_template::end_free = 0; template size_t __default_alloc_template::heap_size = 0; template __default_alloc_template::obj * __VOLATILE __default_alloc_template ::free_list[ # ifdef __SUNPRO_CC __NFREELISTS # else __default_alloc_template::__NFREELISTS # endif ] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; // The 16 zeros are necessary to make version 4.1 of the SunPro // compiler happy. Otherwise it appears to allocate too little // space for the array. # ifdef __STL_WIN32THREADS // Create one to get critical section initialized. // We do this onece per file, but only the first constructor // does anything. static alloc __node_allocator_dummy_instance; # endif #endif /* ! __USE_MALLOC */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #undef __PRIVATE #endif /* __SGI_STL_INTERNAL_ALLOC_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_bvector.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_BVECTOR_H #define __SGI_STL_INTERNAL_BVECTOR_H __STL_BEGIN_NAMESPACE static const int __WORD_BIT = int(CHAR_BIT*sizeof(unsigned int)); #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif struct __bit_reference { unsigned int* p; unsigned int mask; __bit_reference(unsigned int* x, unsigned int y) : p(x), mask(y) {} public: __bit_reference() : p(0), mask(0) {} operator bool() const { return !(!(*p & mask)); } __bit_reference& operator=(bool x) { if (x) *p |= mask; else *p &= ~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() { *p ^= mask; } }; inline void swap(__bit_reference x, __bit_reference y) { bool tmp = x; x = y; y = tmp; } struct __bit_iterator : public random_access_iterator { typedef __bit_reference reference; typedef __bit_reference* pointer; typedef __bit_iterator iterator; unsigned int* p; unsigned int offset; void bump_up() { if (offset++ == __WORD_BIT - 1) { offset = 0; ++p; } } void bump_down() { if (offset-- == 0) { offset = __WORD_BIT - 1; --p; } } __bit_iterator() : p(0), offset(0) {} __bit_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {} reference operator*() const { return reference(p, 1U << offset); } iterator& operator++() { bump_up(); return *this; } iterator operator++(int) { iterator tmp = *this; bump_up(); return tmp; } iterator& operator--() { bump_down(); return *this; } iterator operator--(int) { iterator tmp = *this; bump_down(); return tmp; } iterator& operator+=(difference_type i) { difference_type n = i + offset; p += n / __WORD_BIT; n = n % __WORD_BIT; if (n < 0) { offset = (unsigned int) n + __WORD_BIT; --p; } else offset = (unsigned int) n; 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; } difference_type operator-(iterator x) const { return __WORD_BIT * (p - x.p) + offset - x.offset; } reference operator[](difference_type i) { return *(*this + i); } bool operator==(const iterator& x) const { return p == x.p && offset == x.offset; } bool operator!=(const iterator& x) const { return p != x.p || offset != x.offset; } bool operator<(iterator x) const { return p < x.p || (p == x.p && offset < x.offset); } }; struct __bit_const_iterator : public random_access_iterator { typedef bool reference; typedef bool const_reference; typedef const bool* pointer; typedef __bit_const_iterator const_iterator; unsigned int* p; unsigned int offset; void bump_up() { if (offset++ == __WORD_BIT - 1) { offset = 0; ++p; } } void bump_down() { if (offset-- == 0) { offset = __WORD_BIT - 1; --p; } } __bit_const_iterator() : p(0), offset(0) {} __bit_const_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {} __bit_const_iterator(const __bit_iterator& x) : p(x.p), offset(x.offset) {} const_reference operator*() const { return __bit_reference(p, 1U << offset); } const_iterator& operator++() { bump_up(); return *this; } const_iterator operator++(int) { const_iterator tmp = *this; bump_up(); return tmp; } const_iterator& operator--() { bump_down(); return *this; } const_iterator operator--(int) { const_iterator tmp = *this; bump_down(); return tmp; } const_iterator& operator+=(difference_type i) { difference_type n = i + offset; p += n / __WORD_BIT; n = n % __WORD_BIT; if (n < 0) { offset = (unsigned int) n + __WORD_BIT; --p; } else offset = (unsigned int) n; 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; } difference_type operator-(const_iterator x) const { return __WORD_BIT * (p - x.p) + offset - x.offset; } const_reference operator[](difference_type i) { return *(*this + i); } bool operator==(const const_iterator& x) const { return p == x.p && offset == x.offset; } bool operator!=(const const_iterator& x) const { return p != x.p || offset != x.offset; } bool operator<(const_iterator x) const { return p < x.p || (p == x.p && offset < x.offset); } }; // The next few lines are confusing. What we're doing is declaring a // partial specialization of vector if we have the necessary // compiler support. Otherwise, we define a class bit_vector which uses // the default allocator. In either case, we typedef "data_allocator" // appropriately. #if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NEED_BOOL) #define __SGI_STL_VECBOOL_TEMPLATE #define __BVECTOR vector #else #undef __SGI_STL_VECBOOL_TEMPLATE #define __BVECTOR bit_vector #endif # ifdef __SGI_STL_VECBOOL_TEMPLATE __STL_END_NAMESPACE # include __STL_BEGIN_NAMESPACE template class vector # else /* __SGI_STL_VECBOOL_TEMPLATE */ class bit_vector # endif /* __SGI_STL_VECBOOL_TEMPLATE */ { # ifdef __SGI_STL_VECBOOL_TEMPLATE typedef simple_alloc data_allocator; # else /* __SGI_STL_VECBOOL_TEMPLATE */ typedef simple_alloc data_allocator; # endif /* __SGI_STL_VECBOOL_TEMPLATE */ 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; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: iterator start; iterator finish; unsigned int* end_of_storage; unsigned int* bit_alloc(size_type n) { return data_allocator::allocate((n + __WORD_BIT - 1)/__WORD_BIT); } void deallocate() { if (start.p) data_allocator::deallocate(start.p, end_of_storage - start.p); } void initialize(size_type n) { unsigned int* q = bit_alloc(n); end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT; start = iterator(q, 0); finish = start + difference_type(n); } void insert_aux(iterator position, bool x) { if (finish.p != end_of_storage) { copy_backward(position, finish, finish + 1); *position = x; ++finish; } else { size_type len = size() ? 2 * size() : __WORD_BIT; unsigned int* q = bit_alloc(len); iterator i = copy(begin(), position, iterator(q, 0)); *i++ = x; finish = copy(position, end(), i); deallocate(); end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; start = iterator(q, 0); } } #ifdef __STL_MEMBER_TEMPLATES template void initialize_range(InputIterator first, InputIterator last, input_iterator_tag) { start = iterator(); finish = iterator(); end_of_storage = 0; for ( ; first != last; ++first) push_back(*first); } template void initialize_range(ForwardIterator first, ForwardIterator last, forward_iterator_tag) { size_type n = 0; distance(first, last, n); initialize(n); copy(first, last, start); } template void insert_range(iterator pos, InputIterator first, InputIterator last, input_iterator_tag) { for ( ; first != last; ++first) { pos = insert(pos, *first); ++pos; } } template void insert_range(iterator position, ForwardIterator first, ForwardIterator last, forward_iterator_tag) { if (first != last) { size_type n = 0; distance(first, last, n); if (capacity() - size() >= n) { copy_backward(position, end(), finish + difference_type(n)); copy(first, last, position); finish += difference_type(n); } else { size_type len = size() + max(size(), n); unsigned int* q = bit_alloc(len); iterator i = copy(begin(), position, iterator(q, 0)); i = copy(first, last, i); finish = copy(position, end(), i); deallocate(); end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; start = iterator(q, 0); } } } #endif /* __STL_MEMBER_TEMPLATES */ public: iterator begin() { return start; } const_iterator begin() const { return start; } iterator end() { return finish; } const_iterator end() const { return 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 { return size_type(-1); } size_type capacity() const { return size_type(const_iterator(end_of_storage, 0) - begin()); } bool empty() const { return begin() == end(); } reference operator[](size_type n) { return *(begin() + difference_type(n)); } const_reference operator[](size_type n) const { return *(begin() + difference_type(n)); } __BVECTOR() : start(iterator()), finish(iterator()), end_of_storage(0) {} __BVECTOR(size_type n, bool value) { initialize(n); fill(start.p, end_of_storage, value ? ~0 : 0); } __BVECTOR(int n, bool value) { initialize(n); fill(start.p, end_of_storage, value ? ~0 : 0); } __BVECTOR(long n, bool value) { initialize(n); fill(start.p, end_of_storage, value ? ~0 : 0); } explicit __BVECTOR(size_type n) { initialize(n); fill(start.p, end_of_storage, 0); } __BVECTOR(const __BVECTOR& x) { initialize(x.size()); copy(x.begin(), x.end(), start); } #ifdef __STL_MEMBER_TEMPLATES template __BVECTOR(InputIterator first, InputIterator last) { initialize_range(first, last, iterator_category(first)); } #else /* __STL_MEMBER_TEMPLATES */ __BVECTOR(const_iterator first, const_iterator last) { size_type n = 0; distance(first, last, n); initialize(n); copy(first, last, start); } __BVECTOR(const bool* first, const bool* last) { size_type n = 0; distance(first, last, n); initialize(n); copy(first, last, start); } #endif /* __STL_MEMBER_TEMPLATES */ ~__BVECTOR() { deallocate(); } __BVECTOR& operator=(const __BVECTOR& x) { if (&x == this) return *this; if (x.size() > capacity()) { deallocate(); initialize(x.size()); } copy(x.begin(), x.end(), begin()); finish = begin() + difference_type(x.size()); return *this; } void reserve(size_type n) { if (capacity() < n) { unsigned int* q = bit_alloc(n); finish = copy(begin(), end(), iterator(q, 0)); deallocate(); start = iterator(q, 0); end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT; } } reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(end() - 1); } const_reference back() const { return *(end() - 1); } void push_back(bool x) { if (finish.p != end_of_storage) *finish++ = x; else insert_aux(end(), x); } void swap(__BVECTOR& x) { __STD::swap(start, x.start); __STD::swap(finish, x.finish); __STD::swap(end_of_storage, x.end_of_storage); } iterator insert(iterator position, bool x = bool()) { difference_type n = position - begin(); if (finish.p != end_of_storage && position == end()) *finish++ = x; else insert_aux(position, x); return begin() + n; } #ifdef __STL_MEMBER_TEMPLATES template void insert(iterator position, InputIterator first, InputIterator last) { insert_range(position, first, last, iterator_category(first)); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator position, const_iterator first, const_iterator last) { if (first == last) return; size_type n = 0; distance(first, last, n); if (capacity() - size() >= n) { copy_backward(position, end(), finish + n); copy(first, last, position); finish += n; } else { size_type len = size() + max(size(), n); unsigned int* q = bit_alloc(len); iterator i = copy(begin(), position, iterator(q, 0)); i = copy(first, last, i); finish = copy(position, end(), i); deallocate(); end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; start = iterator(q, 0); } } void insert(iterator position, const bool* first, const bool* last) { if (first == last) return; size_type n = 0; distance(first, last, n); if (capacity() - size() >= n) { copy_backward(position, end(), finish + n); copy(first, last, position); finish += n; } else { size_type len = size() + max(size(), n); unsigned int* q = bit_alloc(len); iterator i = copy(begin(), position, iterator(q, 0)); i = copy(first, last, i); finish = copy(position, end(), i); deallocate(); end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; start = iterator(q, 0); } } #endif /* __STL_MEMBER_TEMPLATES */ void insert(iterator position, size_type n, bool x) { if (n == 0) return; if (capacity() - size() >= n) { copy_backward(position, end(), finish + difference_type(n)); fill(position, position + difference_type(n), x); finish += difference_type(n); } else { size_type len = size() + max(size(), n); unsigned int* q = bit_alloc(len); iterator i = copy(begin(), position, iterator(q, 0)); fill_n(i, n, x); finish = copy(position, end(), i + difference_type(n)); deallocate(); end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; start = iterator(q, 0); } } void insert(iterator pos, int n, bool x) { insert(pos, (size_type)n, x); } void insert(iterator pos, long n, bool x) { insert(pos, (size_type)n, x); } void pop_back() { --finish; } iterator erase(iterator position) { if (position + 1 != end()) copy(position + 1, end(), position); --finish; return position; } iterator erase(iterator first, iterator last) { finish = copy(last, end(), first); return first; } void resize(size_type new_size, bool x = bool()) { if (new_size < size()) erase(begin() + difference_type(new_size), end()); else insert(end(), new_size - size(), x); } void clear() { erase(begin(), end()); } }; #ifdef __SGI_STL_VECBOOL_TEMPLATE typedef vector bit_vector; #else /* __SGI_STL_VECBOOL_TEMPLATE */ inline bool operator==(const bit_vector& x, const bit_vector& y) { return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); } inline bool operator<(const bit_vector& x, const bit_vector& y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #endif /* __SGI_STL_VECBOOL_TEMPLATE */ #undef __SGI_STL_VECBOOL_TEMPLATE #undef __BVECTOR #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_BVECTOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_config.h ================================================ /* * * 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 * * 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 __STL_CONFIG_H # define __STL_CONFIG_H // What this file does. // (1) Defines bool, true, and false if the compiler doesn't do so already. // (2) Defines __STL_NO_DRAND48 if the compiler's standard library does // not support the drand48() function. // (3) Defines __STL_STATIC_TEMPLATE_MEMBER_BUG if the compiler can't // handle static members of template classes. // (4) Defines 'typename' as a null macro if the compiler does not support // the typename keyword. // (5) Defines __STL_CLASS_PARTIAL_SPECIALIZATION if the compiler // supports partial specialization of class templates. // (6) Defines __STL_FUNCTION_TMPL_PARTIAL_ORDER if the compiler supports // partial ordering of function templates (a.k.a partial specialization // of function templates. // (7) Defines __STL_EXPLICIT_FUNCTION_TMPL_ARGS if the compiler // supports calling a function template by providing its template // arguments explicitly. // (8) Defines __STL_MEMBER_TEMPLATES if the compiler supports // template members of classes. // (9) Defines 'explicit' as a null macro if the compiler does not support // the explicit keyword. // (10) Defines __STL_LIMITED_DEFAULT_TEMPLATES if the compiler is // unable to handle default template parameters that depend on // previous template parameters. // (11) Defines __STL_NON_TYPE_TMPL_PARAM_BUG if the compiler has // trouble performing function template argument deduction for // non-type template parameters. // (12) Defines __SGI_STL_NO_ARROW_OPERATOR if the compiler is unable // to support the -> operator for iterators. // (13) Defines __STL_USE_EXCEPTIONS if the compiler (in the current // compilation mode) supports exceptions. // (14) Define __STL_USE_NAMESPACES if we're putting the STL into a // namespace. // (15) Defines __STL_SGI_THREADS if this is being compiled on an SGI // compiler, and if the user hasn't selected pthreads or no threads // instead. // (16) Defines __STL_WIN32THREADS if this is being compiled on a // WIN32 compiler in multithreaded mode. // (17) Define namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) // apropriately. // (18) Define exception-related macros (__STL_TRY, __STL_UNWIND, etc.) // appropriately. // (19) Defines __stl_assert either as a test or as a null macro, // depending on whether or not __STL_ASSERTIONS is defined. #ifdef _PTHREADS # define __STL_PTHREADS #endif # if defined(__sgi) && !defined(__GNUC__) # if !defined(_BOOL) # define __STL_NEED_BOOL # endif # if !defined(_TYPENAME_IS_KEYWORD) # define __STL_NEED_TYPENAME # endif # ifdef _PARTIAL_SPECIALIZATION_OF_CLASS_TEMPLATES # define __STL_CLASS_PARTIAL_SPECIALIZATION # endif # ifdef _MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATES # endif # if !defined(_EXPLICIT_IS_KEYWORD) # define __STL_NEED_EXPLICIT # endif # ifdef __EXCEPTIONS # define __STL_USE_EXCEPTIONS # endif # if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES) # define __STL_USE_NAMESPACES # endif # if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) # define __STL_SGI_THREADS # endif # endif # ifdef __GNUC__ # include <_G_config.h> # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) # define __STL_STATIC_TEMPLATE_MEMBER_BUG # define __STL_NEED_TYPENAME # define __STL_NEED_EXPLICIT # else # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_MEMBER_TEMPLATES # endif /* glibc pre 2.0 is very buggy. We have to disable thread for it. It should be upgraded to glibc 2.0 or later. */ # if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS) # define __STL_PTHREADS # endif # ifdef __EXCEPTIONS # define __STL_USE_EXCEPTIONS # endif # endif # if defined(__SUNPRO_CC) # define __STL_NEED_BOOL # define __STL_NEED_TYPENAME # define __STL_NEED_EXPLICIT # define __STL_USE_EXCEPTIONS # endif # if defined(__COMO__) # define __STL_MEMBER_TEMPLATES # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_USE_EXCEPTIONS # define __STL_USE_NAMESPACES # endif # if defined(_MSC_VER) # if _MSC_VER > 1000 # include # else # define __STL_NEED_BOOL # endif # define __STL_NO_DRAND48 # define __STL_NEED_TYPENAME # if _MSC_VER < 1100 # define __STL_NEED_EXPLICIT # endif # define __STL_NON_TYPE_TMPL_PARAM_BUG # define __SGI_STL_NO_ARROW_OPERATOR # ifdef _CPPUNWIND # define __STL_USE_EXCEPTIONS # endif # ifdef _MT # define __STL_WIN32THREADS # endif # endif # if defined(__BORLANDC__) # define __STL_NO_DRAND48 # define __STL_NEED_TYPENAME # define __STL_LIMITED_DEFAULT_TEMPLATES # define __SGI_STL_NO_ARROW_OPERATOR # define __STL_NON_TYPE_TMPL_PARAM_BUG # ifdef _CPPUNWIND # define __STL_USE_EXCEPTIONS # endif # ifdef __MT__ # define __STL_WIN32THREADS # endif # endif # if defined(__STL_NEED_BOOL) typedef int bool; # define true 1 # define false 0 # endif # ifdef __STL_NEED_TYPENAME # define typename # endif # ifdef __STL_NEED_EXPLICIT # define explicit # endif # ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_NULL_TMPL_ARGS <> # else # define __STL_NULL_TMPL_ARGS # endif # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_TEMPLATE_NULL template<> # else # define __STL_TEMPLATE_NULL # endif // __STL_NO_NAMESPACES is a hook so that users can disable namespaces // without having to edit library headers. # if defined(__STL_USE_NAMESPACES) && !defined(__STL_NO_NAMESPACES) # define __STD std # define __STL_BEGIN_NAMESPACE namespace std { # define __STL_END_NAMESPACE } # define __STL_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE namespace std { # define __STL_END_RELOPS_NAMESPACE } # define __STD_RELOPS std # else # define __STD # define __STL_BEGIN_NAMESPACE # define __STL_END_NAMESPACE # undef __STL_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE # define __STL_END_RELOPS_NAMESPACE # define __STD_RELOPS # endif # ifdef __STL_USE_EXCEPTIONS # define __STL_TRY try # define __STL_CATCH_ALL catch(...) # define __STL_RETHROW throw # define __STL_NOTHROW throw() # define __STL_UNWIND(action) catch(...) { action; throw; } # else # define __STL_TRY # define __STL_CATCH_ALL if (false) # define __STL_RETHROW # define __STL_NOTHROW # define __STL_UNWIND(action) # endif #ifdef __STL_ASSERTIONS # include # define __stl_assert(expr) \ if (!(expr)) { fprintf(stderr, "%s:%d STL assertion failure: %s\n", \ __FILE__, __LINE__, # expr); abort(); } #else # define __stl_assert(expr) #endif #endif /* __STL_CONFIG_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_construct.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_CONSTRUCT_H #define __SGI_STL_INTERNAL_CONSTRUCT_H #include __STL_BEGIN_NAMESPACE template inline void destroy(T* pointer) { pointer->~T(); } template inline void construct(T1* p, const T2& value) { new (p) T1(value); } template inline void __destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) { for ( ; first < last; ++first) destroy(&*first); } template inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {} template inline void __destroy(ForwardIterator first, ForwardIterator last, T*) { typedef typename __type_traits::has_trivial_destructor trivial_destructor; __destroy_aux(first, last, trivial_destructor()); } template inline void destroy(ForwardIterator first, ForwardIterator last) { __destroy(first, last, value_type(first)); } inline void destroy(char*, char*) {} inline void destroy(wchar_t*, wchar_t*) {} __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_CONSTRUCT_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_deque.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_DEQUE_H #define __SGI_STL_INTERNAL_DEQUE_H /* Class invariants: * For any nonsingular iterator i: * i.node is the address of an element in the map array. The * contents of i.node is a pointer to the beginning of a node. * i.first == *(i.node) * 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, and that a deque * with N elements, where N is the buffer size, must have two nodes. * 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]. */ /* * In previous versions of deque, node_size was fixed by the * implementation. In this version, however, users can select * the node size. Deque has three template parameters; the third, * a number of type size_t, is the number of elements per node. * If the third template parameter is 0 (which is the default), * then deque will use a default node size. * * The only reason for using an alternate node size is if your application * requires a different performance tradeoff than the default. If, * for example, your program contains many deques each of which contains * only a few elements, then you might want to save memory (possibly * by sacrificing some speed) by using smaller nodes. * * Unfortunately, some compilers have trouble with non-type template * parameters; stl_config.h defines __STL_NON_TYPE_TMPL_PARAM_BUG if * that is the case. If your compiler is one of them, then you will * not be able to use alternate node sizes; you will have to use the * default value. */ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif // Note: this function is simply a kludge to work around several compilers' // bugs in handling constant expressions. inline size_t __deque_buf_size(size_t n, size_t sz) { return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1)); } #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG template struct __deque_iterator { typedef __deque_iterator iterator; typedef __deque_iterator const_iterator; static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); } #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ template struct __deque_iterator { typedef __deque_iterator iterator; typedef __deque_iterator const_iterator; static size_t buffer_size() {return __deque_buf_size(0, sizeof(T)); } #endif typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef Ptr pointer; typedef Ref reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T** map_pointer; typedef __deque_iterator self; T* cur; T* first; T* last; map_pointer node; __deque_iterator(T* x, map_pointer y) : cur(x), first(*y), last(*y + buffer_size()), node(y) {} __deque_iterator() : cur(0), first(0), last(0), node(0) {} __deque_iterator(const iterator& x) : cur(x.cur), first(x.first), last(x.last), node(x.node) {} reference operator*() const { return *cur; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ difference_type operator-(const self& x) const { return difference_type(buffer_size()) * (node - x.node - 1) + (cur - first) + (x.last - x.cur); } self& operator++() { ++cur; if (cur == last) { set_node(node + 1); cur = first; } return *this; } self operator++(int) { self tmp = *this; ++*this; return tmp; } self& operator--() { if (cur == first) { set_node(node - 1); cur = last; } --cur; return *this; } self operator--(int) { self tmp = *this; --*this; return tmp; } self& operator+=(difference_type n) { difference_type offset = n + (cur - first); if (offset >= 0 && offset < difference_type(buffer_size())) cur += n; else { difference_type node_offset = offset > 0 ? offset / difference_type(buffer_size()) : -difference_type((-offset - 1) / buffer_size()) - 1; set_node(node + node_offset); cur = first + (offset - node_offset * difference_type(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); } bool operator==(const self& x) const { return cur == x.cur; } bool operator!=(const self& x) const { return !(*this == x); } bool operator<(const self& x) const { return (node == x.node) ? (cur < x.cur) : (node < x.node); } void set_node(map_pointer new_node) { node = new_node; first = *new_node; last = first + difference_type(buffer_size()); } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG template inline random_access_iterator_tag iterator_category(const __deque_iterator&) { return random_access_iterator_tag(); } template inline T* value_type(const __deque_iterator&) { return 0; } template inline ptrdiff_t* distance_type(const __deque_iterator&) { return 0; } #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ template inline random_access_iterator_tag iterator_category(const __deque_iterator&) { return random_access_iterator_tag(); } template inline T* value_type(const __deque_iterator&) { return 0; } template inline ptrdiff_t* distance_type(const __deque_iterator&) { return 0; } #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // See __deque_buf_size(). The only reason that the default value is 0 // is as a workaround for bugs in the way that some compilers handle // constant expressions. template class deque { public: // Basic types typedef T 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; public: // Iterators #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG typedef __deque_iterator iterator; typedef __deque_iterator const_iterator; #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ typedef __deque_iterator iterator; typedef __deque_iterator const_iterator; #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: // Internal typedefs typedef pointer* map_pointer; typedef simple_alloc data_allocator; typedef simple_alloc map_allocator; static size_type buffer_size() { return __deque_buf_size(BufSiz, sizeof(value_type)); } static size_type initial_map_size() { return 8; } protected: // Data members iterator start; iterator finish; map_pointer map; size_type map_size; public: // Basic accessors iterator begin() { return start; } iterator end() { return finish; } const_iterator begin() const { return start; } const_iterator end() const { return finish; } reverse_iterator rbegin() { return reverse_iterator(finish); } reverse_iterator rend() { return reverse_iterator(start); } const_reverse_iterator rbegin() const { return const_reverse_iterator(finish); } const_reverse_iterator rend() const { return const_reverse_iterator(start); } reference operator[](size_type n) { return start[difference_type(n)]; } const_reference operator[](size_type n) const { return start[difference_type(n)]; } reference front() { return *start; } reference back() { iterator tmp = finish; --tmp; return *tmp; } const_reference front() const { return *start; } const_reference back() const { const_iterator tmp = finish; --tmp; return *tmp; } size_type size() const { return finish - start;; } size_type max_size() const { return size_type(-1); } bool empty() const { return finish == start; } public: // Constructor, destructor. deque() : start(), finish(), map(0), map_size(0) { create_map_and_nodes(0); } deque(const deque& x) : start(), finish(), map(0), map_size(0) { create_map_and_nodes(x.size()); __STL_TRY { uninitialized_copy(x.begin(), x.end(), start); } __STL_UNWIND(destroy_map_and_nodes()); } deque(size_type n, const value_type& value) : start(), finish(), map(0), map_size(0) { fill_initialize(n, value); } deque(int n, const value_type& value) : start(), finish(), map(0), map_size(0) { fill_initialize(n, value); } deque(long n, const value_type& value) : start(), finish(), map(0), map_size(0) { fill_initialize(n, value); } explicit deque(size_type n) : start(), finish(), map(0), map_size(0) { fill_initialize(n, value_type()); } #ifdef __STL_MEMBER_TEMPLATES template deque(InputIterator first, InputIterator last) : start(), finish(), map(0), map_size(0) { range_initialize(first, last, iterator_category(first)); } #else /* __STL_MEMBER_TEMPLATES */ deque(const value_type* first, const value_type* last) : start(), finish(), map(0), map_size(0) { create_map_and_nodes(last - first); __STL_TRY { uninitialized_copy(first, last, start); } __STL_UNWIND(destroy_map_and_nodes()); } deque(const_iterator first, const_iterator last) : start(), finish(), map(0), map_size(0) { create_map_and_nodes(last - first); __STL_TRY { uninitialized_copy(first, last, start); } __STL_UNWIND(destroy_map_and_nodes()); } #endif /* __STL_MEMBER_TEMPLATES */ ~deque() { destroy(start, finish); destroy_map_and_nodes(); } deque& operator= (const deque& x) { const size_type len = size(); if (&x != this) { if (len >= x.size()) erase(copy(x.begin(), x.end(), start), finish); else { const_iterator mid = x.begin() + difference_type(len); copy(x.begin(), mid, start); insert(finish, mid, x.end()); } } return *this; } void swap(deque& x) { __STD::swap(start, x.start); __STD::swap(finish, x.finish); __STD::swap(map, x.map); __STD::swap(map_size, x.map_size); } public: // push_* and pop_* void push_back(const value_type& t) { if (finish.cur != finish.last - 1) { construct(finish.cur, t); ++finish.cur; } else push_back_aux(t); } void push_front(const value_type& t) { if (start.cur != start.first) { construct(start.cur - 1, t); --start.cur; } else push_front_aux(t); } void pop_back() { if (finish.cur != finish.first) { --finish.cur; destroy(finish.cur); } else pop_back_aux(); } void pop_front() { if (start.cur != start.last - 1) { destroy(start.cur); ++start.cur; } else pop_front_aux(); } public: // Insert iterator insert(iterator position, const value_type& x) { if (position.cur == start.cur) { push_front(x); return start; } else if (position.cur == finish.cur) { push_back(x); iterator tmp = finish; --tmp; return tmp; } else { return insert_aux(position, x); } } iterator insert(iterator position) { return insert(position, value_type()); } void insert(iterator pos, size_type n, const value_type& x); void insert(iterator pos, int n, const value_type& x) { insert(pos, (size_type) n, x); } void insert(iterator pos, long n, const value_type& x) { insert(pos, (size_type) n, x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(iterator pos, InputIterator first, InputIterator last) { insert(pos, first, last, iterator_category(first)); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator pos, const value_type* first, const value_type* last); void insert(iterator pos, const_iterator first, const_iterator last); #endif /* __STL_MEMBER_TEMPLATES */ void resize(size_type new_size, const value_type& x) { const size_type len = size(); if (new_size < len) erase(start + new_size, finish); else insert(finish, new_size - len, x); } void resize(size_type new_size) { resize(new_size, value_type()); } public: // Erase iterator erase(iterator pos) { iterator next = pos; ++next; difference_type index = pos - start; if (index < (size() >> 1)) { copy_backward(start, pos, next); pop_front(); } else { copy(next, finish, pos); pop_back(); } return start + index; } iterator erase(iterator first, iterator last); void clear(); protected: // Internal construction/destruction void create_map_and_nodes(size_type num_elements); void destroy_map_and_nodes(); void fill_initialize(size_type n, const value_type& value); #ifdef __STL_MEMBER_TEMPLATES template void range_initialize(InputIterator first, InputIterator last, input_iterator_tag); template void range_initialize(ForwardIterator first, ForwardIterator last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ protected: // Internal push_* and pop_* void push_back_aux(const value_type& t); void push_front_aux(const value_type& t); void pop_back_aux(); void pop_front_aux(); protected: // Internal insert functions #ifdef __STL_MEMBER_TEMPLATES template void insert(iterator pos, InputIterator first, InputIterator last, input_iterator_tag); template void insert(iterator pos, ForwardIterator first, ForwardIterator last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ iterator insert_aux(iterator pos, const value_type& x); void insert_aux(iterator pos, size_type n, const value_type& x); #ifdef __STL_MEMBER_TEMPLATES template void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last, size_type n); #else /* __STL_MEMBER_TEMPLATES */ void insert_aux(iterator pos, const value_type* first, const value_type* last, size_type n); void insert_aux(iterator pos, const_iterator first, const_iterator last, size_type n); #endif /* __STL_MEMBER_TEMPLATES */ iterator reserve_elements_at_front(size_type n) { size_type vacancies = start.cur - start.first; if (n > vacancies) new_elements_at_front(n - vacancies); return start - difference_type(n); } iterator reserve_elements_at_back(size_type n) { size_type vacancies = (finish.last - finish.cur) - 1; if (n > vacancies) new_elements_at_back(n - vacancies); return finish + difference_type(n); } void new_elements_at_front(size_type new_elements); void new_elements_at_back(size_type new_elements); void destroy_nodes_at_front(iterator before_start); void destroy_nodes_at_back(iterator after_finish); protected: // Allocation of map and nodes // Makes sure the map has space for new nodes. Does not actually // add the nodes. Can invalidate map pointers. (And consequently, // deque iterators.) void reserve_map_at_back (size_type nodes_to_add = 1) { if (nodes_to_add + 1 > map_size - (finish.node - map)) reallocate_map(nodes_to_add, false); } void reserve_map_at_front (size_type nodes_to_add = 1) { if (nodes_to_add > start.node - map) reallocate_map(nodes_to_add, true); } void reallocate_map(size_type nodes_to_add, bool add_at_front); pointer allocate_node() { return data_allocator::allocate(buffer_size()); } void deallocate_node(pointer n) { data_allocator::deallocate(n, buffer_size()); } #ifdef __STL_NON_TYPE_TMPL_PARAM_BUG public: bool operator==(const deque& x) const { return size() == x.size() && equal(begin(), end(), x.begin()); } bool operator!=(const deque& x) const { return size() != x.size() || !equal(begin(), end(), x.begin()); } bool operator<(const deque& x) const { return lexicographical_compare(begin(), end(), x.begin(), x.end()); } #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ }; // Non-inline member functions template void deque::insert(iterator pos, size_type n, const value_type& x) { if (pos.cur == start.cur) { iterator new_start = reserve_elements_at_front(n); uninitialized_fill(new_start, start, x); start = new_start; } else if (pos.cur == finish.cur) { iterator new_finish = reserve_elements_at_back(n); uninitialized_fill(finish, new_finish, x); finish = new_finish; } else insert_aux(pos, n, x); } #ifndef __STL_MEMBER_TEMPLATES template void deque::insert(iterator pos, const value_type* first, const value_type* last) { size_type n = last - first; if (pos.cur == start.cur) { iterator new_start = reserve_elements_at_front(n); __STL_TRY { uninitialized_copy(first, last, new_start); start = new_start; } __STL_UNWIND(destroy_nodes_at_front(new_start)); } else if (pos.cur == finish.cur) { iterator new_finish = reserve_elements_at_back(n); __STL_TRY { uninitialized_copy(first, last, finish); finish = new_finish; } __STL_UNWIND(destroy_nodes_at_back(new_finish)); } else insert_aux(pos, first, last, n); } template void deque::insert(iterator pos, const_iterator first, const_iterator last) { size_type n = last - first; if (pos.cur == start.cur) { iterator new_start = reserve_elements_at_front(n); __STL_TRY { uninitialized_copy(first, last, new_start); start = new_start; } __STL_UNWIND(destroy_nodes_at_front(new_start)); } else if (pos.cur == finish.cur) { iterator new_finish = reserve_elements_at_back(n); __STL_TRY { uninitialized_copy(first, last, finish); finish = new_finish; } __STL_UNWIND(destroy_nodes_at_back(new_finish)); } else insert_aux(pos, first, last, n); } #endif /* __STL_MEMBER_TEMPLATES */ template deque::iterator deque::erase(iterator first, iterator last) { if (first == start && last == finish) { clear(); return finish; } else { difference_type n = last - first; difference_type elems_before = first - start; if (elems_before < (size() - n) / 2) { copy_backward(start, first, last); iterator new_start = start + n; destroy(start, new_start); for (map_pointer cur = start.node; cur < new_start.node; ++cur) data_allocator::deallocate(*cur, buffer_size()); start = new_start; } else { copy(last, finish, first); iterator new_finish = finish - n; destroy(new_finish, finish); for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur) data_allocator::deallocate(*cur, buffer_size()); finish = new_finish; } return start + elems_before; } } template void deque::clear() { for (map_pointer node = start.node + 1; node < finish.node; ++node) { destroy(*node, *node + buffer_size()); data_allocator::deallocate(*node, buffer_size()); } if (start.node != finish.node) { destroy(start.cur, start.last); destroy(finish.first, finish.cur); data_allocator::deallocate(finish.first, buffer_size()); } else destroy(start.cur, finish.cur); finish = start; } template void deque::create_map_and_nodes(size_type num_elements) { size_type num_nodes = num_elements / buffer_size() + 1; map_size = max(initial_map_size(), num_nodes + 2); map = map_allocator::allocate(map_size); map_pointer nstart = map + (map_size - num_nodes) / 2; map_pointer nfinish = nstart + num_nodes - 1; map_pointer cur; __STL_TRY { for (cur = nstart; cur <= nfinish; ++cur) *cur = allocate_node(); } # ifdef __STL_USE_EXCEPTIONS catch(...) { for (map_pointer n = nstart; n < cur; ++n) deallocate_node(*n); map_allocator::deallocate(map, map_size); throw; } # endif /* __STL_USE_EXCEPTIONS */ start.set_node(nstart); finish.set_node(nfinish); start.cur = start.first; finish.cur = finish.first + num_elements % buffer_size(); } // This is only used as a cleanup function in catch clauses. template void deque::destroy_map_and_nodes() { for (map_pointer cur = start.node; cur <= finish.node; ++cur) deallocate_node(*cur); map_allocator::deallocate(map, map_size); } template void deque::fill_initialize(size_type n, const value_type& value) { create_map_and_nodes(n); map_pointer cur; __STL_TRY { for (cur = start.node; cur < finish.node; ++cur) uninitialized_fill(*cur, *cur + buffer_size(), value); uninitialized_fill(finish.first, finish.cur, value); } # ifdef __STL_USE_EXCEPTIONS catch(...) { for (map_pointer n = start.node; n < cur; ++n) destroy(*n, *n + buffer_size()); destroy_map_and_nodes(); throw; } # endif /* __STL_USE_EXCEPTIONS */ } #ifdef __STL_MEMBER_TEMPLATES template template void deque::range_initialize(InputIterator first, InputIterator last, input_iterator_tag) { create_map_and_nodes(0); for ( ; first != last; ++first) push_back(*first); } template template void deque::range_initialize(ForwardIterator first, ForwardIterator last, forward_iterator_tag) { size_type n = 0; distance(first, last, n); create_map_and_nodes(n); __STL_TRY { uninitialized_copy(first, last, start); } __STL_UNWIND(destroy_map_and_nodes()); } #endif /* __STL_MEMBER_TEMPLATES */ // Called only if finish.cur == finish.last - 1. template void deque::push_back_aux(const value_type& t) { value_type t_copy = t; reserve_map_at_back(); *(finish.node + 1) = allocate_node(); __STL_TRY { construct(finish.cur, t_copy); finish.set_node(finish.node + 1); finish.cur = finish.first; } __STL_UNWIND(deallocate_node(*(finish.node + 1))); } // Called only if start.cur == start.first. template void deque::push_front_aux(const value_type& t) { value_type t_copy = t; reserve_map_at_front(); *(start.node - 1) = allocate_node(); __STL_TRY { start.set_node(start.node - 1); start.cur = start.last - 1; construct(start.cur, t_copy); } # ifdef __STL_USE_EXCEPTIONS catch(...) { start.set_node(start.node + 1); start.cur = start.first; deallocate_node(*(start.node - 1)); throw; } # endif /* __STL_USE_EXCEPTIONS */ } // Called only if finish.cur == finish.first. template void deque:: pop_back_aux() { deallocate_node(finish.first); finish.set_node(finish.node - 1); finish.cur = finish.last - 1; destroy(finish.cur); } // Called only if start.cur == start.last - 1. Note that if the deque // has at least one element (a necessary precondition for this member // function), and if start.cur == start.last, then the deque must have // at least two nodes. template void deque::pop_front_aux() { destroy(start.cur); deallocate_node(start.first); start.set_node(start.node + 1); start.cur = start.first; } #ifdef __STL_MEMBER_TEMPLATES template template void deque::insert(iterator pos, InputIterator first, InputIterator last, input_iterator_tag) { copy(first, last, inserter(*this, pos)); } template template void deque::insert(iterator pos, ForwardIterator first, ForwardIterator last, forward_iterator_tag) { size_type n = 0; distance(first, last, n); if (pos.cur == start.cur) { iterator new_start = reserve_elements_at_front(n); __STL_TRY { uninitialized_copy(first, last, new_start); start = new_start; } __STL_UNWIND(destroy_nodes_at_front(new_start)); } else if (pos.cur == finish.cur) { iterator new_finish = reserve_elements_at_back(n); __STL_TRY { uninitialized_copy(first, last, finish); finish = new_finish; } __STL_UNWIND(destroy_nodes_at_back(new_finish)); } else insert_aux(pos, first, last, n); } #endif /* __STL_MEMBER_TEMPLATES */ template typename deque::iterator deque::insert_aux(iterator pos, const value_type& x) { difference_type index = pos - start; value_type x_copy = x; if (index < size() / 2) { push_front(front()); iterator front1 = start; ++front1; iterator front2 = front1; ++front2; pos = start + index; iterator pos1 = pos; ++pos1; copy(front2, pos1, front1); } else { push_back(back()); iterator back1 = finish; --back1; iterator back2 = back1; --back2; pos = start + index; copy_backward(pos, back2, back1); } *pos = x_copy; return pos; } template void deque::insert_aux(iterator pos, size_type n, const value_type& x) { const difference_type elems_before = pos - start; size_type length = size(); value_type x_copy = x; if (elems_before < length / 2) { iterator new_start = reserve_elements_at_front(n); iterator old_start = start; pos = start + elems_before; __STL_TRY { if (elems_before >= difference_type(n)) { iterator start_n = start + difference_type(n); uninitialized_copy(start, start_n, new_start); start = new_start; copy(start_n, pos, old_start); fill(pos - difference_type(n), pos, x_copy); } else { __uninitialized_copy_fill(start, pos, new_start, start, x_copy); start = new_start; fill(old_start, pos, x_copy); } } __STL_UNWIND(destroy_nodes_at_front(new_start)); } else { iterator new_finish = reserve_elements_at_back(n); iterator old_finish = finish; const difference_type elems_after = difference_type(length) - elems_before; pos = finish - elems_after; __STL_TRY { if (elems_after > difference_type(n)) { iterator finish_n = finish - difference_type(n); uninitialized_copy(finish_n, finish, finish); finish = new_finish; copy_backward(pos, finish_n, old_finish); fill(pos, pos + difference_type(n), x_copy); } else { __uninitialized_fill_copy(finish, pos + difference_type(n), x_copy, pos, finish); finish = new_finish; fill(pos, old_finish, x_copy); } } __STL_UNWIND(destroy_nodes_at_back(new_finish)); } } #ifdef __STL_MEMBER_TEMPLATES template template void deque::insert_aux(iterator pos, ForwardIterator first, ForwardIterator last, size_type n) { const difference_type elems_before = pos - start; size_type length = size(); if (elems_before < length / 2) { iterator new_start = reserve_elements_at_front(n); iterator old_start = start; pos = start + elems_before; __STL_TRY { if (elems_before >= difference_type(n)) { iterator start_n = start + difference_type(n); uninitialized_copy(start, start_n, new_start); start = new_start; copy(start_n, pos, old_start); copy(first, last, pos - difference_type(n)); } else { ForwardIterator mid = first; advance(mid, difference_type(n) - elems_before); __uninitialized_copy_copy(start, pos, first, mid, new_start); start = new_start; copy(mid, last, old_start); } } __STL_UNWIND(destroy_nodes_at_front(new_start)); } else { iterator new_finish = reserve_elements_at_back(n); iterator old_finish = finish; const difference_type elems_after = difference_type(length) - elems_before; pos = finish - elems_after; __STL_TRY { if (elems_after > difference_type(n)) { iterator finish_n = finish - difference_type(n); uninitialized_copy(finish_n, finish, finish); finish = new_finish; copy_backward(pos, finish_n, old_finish); copy(first, last, pos); } else { ForwardIterator mid = first; advance(mid, elems_after); __uninitialized_copy_copy(mid, last, pos, finish, finish); finish = new_finish; copy(first, mid, pos); } } __STL_UNWIND(destroy_nodes_at_back(new_finish)); } } #else /* __STL_MEMBER_TEMPLATES */ template void deque::insert_aux(iterator pos, const value_type* first, const value_type* last, size_type n) { const difference_type elems_before = pos - start; size_type length = size(); if (elems_before < length / 2) { iterator new_start = reserve_elements_at_front(n); iterator old_start = start; pos = start + elems_before; __STL_TRY { if (elems_before >= difference_type(n)) { iterator start_n = start + difference_type(n); uninitialized_copy(start, start_n, new_start); start = new_start; copy(start_n, pos, old_start); copy(first, last, pos - difference_type(n)); } else { const value_type* mid = first + (difference_type(n) - elems_before); __uninitialized_copy_copy(start, pos, first, mid, new_start); start = new_start; copy(mid, last, old_start); } } __STL_UNWIND(destroy_nodes_at_front(new_start)); } else { iterator new_finish = reserve_elements_at_back(n); iterator old_finish = finish; const difference_type elems_after = difference_type(length) - elems_before; pos = finish - elems_after; __STL_TRY { if (elems_after > difference_type(n)) { iterator finish_n = finish - difference_type(n); uninitialized_copy(finish_n, finish, finish); finish = new_finish; copy_backward(pos, finish_n, old_finish); copy(first, last, pos); } else { const value_type* mid = first + elems_after; __uninitialized_copy_copy(mid, last, pos, finish, finish); finish = new_finish; copy(first, mid, pos); } } __STL_UNWIND(destroy_nodes_at_back(new_finish)); } } template void deque::insert_aux(iterator pos, const_iterator first, const_iterator last, size_type n) { const difference_type elems_before = pos - start; size_type length = size(); if (elems_before < length / 2) { iterator new_start = reserve_elements_at_front(n); iterator old_start = start; pos = start + elems_before; __STL_TRY { if (elems_before >= n) { iterator start_n = start + n; uninitialized_copy(start, start_n, new_start); start = new_start; copy(start_n, pos, old_start); copy(first, last, pos - difference_type(n)); } else { const_iterator mid = first + (n - elems_before); __uninitialized_copy_copy(start, pos, first, mid, new_start); start = new_start; copy(mid, last, old_start); } } __STL_UNWIND(destroy_nodes_at_front(new_start)); } else { iterator new_finish = reserve_elements_at_back(n); iterator old_finish = finish; const difference_type elems_after = length - elems_before; pos = finish - elems_after; __STL_TRY { if (elems_after > n) { iterator finish_n = finish - difference_type(n); uninitialized_copy(finish_n, finish, finish); finish = new_finish; copy_backward(pos, finish_n, old_finish); copy(first, last, pos); } else { const_iterator mid = first + elems_after; __uninitialized_copy_copy(mid, last, pos, finish, finish); finish = new_finish; copy(first, mid, pos); } } __STL_UNWIND(destroy_nodes_at_back(new_finish)); } } #endif /* __STL_MEMBER_TEMPLATES */ template void deque::new_elements_at_front(size_type new_elements) { size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size(); reserve_map_at_front(new_nodes); size_type i; __STL_TRY { for (i = 1; i <= new_nodes; ++i) *(start.node - i) = allocate_node(); } # ifdef __STL_USE_EXCEPTIONS catch(...) { for (size_type j = 1; j < i; ++j) deallocate_node(*(start.node - j)); throw; } # endif /* __STL_USE_EXCEPTIONS */ } template void deque::new_elements_at_back(size_type new_elements) { size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size(); reserve_map_at_back(new_nodes); size_type i; __STL_TRY { for (i = 1; i <= new_nodes; ++i) *(finish.node + i) = allocate_node(); } # ifdef __STL_USE_EXCEPTIONS catch(...) { for (size_type j = 1; j < i; ++j) deallocate_node(*(finish.node + j)); throw; } # endif /* __STL_USE_EXCEPTIONS */ } template void deque::destroy_nodes_at_front(iterator before_start) { for (map_pointer n = before_start.node; n < start.node; ++n) deallocate_node(*n); } template void deque::destroy_nodes_at_back(iterator after_finish) { for (map_pointer n = after_finish.node; n > finish.node; --n) deallocate_node(*n); } template void deque::reallocate_map(size_type nodes_to_add, bool add_at_front) { size_type old_num_nodes = finish.node - start.node + 1; size_type new_num_nodes = old_num_nodes + nodes_to_add; map_pointer new_nstart; if (map_size > 2 * new_num_nodes) { new_nstart = map + (map_size - new_num_nodes) / 2 + (add_at_front ? nodes_to_add : 0); if (new_nstart < start.node) copy(start.node, finish.node + 1, new_nstart); else copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes); } else { size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2; map_pointer new_map = map_allocator::allocate(new_map_size); new_nstart = new_map + (new_map_size - new_num_nodes) / 2 + (add_at_front ? nodes_to_add : 0); copy(start.node, finish.node + 1, new_nstart); map_allocator::deallocate(map, map_size); map = new_map; map_size = new_map_size; } start.set_node(new_nstart); finish.set_node(new_nstart + old_num_nodes - 1); } // Nonmember functions. #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG template bool operator==(const deque& x, const deque& y) { return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); } template bool operator<(const deque& x, const deque& y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ #if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \ !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) template inline void swap(deque& x, deque& y) { x.swap(y); } #endif #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_DEQUE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_function.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_FUNCTION_H #define __SGI_STL_INTERNAL_FUNCTION_H __STL_BEGIN_NAMESPACE template struct unary_function { typedef Arg argument_type; typedef Result result_type; }; template struct binary_function { typedef Arg1 first_argument_type; typedef Arg2 second_argument_type; typedef Result result_type; }; template struct plus : public binary_function { T operator()(const T& x, const T& y) const { return x + y; } }; template struct minus : public binary_function { T operator()(const T& x, const T& y) const { return x - y; } }; template struct multiplies : public binary_function { T operator()(const T& x, const T& y) const { return x * y; } }; template struct divides : public binary_function { T operator()(const T& x, const T& y) const { return x / y; } }; template inline T identity_element(plus) { return T(0); } template inline T identity_element(multiplies) { return T(1); } template struct modulus : public binary_function { T operator()(const T& x, const T& y) const { return x % y; } }; template struct negate : public unary_function { T operator()(const T& x) const { return -x; } }; template struct equal_to : public binary_function { bool operator()(const T& x, const T& y) const { return x == y; } }; template struct not_equal_to : public binary_function { bool operator()(const T& x, const T& y) const { return x != y; } }; template struct greater : public binary_function { bool operator()(const T& x, const T& y) const { return x > y; } }; template struct less : public binary_function { bool operator()(const T& x, const T& y) const { return x < y; } }; template struct greater_equal : public binary_function { bool operator()(const T& x, const T& y) const { return x >= y; } }; template struct less_equal : public binary_function { bool operator()(const T& x, const T& y) const { return x <= y; } }; template struct logical_and : public binary_function { bool operator()(const T& x, const T& y) const { return x && y; } }; template struct logical_or : public binary_function { bool operator()(const T& x, const T& y) const { return x || y; } }; template struct logical_not : public unary_function { bool operator()(const T& x) const { return !x; } }; template class unary_negate : public unary_function { protected: Predicate pred; public: explicit unary_negate(const Predicate& x) : pred(x) {} bool operator()(const typename Predicate::argument_type& x) const { return !pred(x); } }; template inline unary_negate not1(const Predicate& pred) { return unary_negate(pred); } template class binary_negate : public binary_function { protected: Predicate pred; public: explicit binary_negate(const Predicate& x) : pred(x) {} bool operator()(const typename Predicate::first_argument_type& x, const typename Predicate::second_argument_type& y) const { return !pred(x, y); } }; template inline binary_negate not2(const Predicate& pred) { return binary_negate(pred); } template class binder1st : public unary_function { 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); } }; template inline binder1st bind1st(const Operation& op, const T& x) { typedef typename Operation::first_argument_type arg1_type; return binder1st(op, arg1_type(x)); } template class binder2nd : public unary_function { 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); } }; template inline binder2nd bind2nd(const Operation& op, const T& x) { typedef typename Operation::second_argument_type arg2_type; return binder2nd(op, arg2_type(x)); } template class unary_compose : public unary_function { protected: Operation1 op1; Operation2 op2; public: unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {} typename Operation1::result_type operator()(const typename Operation2::argument_type& x) const { return op1(op2(x)); } }; template inline unary_compose compose1(const Operation1& op1, const Operation2& op2) { return unary_compose(op1, op2); } template class binary_compose : public unary_function { protected: Operation1 op1; Operation2 op2; Operation3 op3; public: binary_compose(const Operation1& x, const Operation2& y, const Operation3& z) : op1(x), op2(y), op3(z) { } typename Operation1::result_type operator()(const typename Operation2::argument_type& x) const { return op1(op2(x), op3(x)); } }; template inline binary_compose compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) { return binary_compose(op1, op2, op3); } template class pointer_to_unary_function : public unary_function { protected: Result (*ptr)(Arg); public: pointer_to_unary_function() {} explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {} Result operator()(Arg x) const { return ptr(x); } }; template inline pointer_to_unary_function ptr_fun(Result (*x)(Arg)) { return pointer_to_unary_function(x); } template class pointer_to_binary_function : public binary_function { protected: Result (*ptr)(Arg1, Arg2); public: pointer_to_binary_function() {} explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {} Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); } }; template inline pointer_to_binary_function ptr_fun(Result (*x)(Arg1, Arg2)) { return pointer_to_binary_function(x); } template struct identity : public unary_function { const T& operator()(const T& x) const { return x; } }; template struct select1st : public unary_function { const typename Pair::first_type& operator()(const Pair& x) const { return x.first; } }; template struct select2nd : public unary_function { const typename Pair::second_type& operator()(const Pair& x) const { return x.second; } }; template struct project1st : public binary_function { Arg1 operator()(const Arg1& x, const Arg2&) const { return x; } }; template struct project2nd : public binary_function { Arg2 operator()(const Arg1&, const Arg2& y) const { return y; } }; template struct constant_void_fun { typedef Result result_type; result_type val; constant_void_fun(const result_type& v) : val(v) {} const result_type& operator()() const { return val; } }; #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template #else template #endif struct constant_unary_fun : public unary_function { Result val; constant_unary_fun(const Result& v) : val(v) {} const Result& operator()(const Argument&) const { return val; } }; #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template #else template #endif struct constant_binary_fun : public binary_function { Result val; constant_binary_fun(const Result& v) : val(v) {} const Result& operator()(const Arg1&, const Arg2&) const { return val; } }; template inline constant_void_fun constant0(const Result& val) { return constant_void_fun(val); } template inline constant_unary_fun constant1(const Result& val) { return constant_unary_fun(val); } template inline constant_binary_fun constant2(const Result& val) { return constant_binary_fun(val); } // Note: this code assumes that int is 32 bits. class subtractive_rng : public unary_function { private: unsigned int table[55]; size_t index1; size_t index2; public: unsigned int operator()(unsigned int limit) { index1 = (index1 + 1) % 55; index2 = (index2 + 1) % 55; table[index1] = table[index1] - table[index2]; return table[index1] % limit; } void initialize(unsigned int seed) { unsigned int k = 1; table[54] = seed; size_t i; for (i = 0; i < 54; i++) { size_t ii = (21 * (i + 1) % 55) - 1; table[ii] = k; k = seed - k; seed = table[ii]; } for (int loop = 0; loop < 4; loop++) { for (i = 0; i < 55; i++) table[i] = table[i] - table[(1 + i + 30) % 55]; } index1 = 0; index2 = 31; } subtractive_rng(unsigned int seed) { initialize(seed); } subtractive_rng() { initialize(161803398u); } }; // Adaptor function objects: pointers to member functions. // There are a total of 16 = 2^4 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) Member function with void return type vs member function with // non-void return type. // (4) Const vs non-const member function. // Note that choice (4) is not present in the 8/97 draft C++ standard, // which only allows these adaptors to be used with non-const functions. // This is likely to be recified before the standard becomes final. // Note also that choice (3) is nothing more than a workaround: according // to the draft, compilers should handle void and non-void the same way. // This feature is not yet widely implemented, though. You can only use // member functions returning void if your compiler supports partial // specialization. // All of this complexity is in the function objects themselves. You can // ignore it by using the helper function mem_fun, mem_fun_ref, // mem_fun1, and mem_fun1_ref, which create whichever type of adaptor // is appropriate. template class mem_fun_t : public unary_function { public: explicit mem_fun_t(S (T::*pf)()) : f(pf) {} S operator()(T* p) const { return (p->*f)(); } private: S (T::*f)(); }; template class const_mem_fun_t : public unary_function { public: explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {} S operator()(const T* p) const { return (p->*f)(); } private: S (T::*f)() const; }; template class mem_fun_ref_t : public unary_function { public: explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {} S operator()(T& r) const { return (r.*f)(); } private: S (T::*f)(); }; template class const_mem_fun_ref_t : public unary_function { public: explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {} S operator()(const T& r) const { return (r.*f)(); } private: S (T::*f)() const; }; template class mem_fun1_t : public binary_function { public: explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {} S operator()(T* p, A x) const { return (p->*f)(x); } private: S (T::*f)(A); }; template class const_mem_fun1_t : public binary_function { public: explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {} S operator()(const T* p, A x) const { return (p->*f)(x); } private: S (T::*f)(A) const; }; template class mem_fun1_ref_t : public binary_function { public: explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {} S operator()(T& r, A x) const { return (r.*f)(x); } private: S (T::*f)(A); }; template class const_mem_fun1_ref_t : public binary_function { public: explicit const_mem_fun1_ref_t(S (T::*pf)(A) const) : f(pf) {} S operator()(const T& r, A x) const { return (r.*f)(x); } private: S (T::*f)(A) const; }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template class mem_fun_t : public unary_function { public: explicit mem_fun_t(void (T::*pf)()) : f(pf) {} void operator()(T* p) const { (p->*f)(); } private: void (T::*f)(); }; template class const_mem_fun_t : public unary_function { public: explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {} void operator()(const T* p) const { (p->*f)(); } private: void (T::*f)() const; }; template class mem_fun_ref_t : public unary_function { public: explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {} void operator()(T& r) const { (r.*f)(); } private: void (T::*f)(); }; template class const_mem_fun_ref_t : public unary_function { public: explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {} void operator()(const T& r) const { (r.*f)(); } private: void (T::*f)() const; }; template class mem_fun1_t : public binary_function { public: explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {} void operator()(T* p, A x) const { (p->*f)(x); } private: void (T::*f)(A); }; template class const_mem_fun1_t : public binary_function { public: explicit const_mem_fun1_t(void (T::*pf)(A) const) : f(pf) {} void operator()(const T* p, A x) const { (p->*f)(x); } private: void (T::*f)(A) const; }; template class mem_fun1_ref_t : public binary_function { public: explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {} void operator()(T& r, A x) const { (r.*f)(x); } private: void (T::*f)(A); }; template class const_mem_fun1_ref_t : public binary_function { public: explicit const_mem_fun1_ref_t(void (T::*pf)(A) const) : f(pf) {} void operator()(const T& r, A x) const { (r.*f)(x); } private: void (T::*f)(A) const; }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // Mem_fun adaptor helper functions. There are only four: // mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref. template inline mem_fun_t mem_fun(S (T::*f)()) { return mem_fun_t(f); } template inline const_mem_fun_t mem_fun(S (T::*f)() const) { return const_mem_fun_t(f); } template inline mem_fun_ref_t mem_fun_ref(S (T::*f)()) { return mem_fun_ref_t(f); } template inline const_mem_fun_ref_t mem_fun_ref(S (T::*f)() const) { return const_mem_fun_ref_t(f); } template inline mem_fun1_t mem_fun1(S (T::*f)(A)) { return mem_fun1_t(f); } template inline const_mem_fun1_t mem_fun1(S (T::*f)(A) const) { return const_mem_fun1_t(f); } template inline mem_fun1_ref_t mem_fun1_ref(S (T::*f)(A)) { return mem_fun1_ref_t(f); } template inline const_mem_fun1_ref_t mem_fun1_ref(S (T::*f)(A) const) { return const_mem_fun1_ref_t(f); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_FUNCTION_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_hash_fun.h ================================================ /* * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_HASH_FUN_H #define __SGI_STL_HASH_FUN_H #include __STL_BEGIN_NAMESPACE template 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); } __STL_TEMPLATE_NULL struct hash { size_t operator()(const char* s) const { return __stl_hash_string(s); } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(const char* s) const { return __stl_hash_string(s); } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(char x) const { return x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned char x) const { return x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned char x) const { return x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(short x) const { return x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned short x) const { return x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(int x) const { return x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned int x) const { return x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(long x) const { return x; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(unsigned long x) const { return x; } }; __STL_END_NAMESPACE #endif /* __SGI_STL_HASH_FUN_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_hash_map.h ================================================ /* * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_HASH_MAP_H #define __SGI_STL_INTERNAL_HASH_MAP_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template , class EqualKey = equal_to, class Alloc = alloc> #else template #endif class hash_map { private: typedef hashtable, Key, HashFcn, select1st >, EqualKey, Alloc> ht; ht rep; public: typedef typename ht::key_type key_type; typedef T data_type; typedef T 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; hasher hash_funct() const { return rep.hash_funct(); } key_equal key_eq() const { return rep.key_eq(); } public: hash_map() : rep(100, hasher(), key_equal()) {} explicit hash_map(size_type n) : rep(n, hasher(), key_equal()) {} hash_map(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} hash_map(size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) {} #ifdef __STL_MEMBER_TEMPLATES template hash_map(InputIterator f, InputIterator l) : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } template hash_map(InputIterator f, InputIterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } template hash_map(InputIterator f, InputIterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } template hash_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_unique(f, l); } #else hash_map(const value_type* f, const value_type* l) : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } hash_map(const value_type* f, const value_type* l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } hash_map(const value_type* f, const value_type* l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } hash_map(const value_type* f, const value_type* l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_unique(f, l); } hash_map(const_iterator f, const_iterator l) : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } hash_map(const_iterator f, const_iterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } hash_map(const_iterator f, const_iterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } hash_map(const_iterator f, const_iterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_unique(f, l); } #endif /*__STL_MEMBER_TEMPLATES */ public: size_type size() const { return rep.size(); } size_type max_size() const { return rep.max_size(); } bool empty() const { return rep.empty(); } void swap(hash_map& hs) { rep.swap(hs.rep); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); iterator begin() { return rep.begin(); } iterator end() { return rep.end(); } const_iterator begin() const { return rep.begin(); } const_iterator end() const { return rep.end(); } public: pair insert(const value_type& obj) { return rep.insert_unique(obj); } #ifdef __STL_MEMBER_TEMPLATES template void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); } #else void insert(const value_type* f, const value_type* l) { rep.insert_unique(f,l); } void insert(const_iterator f, const_iterator l) { rep.insert_unique(f, l); } #endif /*__STL_MEMBER_TEMPLATES */ pair insert_noresize(const value_type& obj) { return rep.insert_unique_noresize(obj); } iterator find(const key_type& key) { return rep.find(key); } const_iterator find(const key_type& key) const { return rep.find(key); } T& operator[](const key_type& key) { return rep.find_or_insert(value_type(key, T())).second; } size_type count(const key_type& key) const { return rep.count(key); } pair equal_range(const key_type& key) { return rep.equal_range(key); } pair equal_range(const key_type& key) const { return rep.equal_range(key); } size_type erase(const key_type& key) {return rep.erase(key); } void erase(iterator it) { rep.erase(it); } void erase(iterator f, iterator l) { rep.erase(f, l); } void clear() { rep.clear(); } public: void resize(size_type hint) { rep.resize(hint); } size_type bucket_count() const { return rep.bucket_count(); } size_type max_bucket_count() const { return rep.max_bucket_count(); } size_type elems_in_bucket(size_type n) const { return rep.elems_in_bucket(n); } }; template inline bool operator==(const hash_map& hm1, const hash_map& hm2) { return hm1.rep == hm2.rep; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(hash_map& hm1, hash_map& hm2) { hm1.swap(hm2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template , class EqualKey = equal_to, class Alloc = alloc> #else template #endif class hash_multimap { private: typedef hashtable, Key, HashFcn, select1st >, EqualKey, Alloc> ht; ht rep; public: typedef typename ht::key_type key_type; typedef T data_type; typedef T 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; hasher hash_funct() const { return rep.hash_funct(); } key_equal key_eq() const { return rep.key_eq(); } public: hash_multimap() : rep(100, hasher(), key_equal()) {} explicit hash_multimap(size_type n) : rep(n, hasher(), key_equal()) {} hash_multimap(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} hash_multimap(size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) {} #ifdef __STL_MEMBER_TEMPLATES template hash_multimap(InputIterator f, InputIterator l) : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } template hash_multimap(InputIterator f, InputIterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } template hash_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } template hash_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_equal(f, l); } #else hash_multimap(const value_type* f, const value_type* l) : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multimap(const value_type* f, const value_type* l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multimap(const value_type* f, const value_type* l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } hash_multimap(const value_type* f, const value_type* l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_equal(f, l); } hash_multimap(const_iterator f, const_iterator l) : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multimap(const_iterator f, const_iterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multimap(const_iterator f, const_iterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } hash_multimap(const_iterator f, const_iterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_equal(f, l); } #endif /*__STL_MEMBER_TEMPLATES */ public: size_type size() const { return rep.size(); } size_type max_size() const { return rep.max_size(); } bool empty() const { return rep.empty(); } void swap(hash_multimap& hs) { rep.swap(hs.rep); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, const hash_multimap&); iterator begin() { return rep.begin(); } iterator end() { return rep.end(); } const_iterator begin() const { return rep.begin(); } const_iterator end() const { return rep.end(); } public: iterator insert(const value_type& obj) { return rep.insert_equal(obj); } #ifdef __STL_MEMBER_TEMPLATES template void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } #else void insert(const value_type* f, const value_type* l) { rep.insert_equal(f,l); } void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } #endif /*__STL_MEMBER_TEMPLATES */ iterator insert_noresize(const value_type& obj) { return rep.insert_equal_noresize(obj); } iterator find(const key_type& key) { return rep.find(key); } const_iterator find(const key_type& key) const { return rep.find(key); } size_type count(const key_type& key) const { return rep.count(key); } pair equal_range(const key_type& key) { return rep.equal_range(key); } pair equal_range(const key_type& key) const { return rep.equal_range(key); } size_type erase(const key_type& key) {return rep.erase(key); } void erase(iterator it) { rep.erase(it); } void erase(iterator f, iterator l) { rep.erase(f, l); } void clear() { rep.clear(); } public: void resize(size_type hint) { rep.resize(hint); } size_type bucket_count() const { return rep.bucket_count(); } size_type max_bucket_count() const { return rep.max_bucket_count(); } size_type elems_in_bucket(size_type n) const { return rep.elems_in_bucket(n); } }; template inline bool operator==(const hash_multimap& hm1, const hash_multimap& hm2) { return hm1.rep == hm2.rep; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(hash_multimap& hm1, hash_multimap& hm2) { hm1.swap(hm2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HASH_MAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_hash_set.h ================================================ /* * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_HASH_SET_H #define __SGI_STL_INTERNAL_HASH_SET_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template , class EqualKey = equal_to, class Alloc = alloc> #else template #endif class hash_set { private: typedef hashtable, EqualKey, Alloc> ht; ht rep; 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 ht::const_pointer pointer; typedef typename ht::const_pointer const_pointer; typedef typename ht::const_reference reference; typedef typename ht::const_reference const_reference; typedef typename ht::const_iterator iterator; typedef typename ht::const_iterator const_iterator; hasher hash_funct() const { return rep.hash_funct(); } key_equal key_eq() const { return rep.key_eq(); } public: hash_set() : rep(100, hasher(), key_equal()) {} explicit hash_set(size_type n) : rep(n, hasher(), key_equal()) {} hash_set(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} hash_set(size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) {} #ifdef __STL_MEMBER_TEMPLATES template hash_set(InputIterator f, InputIterator l) : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } template hash_set(InputIterator f, InputIterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } template hash_set(InputIterator f, InputIterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } template hash_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_unique(f, l); } #else hash_set(const value_type* f, const value_type* l) : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } hash_set(const value_type* f, const value_type* l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } hash_set(const value_type* f, const value_type* l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } hash_set(const value_type* f, const value_type* l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_unique(f, l); } hash_set(const_iterator f, const_iterator l) : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } hash_set(const_iterator f, const_iterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } hash_set(const_iterator f, const_iterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } hash_set(const_iterator f, const_iterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_unique(f, l); } #endif /*__STL_MEMBER_TEMPLATES */ public: size_type size() const { return rep.size(); } size_type max_size() const { return rep.max_size(); } bool empty() const { return rep.empty(); } void swap(hash_set& hs) { rep.swap(hs.rep); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_set&, const hash_set&); iterator begin() const { return rep.begin(); } iterator end() const { return rep.end(); } public: pair insert(const value_type& obj) { pair p = rep.insert_unique(obj); return pair(p.first, p.second); } #ifdef __STL_MEMBER_TEMPLATES template void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); } #else void insert(const value_type* f, const value_type* l) { rep.insert_unique(f,l); } void insert(const_iterator f, const_iterator l) {rep.insert_unique(f, l); } #endif /*__STL_MEMBER_TEMPLATES */ pair insert_noresize(const value_type& obj) { pair p = rep.insert_unique_noresize(obj); return pair(p.first, p.second); } iterator find(const key_type& key) const { return rep.find(key); } size_type count(const key_type& key) const { return rep.count(key); } pair equal_range(const key_type& key) const { return rep.equal_range(key); } size_type erase(const key_type& key) {return rep.erase(key); } void erase(iterator it) { rep.erase(it); } void erase(iterator f, iterator l) { rep.erase(f, l); } void clear() { rep.clear(); } public: void resize(size_type hint) { rep.resize(hint); } size_type bucket_count() const { return rep.bucket_count(); } size_type max_bucket_count() const { return rep.max_bucket_count(); } size_type elems_in_bucket(size_type n) const { return rep.elems_in_bucket(n); } }; template inline bool operator==(const hash_set& hs1, const hash_set& hs2) { return hs1.rep == hs2.rep; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(hash_set& hs1, hash_set& hs2) { hs1.swap(hs2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template , class EqualKey = equal_to, class Alloc = alloc> #else template #endif class hash_multiset { private: typedef hashtable, EqualKey, Alloc> ht; ht rep; 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 ht::const_pointer pointer; typedef typename ht::const_pointer const_pointer; typedef typename ht::const_reference reference; typedef typename ht::const_reference const_reference; typedef typename ht::const_iterator iterator; typedef typename ht::const_iterator const_iterator; hasher hash_funct() const { return rep.hash_funct(); } key_equal key_eq() const { return rep.key_eq(); } public: hash_multiset() : rep(100, hasher(), key_equal()) {} explicit hash_multiset(size_type n) : rep(n, hasher(), key_equal()) {} hash_multiset(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} hash_multiset(size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) {} #ifdef __STL_MEMBER_TEMPLATES template hash_multiset(InputIterator f, InputIterator l) : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } template hash_multiset(InputIterator f, InputIterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } template hash_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } template hash_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_equal(f, l); } #else hash_multiset(const value_type* f, const value_type* l) : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multiset(const value_type* f, const value_type* l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multiset(const value_type* f, const value_type* l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } hash_multiset(const value_type* f, const value_type* l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_equal(f, l); } hash_multiset(const_iterator f, const_iterator l) : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multiset(const_iterator f, const_iterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multiset(const_iterator f, const_iterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } hash_multiset(const_iterator f, const_iterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_equal(f, l); } #endif /*__STL_MEMBER_TEMPLATES */ public: size_type size() const { return rep.size(); } size_type max_size() const { return rep.max_size(); } bool empty() const { return rep.empty(); } void swap(hash_multiset& hs) { rep.swap(hs.rep); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_multiset&, const hash_multiset&); iterator begin() const { return rep.begin(); } iterator end() const { return rep.end(); } public: iterator insert(const value_type& obj) { return rep.insert_equal(obj); } #ifdef __STL_MEMBER_TEMPLATES template void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } #else void insert(const value_type* f, const value_type* l) { rep.insert_equal(f,l); } void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } #endif /*__STL_MEMBER_TEMPLATES */ iterator insert_noresize(const value_type& obj) { return rep.insert_equal_noresize(obj); } iterator find(const key_type& key) const { return rep.find(key); } size_type count(const key_type& key) const { return rep.count(key); } pair equal_range(const key_type& key) const { return rep.equal_range(key); } size_type erase(const key_type& key) {return rep.erase(key); } void erase(iterator it) { rep.erase(it); } void erase(iterator f, iterator l) { rep.erase(f, l); } void clear() { rep.clear(); } public: void resize(size_type hint) { rep.resize(hint); } size_type bucket_count() const { return rep.bucket_count(); } size_type max_bucket_count() const { return rep.max_bucket_count(); } size_type elems_in_bucket(size_type n) const { return rep.elems_in_bucket(n); } }; template inline bool operator==(const hash_multiset& hs1, const hash_multiset& hs2) { return hs1.rep == hs2.rep; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(hash_multiset& hs1, hash_multiset& hs2) { hs1.swap(hs2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HASH_SET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_hashtable.h ================================================ /* * 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 __SGI_STL_INTERNAL_HASHTABLE_H #define __SGI_STL_INTERNAL_HASHTABLE_H // Hashtable class, used to implement the hashed associative containers // hash_set, hash_map, hash_multiset, and hash_multimap. #include #include #include #include #include #include #include #include #include __STL_BEGIN_NAMESPACE template struct __hashtable_node { __hashtable_node* next; Value val; }; template class hashtable; template struct __hashtable_iterator; template struct __hashtable_const_iterator; template struct __hashtable_iterator { typedef hashtable hashtable; typedef __hashtable_iterator iterator; typedef __hashtable_const_iterator const_iterator; typedef __hashtable_node node; typedef forward_iterator_tag iterator_category; typedef Value value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; typedef Value& reference; typedef Value* pointer; node* cur; hashtable* ht; __hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {} __hashtable_iterator() {} reference operator*() const { return cur->val; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ iterator& operator++(); iterator operator++(int); bool operator==(const iterator& it) const { return cur == it.cur; } bool operator!=(const iterator& it) const { return cur != it.cur; } }; template struct __hashtable_const_iterator { typedef hashtable hashtable; typedef __hashtable_iterator iterator; typedef __hashtable_const_iterator const_iterator; typedef __hashtable_node node; typedef forward_iterator_tag iterator_category; typedef Value value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; typedef const Value& reference; typedef const Value* pointer; const node* cur; const hashtable* ht; __hashtable_const_iterator(const node* n, const hashtable* tab) : cur(n), ht(tab) {} __hashtable_const_iterator() {} __hashtable_const_iterator(const iterator& it) : cur(it.cur), ht(it.ht) {} reference operator*() const { return cur->val; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ const_iterator& operator++(); const_iterator operator++(int); bool operator==(const const_iterator& it) const { return cur == it.cur; } bool operator!=(const const_iterator& it) const { return cur != it.cur; } }; // Note: assumes long is at least 32 bits. static const int __stl_num_primes = 28; static const unsigned long __stl_prime_list[__stl_num_primes] = { 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741, 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 + __stl_num_primes; const unsigned long* pos = lower_bound(first, last, n); return pos == last ? *(last - 1) : *pos; } template class hashtable { public: typedef Key key_type; typedef Value 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 hash; } key_equal key_eq() const { return equals; } private: hasher hash; key_equal equals; ExtractKey get_key; typedef __hashtable_node node; typedef simple_alloc node_allocator; vector buckets; size_type num_elements; public: typedef __hashtable_iterator iterator; typedef __hashtable_const_iterator const_iterator; friend struct __hashtable_iterator; friend struct __hashtable_const_iterator; public: hashtable(size_type n, const HashFcn& hf, const EqualKey& eql, const ExtractKey& ext) : hash(hf), equals(eql), get_key(ext), num_elements(0) { initialize_buckets(n); } hashtable(size_type n, const HashFcn& hf, const EqualKey& eql) : hash(hf), equals(eql), get_key(ExtractKey()), num_elements(0) { initialize_buckets(n); } hashtable(const hashtable& ht) : hash(ht.hash), equals(ht.equals), get_key(ht.get_key), num_elements(0) { copy_from(ht); } hashtable& operator= (const hashtable& ht) { if (&ht != this) { clear(); hash = ht.hash; equals = ht.equals; get_key = ht.get_key; copy_from(ht); } return *this; } ~hashtable() { clear(); } size_type size() const { return num_elements; } size_type max_size() const { return size_type(-1); } bool empty() const { return size() == 0; } void swap(hashtable& ht) { __STD::swap(hash, ht.hash); __STD::swap(equals, ht.equals); __STD::swap(get_key, ht.get_key); buckets.swap(ht.buckets); __STD::swap(num_elements, ht.num_elements); } iterator begin() { for (size_type n = 0; n < buckets.size(); ++n) if (buckets[n]) return iterator(buckets[n], this); return end(); } iterator end() { return iterator(0, this); } const_iterator begin() const { for (size_type n = 0; n < buckets.size(); ++n) if (buckets[n]) return const_iterator(buckets[n], this); return end(); } const_iterator end() const { return const_iterator(0, this); } friend bool operator== __STL_NULL_TMPL_ARGS (const hashtable&, const hashtable&); public: size_type bucket_count() const { return buckets.size(); } size_type max_bucket_count() const { return __stl_prime_list[__stl_num_primes - 1]; } size_type elems_in_bucket(size_type bucket) const { size_type result = 0; for (node* cur = buckets[bucket]; cur; cur = cur->next) result += 1; return result; } pair insert_unique(const value_type& obj) { resize(num_elements + 1); return insert_unique_noresize(obj); } iterator insert_equal(const value_type& obj) { resize(num_elements + 1); return insert_equal_noresize(obj); } pair insert_unique_noresize(const value_type& obj); iterator insert_equal_noresize(const value_type& obj); #ifdef __STL_MEMBER_TEMPLATES template void insert_unique(InputIterator f, InputIterator l) { insert_unique(f, l, iterator_category(f)); } template void insert_equal(InputIterator f, InputIterator l) { insert_equal(f, l, iterator_category(f)); } template void insert_unique(InputIterator f, InputIterator l, input_iterator_tag) { for ( ; f != l; ++f) insert_unique(*f); } template void insert_equal(InputIterator f, InputIterator l, input_iterator_tag) { for ( ; f != l; ++f) insert_equal(*f); } template void insert_unique(ForwardIterator f, ForwardIterator l, forward_iterator_tag) { size_type n = 0; distance(f, l, n); resize(num_elements + n); for ( ; n > 0; --n, ++f) insert_unique_noresize(*f); } template void insert_equal(ForwardIterator f, ForwardIterator l, forward_iterator_tag) { size_type n = 0; distance(f, l, n); resize(num_elements + n); for ( ; n > 0; --n, ++f) insert_equal_noresize(*f); } #else /* __STL_MEMBER_TEMPLATES */ void insert_unique(const value_type* f, const value_type* l) { size_type n = l - f; resize(num_elements + n); for ( ; n > 0; --n, ++f) insert_unique_noresize(*f); } void insert_equal(const value_type* f, const value_type* l) { size_type n = l - f; resize(num_elements + n); for ( ; n > 0; --n, ++f) insert_equal_noresize(*f); } void insert_unique(const_iterator f, const_iterator l) { size_type n = 0; distance(f, l, n); resize(num_elements + n); for ( ; n > 0; --n, ++f) insert_unique_noresize(*f); } void insert_equal(const_iterator f, const_iterator l) { size_type n = 0; distance(f, l, n); resize(num_elements + n); for ( ; n > 0; --n, ++f) insert_equal_noresize(*f); } #endif /*__STL_MEMBER_TEMPLATES */ reference find_or_insert(const value_type& obj); iterator find(const key_type& key) { size_type n = bkt_num_key(key); node* first; for ( first = buckets[n]; first && !equals(get_key(first->val), key); first = first->next) {} return iterator(first, this); } const_iterator find(const key_type& key) const { size_type n = bkt_num_key(key); const node* first; for ( first = buckets[n]; first && !equals(get_key(first->val), key); first = first->next) {} return const_iterator(first, this); } size_type count(const key_type& key) const { const size_type n = bkt_num_key(key); size_type result = 0; for (const node* cur = buckets[n]; cur; cur = cur->next) if (equals(get_key(cur->val), key)) ++result; return result; } pair equal_range(const key_type& key); pair 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 next_size(size_type n) const { return __stl_next_prime(n); } void initialize_buckets(size_type n) { const size_type n_buckets = next_size(n); buckets.reserve(n_buckets); buckets.insert(buckets.end(), n_buckets, (node*) 0); num_elements = 0; } size_type bkt_num_key(const key_type& key) const { return bkt_num_key(key, buckets.size()); } size_type bkt_num(const value_type& obj) const { return bkt_num_key(get_key(obj)); } size_type bkt_num_key(const key_type& key, size_t n) const { return hash(key) % n; } size_type bkt_num(const value_type& obj, size_t n) const { return bkt_num_key(get_key(obj), n); } node* new_node(const value_type& obj) { node* n = node_allocator::allocate(); n->next = 0; __STL_TRY { construct(&n->val, obj); return n; } __STL_UNWIND(node_allocator::deallocate(n)); } void delete_node(node* n) { destroy(&n->val); node_allocator::deallocate(n); } void erase_bucket(const size_type n, node* first, node* last); void erase_bucket(const size_type n, node* last); void copy_from(const hashtable& ht); }; template __hashtable_iterator& __hashtable_iterator::operator++() { const node* old = cur; cur = cur->next; if (!cur) { size_type bucket = ht->bkt_num(old->val); while (!cur && ++bucket < ht->buckets.size()) cur = ht->buckets[bucket]; } return *this; } template inline __hashtable_iterator __hashtable_iterator::operator++(int) { iterator tmp = *this; ++*this; return tmp; } template __hashtable_const_iterator& __hashtable_const_iterator::operator++() { const node* old = cur; cur = cur->next; if (!cur) { size_type bucket = ht->bkt_num(old->val); while (!cur && ++bucket < ht->buckets.size()) cur = ht->buckets[bucket]; } return *this; } template inline __hashtable_const_iterator __hashtable_const_iterator::operator++(int) { const_iterator tmp = *this; ++*this; return tmp; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline forward_iterator_tag iterator_category(const __hashtable_iterator&) { return forward_iterator_tag(); } template inline V* value_type(const __hashtable_iterator&) { return (V*) 0; } template inline hashtable::difference_type* distance_type(const __hashtable_iterator&) { return (hashtable::difference_type*) 0; } template inline forward_iterator_tag iterator_category(const __hashtable_const_iterator&) { return forward_iterator_tag(); } template inline V* value_type(const __hashtable_const_iterator&) { return (V*) 0; } template inline hashtable::difference_type* distance_type(const __hashtable_const_iterator&) { return (hashtable::difference_type*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template bool operator==(const hashtable& ht1, const hashtable& ht2) { typedef typename hashtable::node node; if (ht1.buckets.size() != ht2.buckets.size()) return false; for (int n = 0; n < ht1.buckets.size(); ++n) { node* cur1 = ht1.buckets[n]; node* cur2 = ht2.buckets[n]; for ( ; cur1 && cur2 && cur1->val == cur2->val; cur1 = cur1->next, cur2 = cur2->next) {} if (cur1 || cur2) return false; } return true; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(hashtable& ht1, hashtable& ht2) { ht1.swap(ht2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template pair::iterator, bool> hashtable::insert_unique_noresize(const value_type& obj) { const size_type n = bkt_num(obj); node* first = buckets[n]; for (node* cur = first; cur; cur = cur->next) if (equals(get_key(cur->val), get_key(obj))) return pair(iterator(cur, this), false); node* tmp = new_node(obj); tmp->next = first; buckets[n] = tmp; ++num_elements; return pair(iterator(tmp, this), true); } template typename hashtable::iterator hashtable::insert_equal_noresize(const value_type& obj) { const size_type n = bkt_num(obj); node* first = buckets[n]; for (node* cur = first; cur; cur = cur->next) if (equals(get_key(cur->val), get_key(obj))) { node* tmp = new_node(obj); tmp->next = cur->next; cur->next = tmp; ++num_elements; return iterator(tmp, this); } node* tmp = new_node(obj); tmp->next = first; buckets[n] = tmp; ++num_elements; return iterator(tmp, this); } template typename hashtable::reference hashtable::find_or_insert(const value_type& obj) { resize(num_elements + 1); size_type n = bkt_num(obj); node* first = buckets[n]; for (node* cur = first; cur; cur = cur->next) if (equals(get_key(cur->val), get_key(obj))) return cur->val; node* tmp = new_node(obj); tmp->next = first; buckets[n] = tmp; ++num_elements; return tmp->val; } template pair::iterator, typename hashtable::iterator> hashtable::equal_range(const key_type& key) { typedef pair pii; const size_type n = bkt_num_key(key); for (node* first = buckets[n]; first; first = first->next) { if (equals(get_key(first->val), key)) { for (node* cur = first->next; cur; cur = cur->next) if (!equals(get_key(cur->val), key)) return pii(iterator(first, this), iterator(cur, this)); for (size_type m = n + 1; m < buckets.size(); ++m) if (buckets[m]) return pii(iterator(first, this), iterator(buckets[m], this)); return pii(iterator(first, this), end()); } } return pii(end(), end()); } template pair::const_iterator, typename hashtable::const_iterator> hashtable::equal_range(const key_type& key) const { typedef pair pii; const size_type n = bkt_num_key(key); for (const node* first = buckets[n] ; first; first = first->next) { if (equals(get_key(first->val), key)) { for (const node* cur = first->next; cur; cur = cur->next) if (!equals(get_key(cur->val), key)) return pii(const_iterator(first, this), const_iterator(cur, this)); for (size_type m = n + 1; m < buckets.size(); ++m) if (buckets[m]) return pii(const_iterator(first, this), const_iterator(buckets[m], this)); return pii(const_iterator(first, this), end()); } } return pii(end(), end()); } template typename hashtable::size_type hashtable::erase(const key_type& key) { const size_type n = bkt_num_key(key); node* first = buckets[n]; size_type erased = 0; if (first) { node* cur = first; node* next = cur->next; while (next) { if (equals(get_key(next->val), key)) { cur->next = next->next; delete_node(next); next = cur->next; ++erased; --num_elements; } else { cur = next; next = cur->next; } } if (equals(get_key(first->val), key)) { buckets[n] = first->next; delete_node(first); ++erased; --num_elements; } } return erased; } template void hashtable::erase(const iterator& it) { if (node* const p = it.cur) { const size_type n = bkt_num(p->val); node* cur = buckets[n]; if (cur == p) { buckets[n] = cur->next; delete_node(cur); --num_elements; } else { node* next = cur->next; while (next) { if (next == p) { cur->next = next->next; delete_node(next); --num_elements; break; } else { cur = next; next = cur->next; } } } } } template void hashtable::erase(iterator first, iterator last) { size_type f_bucket = first.cur ? bkt_num(first.cur->val) : buckets.size(); size_type l_bucket = last.cur ? bkt_num(last.cur->val) : buckets.size(); if (first.cur == last.cur) return; else if (f_bucket == l_bucket) erase_bucket(f_bucket, first.cur, last.cur); else { erase_bucket(f_bucket, first.cur, 0); for (size_type n = f_bucket + 1; n < l_bucket; ++n) erase_bucket(n, 0); if (l_bucket != buckets.size()) erase_bucket(l_bucket, last.cur); } } template inline void hashtable::erase(const_iterator first, const_iterator last) { erase(iterator(const_cast(first.cur), const_cast(first.ht)), iterator(const_cast(last.cur), const_cast(last.ht))); } template inline void hashtable::erase(const const_iterator& it) { erase(iterator(const_cast(it.cur), const_cast(it.ht))); } template void hashtable::resize(size_type num_elements_hint) { const size_type old_n = buckets.size(); if (num_elements_hint > old_n) { const size_type n = next_size(num_elements_hint); if (n > old_n) { vector tmp(n, (node*) 0); __STL_TRY { for (size_type bucket = 0; bucket < old_n; ++bucket) { node* first = buckets[bucket]; while (first) { size_type new_bucket = bkt_num(first->val, n); buckets[bucket] = first->next; first->next = tmp[new_bucket]; tmp[new_bucket] = first; first = buckets[bucket]; } } buckets.swap(tmp); } # ifdef __STL_USE_EXCEPTIONS catch(...) { for (size_type bucket = 0; bucket < tmp.size(); ++bucket) { while (tmp[bucket]) { node* next = tmp[bucket]->next; delete_node(tmp[bucket]); tmp[bucket] = next; } } throw; } # endif /* __STL_USE_EXCEPTIONS */ } } } template void hashtable::erase_bucket(const size_type n, node* first, node* last) { node* cur = buckets[n]; if (cur == first) erase_bucket(n, last); else { node* next; for (next = cur->next; next != first; cur = next, next = cur->next) ; while (next) { cur->next = next->next; delete_node(next); next = cur->next; --num_elements; } } } template void hashtable::erase_bucket(const size_type n, node* last) { node* cur = buckets[n]; while (cur != last) { node* next = cur->next; delete_node(cur); cur = next; buckets[n] = cur; --num_elements; } } template void hashtable::clear() { for (size_type i = 0; i < buckets.size(); ++i) { node* cur = buckets[i]; while (cur != 0) { node* next = cur->next; delete_node(cur); cur = next; } buckets[i] = 0; } num_elements = 0; } template void hashtable::copy_from(const hashtable& ht) { buckets.clear(); buckets.reserve(ht.buckets.size()); buckets.insert(buckets.end(), ht.buckets.size(), (node*) 0); __STL_TRY { for (size_type i = 0; i < ht.buckets.size(); ++i) { if (const node* cur = ht.buckets[i]) { node* copy = new_node(cur->val); buckets[i] = copy; for (node* next = cur->next; next; cur = next, next = cur->next) { copy->next = new_node(next->val); copy = copy->next; } } } num_elements = ht.num_elements; } __STL_UNWIND(clear()); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HASHTABLE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_heap.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_HEAP_H #define __SGI_STL_INTERNAL_HEAP_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1209 #endif template void __push_heap(RandomAccessIterator first, Distance holeIndex, Distance topIndex, T 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; } template inline void __push_heap_aux(RandomAccessIterator first, RandomAccessIterator last, Distance*, T*) { __push_heap(first, Distance((last - first) - 1), Distance(0), T(*(last - 1))); } template inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) { __push_heap_aux(first, last, distance_type(first), value_type(first)); } template void __push_heap(RandomAccessIterator first, Distance holeIndex, Distance topIndex, T 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; } template inline void __push_heap_aux(RandomAccessIterator first, RandomAccessIterator last, Compare comp, Distance*, T*) { __push_heap(first, Distance((last - first) - 1), Distance(0), T(*(last - 1)), comp); } template inline void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { __push_heap_aux(first, last, comp, distance_type(first), value_type(first)); } template void __adjust_heap(RandomAccessIterator first, Distance holeIndex, Distance len, T value) { 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; } __push_heap(first, holeIndex, topIndex, value); } template inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator result, T value, Distance*) { *result = *first; __adjust_heap(first, Distance(0), Distance(last - first), value); } template inline void __pop_heap_aux(RandomAccessIterator first, RandomAccessIterator last, T*) { __pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first)); } template inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) { __pop_heap_aux(first, last, value_type(first)); } template void __adjust_heap(RandomAccessIterator first, Distance holeIndex, Distance len, T value, Compare comp) { 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; } __push_heap(first, holeIndex, topIndex, value, comp); } template inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator result, T value, Compare comp, Distance*) { *result = *first; __adjust_heap(first, Distance(0), Distance(last - first), value, comp); } template inline void __pop_heap_aux(RandomAccessIterator first, RandomAccessIterator last, T*, Compare comp) { __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp, distance_type(first)); } template inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { __pop_heap_aux(first, last, value_type(first), comp); } template void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*, Distance*) { if (last - first < 2) return; Distance len = last - first; Distance parent = (len - 2)/2; while (true) { __adjust_heap(first, parent, len, T(*(first + parent))); if (parent == 0) return; parent--; } } template inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) { __make_heap(first, last, value_type(first), distance_type(first)); } template void __make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp, T*, Distance*) { if (last - first < 2) return; Distance len = last - first; Distance parent = (len - 2)/2; while (true) { __adjust_heap(first, parent, len, T(*(first + parent)), comp); if (parent == 0) return; parent--; } } template inline void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { __make_heap(first, last, comp, value_type(first), distance_type(first)); } template void sort_heap(RandomAccessIterator first, RandomAccessIterator last) { while (last - first > 1) pop_heap(first, last--); } template void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { while (last - first > 1) pop_heap(first, last--, comp); } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1209 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_HEAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_iterator.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ITERATOR_H #define __SGI_STL_INTERNAL_ITERATOR_H __STL_BEGIN_NAMESPACE struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; template struct input_iterator { typedef input_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef T& 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 struct forward_iterator { typedef forward_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef T& reference; }; template struct bidirectional_iterator { typedef bidirectional_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef T& reference; }; template struct random_access_iterator { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef T& reference; }; #ifdef __STL_USE_NAMESPACES template struct iterator { typedef Category iterator_category; typedef T value_type; typedef Distance difference_type; typedef Pointer pointer; typedef Reference reference; }; #endif /* __STL_USE_NAMESPACES */ #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template 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 struct iterator_traits { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; }; template struct iterator_traits { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef const T* pointer; typedef const T& reference; }; template inline typename iterator_traits::iterator_category iterator_category(const Iterator&) { typedef typename iterator_traits::iterator_category category; return category(); } template inline typename iterator_traits::difference_type* distance_type(const Iterator&) { return static_cast::difference_type*>(0); } template inline typename iterator_traits::value_type* value_type(const Iterator&) { return static_cast::value_type*>(0); } #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline input_iterator_tag iterator_category(const input_iterator&) { return input_iterator_tag(); } inline output_iterator_tag iterator_category(const output_iterator&) { return output_iterator_tag(); } template inline forward_iterator_tag iterator_category(const forward_iterator&) { return forward_iterator_tag(); } template inline bidirectional_iterator_tag iterator_category(const bidirectional_iterator&) { return bidirectional_iterator_tag(); } template inline random_access_iterator_tag iterator_category(const random_access_iterator&) { return random_access_iterator_tag(); } template inline random_access_iterator_tag iterator_category(const T*) { return random_access_iterator_tag(); } template inline T* value_type(const input_iterator&) { return (T*)(0); } template inline T* value_type(const forward_iterator&) { return (T*)(0); } template inline T* value_type(const bidirectional_iterator&) { return (T*)(0); } template inline T* value_type(const random_access_iterator&) { return (T*)(0); } template inline T* value_type(const T*) { return (T*)(0); } template inline Distance* distance_type(const input_iterator&) { return (Distance*)(0); } template inline Distance* distance_type(const forward_iterator&) { return (Distance*)(0); } template inline Distance* distance_type(const bidirectional_iterator&) { return (Distance*)(0); } template inline Distance* distance_type(const random_access_iterator&) { return (Distance*)(0); } template inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline void __distance(InputIterator first, InputIterator last, Distance& n, input_iterator_tag) { while (first != last) { ++first; ++n; } } template inline void __distance(RandomAccessIterator first, RandomAccessIterator last, Distance& n, random_access_iterator_tag) { n += last - first; } template inline void distance(InputIterator first, InputIterator last, Distance& n) { __distance(first, last, n, iterator_category(first)); } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template inline iterator_traits::difference_type __distance(InputIterator first, InputIterator last, input_iterator_tag) { iterator_traits::difference_type n = 0; while (first != last) { ++first; ++n; } return n; } template inline iterator_traits::difference_type __distance(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag) { return last - first; } template inline iterator_traits::difference_type distance(InputIterator first, InputIterator last) { typedef typename iterator_traits::iterator_category category; return __distance(first, last, category()); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline void __advance(InputIterator& i, Distance n, input_iterator_tag) { while (n--) ++i; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1183 #endif template inline void __advance(BidirectionalIterator& i, Distance n, bidirectional_iterator_tag) { if (n >= 0) while (n--) ++i; else while (n++) --i; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1183 #endif template inline void __advance(RandomAccessIterator& i, Distance n, random_access_iterator_tag) { i += n; } template inline void advance(InputIterator& i, Distance n) { __advance(i, n, iterator_category(i)); } template class back_insert_iterator { protected: Container* container; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit back_insert_iterator(Container& x) : container(&x) {} back_insert_iterator& operator=(const typename Container::value_type& value) { container->push_back(value); return *this; } back_insert_iterator& operator*() { return *this; } back_insert_iterator& operator++() { return *this; } back_insert_iterator& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const back_insert_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline back_insert_iterator back_inserter(Container& x) { return back_insert_iterator(x); } template class front_insert_iterator { protected: Container* container; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit front_insert_iterator(Container& x) : container(&x) {} front_insert_iterator& operator=(const typename Container::value_type& value) { container->push_front(value); return *this; } front_insert_iterator& operator*() { return *this; } front_insert_iterator& operator++() { return *this; } front_insert_iterator& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const front_insert_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline front_insert_iterator front_inserter(Container& x) { return front_insert_iterator(x); } template class insert_iterator { protected: Container* container; typename Container::iterator iter; public: 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), iter(i) {} insert_iterator& operator=(const typename Container::value_type& value) { iter = container->insert(iter, value); ++iter; return *this; } insert_iterator& operator*() { return *this; } insert_iterator& operator++() { return *this; } insert_iterator& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const insert_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline insert_iterator inserter(Container& x, Iterator i) { typedef typename Container::iterator iter; return insert_iterator(x, iter(i)); } #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template #else template #endif class reverse_bidirectional_iterator { typedef reverse_bidirectional_iterator self; protected: BidirectionalIterator current; public: typedef bidirectional_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef Reference reference; reverse_bidirectional_iterator() {} explicit reverse_bidirectional_iterator(BidirectionalIterator x) : current(x) {} BidirectionalIterator base() const { return current; } Reference operator*() const { BidirectionalIterator tmp = current; return *--tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ self& operator++() { --current; return *this; } self operator++(int) { self tmp = *this; --current; return tmp; } self& operator--() { ++current; return *this; } self operator--(int) { self tmp = *this; ++current; return tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline bidirectional_iterator_tag iterator_category(const reverse_bidirectional_iterator&) { return bidirectional_iterator_tag(); } template inline T* value_type(const reverse_bidirectional_iterator&) { return (T*) 0; } template inline Distance* distance_type(const reverse_bidirectional_iterator&) { return (Distance*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline bool operator==( const reverse_bidirectional_iterator& x, const reverse_bidirectional_iterator& y) { return x.base() == y.base(); } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION // This is the new version of reverse_iterator, as defined in the // draft C++ standard. It relies on the iterator_traits template, // which in turn relies on partial specialization. The class // reverse_bidirectional_iterator is no longer part of the draft // standard, but it is retained for backward compatibility. template class reverse_iterator { protected: Iterator current; public: typedef typename iterator_traits::iterator_category iterator_category; typedef typename iterator_traits::value_type value_type; typedef typename iterator_traits::difference_type difference_type; typedef typename iterator_traits::pointer pointer; typedef typename iterator_traits::reference reference; typedef Iterator iterator_type; typedef reverse_iterator self; public: reverse_iterator() {} explicit reverse_iterator(iterator_type x) : current(x) {} reverse_iterator(const self& x) : current(x.current) {} #ifdef __STL_MEMBER_TEMPLATES template reverse_iterator(const reverse_iterator& x) : current(x.current) {} #endif /* __STL_MEMBER_TEMPLATES */ iterator_type base() const { return current; } reference operator*() const { Iterator tmp = current; return *--tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ self& operator++() { --current; return *this; } self operator++(int) { self tmp = *this; --current; return tmp; } self& operator--() { ++current; return *this; } self operator--(int) { self tmp = *this; ++current; return tmp; } self operator+(difference_type n) const { return self(current - n); } self& operator+=(difference_type n) { current -= n; return *this; } self operator-(difference_type n) const { return self(current + n); } self& operator-=(difference_type n) { current += n; return *this; } reference operator[](difference_type n) const { return *(*this + n); } }; template inline bool operator==(const reverse_iterator& x, const reverse_iterator& y) { return x.base() == y.base(); } template inline bool operator<(const reverse_iterator& x, const reverse_iterator& y) { return y.base() < x.base(); } template inline typename reverse_iterator::difference_type operator-(const reverse_iterator& x, const reverse_iterator& y) { return y.base() - x.base(); } template inline reverse_iterator operator+(reverse_iterator::difference_type n, const reverse_iterator& x) { return reverse_iterator(x.base() - n); } #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // This is the old version of reverse_iterator, as found in the original // HP STL. It does not use partial specialization. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template #else template #endif class reverse_iterator { typedef reverse_iterator self; protected: RandomAccessIterator current; public: typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef Reference reference; reverse_iterator() {} explicit reverse_iterator(RandomAccessIterator x) : current(x) {} RandomAccessIterator base() const { return current; } Reference operator*() const { return *(current - 1); } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ self& operator++() { --current; return *this; } self operator++(int) { self tmp = *this; --current; return tmp; } self& operator--() { ++current; return *this; } self operator--(int) { self tmp = *this; ++current; return tmp; } self operator+(Distance n) const { return self(current - n); } self& operator+=(Distance n) { current -= n; return *this; } self operator-(Distance n) const { return self(current + n); } self& operator-=(Distance n) { current += n; return *this; } Reference operator[](Distance n) const { return *(*this + n); } }; template inline random_access_iterator_tag iterator_category(const reverse_iterator&) { return random_access_iterator_tag(); } template inline T* value_type(const reverse_iterator&) { return (T*) 0; } template inline Distance* distance_type(const reverse_iterator&) { return (Distance*) 0; } template inline bool operator==(const reverse_iterator& x, const reverse_iterator& y) { return x.base() == y.base(); } template inline bool operator<(const reverse_iterator& x, const reverse_iterator& y) { return y.base() < x.base(); } template inline Distance operator-(const reverse_iterator& x, const reverse_iterator& y) { return y.base() - x.base(); } template inline reverse_iterator operator+(Dist n, const reverse_iterator& x) { return reverse_iterator(x.base() - n); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template class istream_iterator { friend bool operator== __STL_NULL_TMPL_ARGS (const istream_iterator& x, const istream_iterator& y); protected: istream* stream; T value; bool end_marker; void read() { end_marker = (*stream) ? true : false; if (end_marker) *stream >> value; end_marker = (*stream) ? true : false; } public: typedef input_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef const T* pointer; typedef const T& reference; istream_iterator() : stream(&cin), end_marker(false) {} istream_iterator(istream& s) : stream(&s) { read(); } reference operator*() const { return value; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ istream_iterator& operator++() { read(); return *this; } istream_iterator operator++(int) { istream_iterator tmp = *this; read(); return tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline input_iterator_tag iterator_category(const istream_iterator&) { return input_iterator_tag(); } template inline T* value_type(const istream_iterator&) { return (T*) 0; } template inline Distance* distance_type(const istream_iterator&) { return (Distance*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline bool operator==(const istream_iterator& x, const istream_iterator& y) { return x.stream == y.stream && x.end_marker == y.end_marker || x.end_marker == false && y.end_marker == false; } template class ostream_iterator { protected: ostream* stream; const char* string; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; ostream_iterator(ostream& s) : stream(&s), string(0) {} ostream_iterator(ostream& s, const char* c) : stream(&s), string(c) {} ostream_iterator& operator=(const T& value) { *stream << value; if (string) *stream << string; return *this; } ostream_iterator& operator*() { return *this; } ostream_iterator& operator++() { return *this; } ostream_iterator& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const ostream_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ITERATOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_list.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_LIST_H #define __SGI_STL_INTERNAL_LIST_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif template struct __list_node { typedef void* void_pointer; void_pointer next; void_pointer prev; T data; }; template struct __list_iterator { typedef __list_iterator iterator; typedef __list_iterator const_iterator; typedef __list_iterator self; typedef bidirectional_iterator_tag iterator_category; typedef T value_type; typedef Ptr pointer; typedef Ref reference; typedef __list_node* link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; link_type node; __list_iterator(link_type x) : node(x) {} __list_iterator() {} __list_iterator(const iterator& x) : node(x.node) {} bool operator==(const self& x) const { return node == x.node; } bool operator!=(const self& x) const { return node != x.node; } reference operator*() const { return (*node).data; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ self& operator++() { node = (link_type)((*node).next); return *this; } self operator++(int) { self tmp = *this; ++*this; return tmp; } self& operator--() { node = (link_type)((*node).prev); return *this; } self operator--(int) { self tmp = *this; --*this; return tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline bidirectional_iterator_tag iterator_category(const __list_iterator&) { return bidirectional_iterator_tag(); } template inline T* value_type(const __list_iterator&) { return 0; } template inline ptrdiff_t* distance_type(const __list_iterator&) { return 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template class list { protected: typedef void* void_pointer; typedef __list_node list_node; typedef simple_alloc list_node_allocator; public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef list_node* link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; public: typedef __list_iterator iterator; typedef __list_iterator const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_bidirectional_iterator const_reverse_iterator; typedef reverse_bidirectional_iterator reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: link_type get_node() { return list_node_allocator::allocate(); } void put_node(link_type p) { list_node_allocator::deallocate(p); } link_type create_node(const T& x) { link_type p = get_node(); __STL_TRY { construct(&p->data, x); } __STL_UNWIND(put_node(p)); return p; } void destroy_node(link_type p) { destroy(&p->data); put_node(p); } protected: void empty_initialize() { node = get_node(); node->next = node; node->prev = node; } void fill_initialize(size_type n, const T& value) { empty_initialize(); __STL_TRY { insert(begin(), n, value); } __STL_UNWIND(clear(); put_node(node)); } #ifdef __STL_MEMBER_TEMPLATES template void range_initialize(InputIterator first, InputIterator last) { empty_initialize(); __STL_TRY { insert(begin(), first, last); } __STL_UNWIND(clear(); put_node(node)); } #else /* __STL_MEMBER_TEMPLATES */ void range_initialize(const T* first, const T* last) { empty_initialize(); __STL_TRY { insert(begin(), first, last); } __STL_UNWIND(clear(); put_node(node)); } void range_initialize(const_iterator first, const_iterator last) { empty_initialize(); __STL_TRY { insert(begin(), first, last); } __STL_UNWIND(clear(); put_node(node)); } #endif /* __STL_MEMBER_TEMPLATES */ protected: link_type node; public: list() { empty_initialize(); } iterator begin() { return (link_type)((*node).next); } const_iterator begin() const { return (link_type)((*node).next); } iterator end() { return node; } const_iterator end() const { return node; } 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 node->next == node; } size_type size() const { size_type result = 0; distance(begin(), end(), result); return result; } size_type max_size() const { return size_type(-1); } reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(--end()); } const_reference back() const { return *(--end()); } void swap(list& x) { __STD::swap(node, x.node); } iterator insert(iterator position, const T& x) { link_type tmp = create_node(x); tmp->next = position.node; tmp->prev = position.node->prev; (link_type(position.node->prev))->next = tmp; position.node->prev = tmp; return tmp; } iterator insert(iterator position) { return insert(position, T()); } #ifdef __STL_MEMBER_TEMPLATES template void insert(iterator position, InputIterator first, InputIterator last); #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator position, const T* first, const T* last); void insert(iterator position, const_iterator first, const_iterator last); #endif /* __STL_MEMBER_TEMPLATES */ void insert(iterator pos, size_type n, const T& x); void insert(iterator pos, int n, const T& x) { insert(pos, (size_type)n, x); } void insert(iterator pos, long n, const T& x) { insert(pos, (size_type)n, x); } void push_front(const T& x) { insert(begin(), x); } void push_back(const T& x) { insert(end(), x); } iterator erase(iterator position) { link_type next_node = link_type(position.node->next); link_type prev_node = link_type(position.node->prev); prev_node->next = next_node; next_node->prev = prev_node; destroy_node(position.node); return iterator(next_node); } iterator erase(iterator first, iterator last); void resize(size_type new_size, const T& x); void resize(size_type new_size) { resize(new_size, T()); } void clear(); void pop_front() { erase(begin()); } void pop_back() { iterator tmp = end(); erase(--tmp); } list(size_type n, const T& value) { fill_initialize(n, value); } list(int n, const T& value) { fill_initialize(n, value); } list(long n, const T& value) { fill_initialize(n, value); } explicit list(size_type n) { fill_initialize(n, T()); } #ifdef __STL_MEMBER_TEMPLATES template list(InputIterator first, InputIterator last) { range_initialize(first, last); } #else /* __STL_MEMBER_TEMPLATES */ list(const T* first, const T* last) { range_initialize(first, last); } list(const_iterator first, const_iterator last) { range_initialize(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ list(const list& x) { range_initialize(x.begin(), x.end()); } ~list() { clear(); put_node(node); } list& operator=(const list& x); protected: void transfer(iterator position, iterator first, iterator last) { if (position != last) { (*(link_type((*last.node).prev))).next = position.node; (*(link_type((*first.node).prev))).next = last.node; (*(link_type((*position.node).prev))).next = first.node; link_type tmp = link_type((*position.node).prev); (*position.node).prev = (*last.node).prev; (*last.node).prev = (*first.node).prev; (*first.node).prev = tmp; } } public: void splice(iterator position, list& x) { if (!x.empty()) transfer(position, x.begin(), x.end()); } void splice(iterator position, list&, iterator i) { iterator j = i; ++j; if (position == i || position == j) return; transfer(position, i, j); } void splice(iterator position, list&, iterator first, iterator last) { if (first != last) transfer(position, first, last); } void remove(const T& value); void unique(); void merge(list& x); void reverse(); void sort(); #ifdef __STL_MEMBER_TEMPLATES template void remove_if(Predicate); template void unique(BinaryPredicate); template void merge(list&, StrictWeakOrdering); template void sort(StrictWeakOrdering); #endif /* __STL_MEMBER_TEMPLATES */ friend bool operator== __STL_NULL_TMPL_ARGS (const list& x, const list& y); }; template inline bool operator==(const list& x, const list& y) { typedef typename list::link_type link_type; link_type e1 = x.node; link_type e2 = y.node; link_type n1 = (link_type) e1->next; link_type n2 = (link_type) e2->next; for ( ; n1 != e1 && n2 != e2 ; n1 = (link_type) n1->next, n2 = (link_type) n2->next) if (n1->data != n2->data) return false; return n1 == e1 && n2 == e2; } template inline bool operator<(const list& x, const list& y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(list& x, list& y) { x.swap(y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifdef __STL_MEMBER_TEMPLATES template template void list::insert(iterator position, InputIterator first, InputIterator last) { for ( ; first != last; ++first) insert(position, *first); } #else /* __STL_MEMBER_TEMPLATES */ template void list::insert(iterator position, const T* first, const T* last) { for ( ; first != last; ++first) insert(position, *first); } template void list::insert(iterator position, const_iterator first, const_iterator last) { for ( ; first != last; ++first) insert(position, *first); } #endif /* __STL_MEMBER_TEMPLATES */ template void list::insert(iterator position, size_type n, const T& x) { for ( ; n > 0; --n) insert(position, x); } template list::iterator list::erase(iterator first, iterator last) { while (first != last) erase(first++); return last; } template void list::resize(size_type new_size, const T& 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 void list::clear() { link_type cur = (link_type) node->next; while (cur != node) { link_type tmp = cur; cur = (link_type) cur->next; destroy_node(tmp); } node->next = node; node->prev = node; } template list& list::operator=(const list& x) { if (this != &x) { iterator first1 = begin(); iterator last1 = end(); const_iterator first2 = x.begin(); const_iterator last2 = x.end(); while (first1 != last1 && first2 != last2) *first1++ = *first2++; if (first2 == last2) erase(first1, last1); else insert(last1, first2, last2); } return *this; } template void list::remove(const T& value) { iterator first = begin(); iterator last = end(); while (first != last) { iterator next = first; ++next; if (*first == value) erase(first); first = next; } } template void list::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 void list::merge(list& 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; transfer(first1, first2, ++next); first2 = next; } else ++first1; if (first2 != last2) transfer(last1, first2, last2); } template void list::reverse() { if (node->next == node || link_type(node->next)->next == node) return; iterator first = begin(); ++first; while (first != end()) { iterator old = first; ++first; transfer(begin(), old, first); } } template void list::sort() { if (node->next == node || link_type(node->next)->next == node) return; list carry; list counter[64]; int fill = 0; while (!empty()) { carry.splice(carry.begin(), *this, begin()); int i = 0; while(i < fill && !counter[i].empty()) { counter[i].merge(carry); carry.swap(counter[i++]); } carry.swap(counter[i]); if (i == fill) ++fill; } for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]); swap(counter[fill-1]); } #ifdef __STL_MEMBER_TEMPLATES template template void list::remove_if(Predicate pred) { iterator first = begin(); iterator last = end(); while (first != last) { iterator next = first; ++next; if (pred(*first)) erase(first); first = next; } } template template void list::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; } } template template void list::merge(list& x, StrictWeakOrdering comp) { 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; transfer(first1, first2, ++next); first2 = next; } else ++first1; if (first2 != last2) transfer(last1, first2, last2); } template template void list::sort(StrictWeakOrdering comp) { if (node->next == node || link_type(node->next)->next == node) return; list carry; list counter[64]; int fill = 0; while (!empty()) { carry.splice(carry.begin(), *this, begin()); int i = 0; while(i < fill && !counter[i].empty()) { counter[i].merge(carry, comp); carry.swap(counter[i++]); } carry.swap(counter[i]); if (i == fill) ++fill; } for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1], comp); swap(counter[fill-1]); } #endif /* __STL_MEMBER_TEMPLATES */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_LIST_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_map.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_MAP_H #define __SGI_STL_INTERNAL_MAP_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template , class Alloc = alloc> #else template #endif class map { public: // typedefs: typedef Key key_type; typedef T data_type; typedef T mapped_type; typedef pair value_type; typedef Compare key_compare; class value_compare : public binary_function { friend class map; 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: typedef rb_tree, key_compare, Alloc> rep_type; rep_type t; // red-black tree representing map public: typedef typename rep_type::pointer pointer; typedef typename rep_type::const_pointer const_pointer; typedef typename rep_type::reference reference; typedef typename rep_type::const_reference const_reference; typedef typename rep_type::iterator iterator; typedef typename rep_type::const_iterator const_iterator; typedef typename rep_type::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 map() : t(Compare()) {} explicit map(const Compare& comp) : t(comp) {} #ifdef __STL_MEMBER_TEMPLATES template map(InputIterator first, InputIterator last) : t(Compare()) { t.insert_unique(first, last); } template map(InputIterator first, InputIterator last, const Compare& comp) : t(comp) { t.insert_unique(first, last); } #else map(const value_type* first, const value_type* last) : t(Compare()) { t.insert_unique(first, last); } map(const value_type* first, const value_type* last, const Compare& comp) : t(comp) { t.insert_unique(first, last); } map(const_iterator first, const_iterator last) : t(Compare()) { t.insert_unique(first, last); } map(const_iterator first, const_iterator last, const Compare& comp) : t(comp) { t.insert_unique(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ map(const map& x) : t(x.t) {} map& operator=(const map& x) { t = x.t; return *this; } // accessors: key_compare key_comp() const { return t.key_comp(); } value_compare value_comp() const { return value_compare(t.key_comp()); } iterator begin() { return t.begin(); } const_iterator begin() const { return t.begin(); } iterator end() { return t.end(); } const_iterator end() const { return t.end(); } reverse_iterator rbegin() { return t.rbegin(); } const_reverse_iterator rbegin() const { return t.rbegin(); } reverse_iterator rend() { return t.rend(); } const_reverse_iterator rend() const { return t.rend(); } bool empty() const { return t.empty(); } size_type size() const { return t.size(); } size_type max_size() const { return t.max_size(); } T& operator[](const key_type& k) { return (*((insert(value_type(k, T()))).first)).second; } void swap(map& x) { t.swap(x.t); } // insert/erase pair insert(const value_type& x) { return t.insert_unique(x); } iterator insert(iterator position, const value_type& x) { return t.insert_unique(position, x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(InputIterator first, InputIterator last) { t.insert_unique(first, last); } #else void insert(const value_type* first, const value_type* last) { t.insert_unique(first, last); } void insert(const_iterator first, const_iterator last) { t.insert_unique(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator position) { t.erase(position); } size_type erase(const key_type& x) { return t.erase(x); } void erase(iterator first, iterator last) { t.erase(first, last); } void clear() { t.clear(); } // map operations: iterator find(const key_type& x) { return t.find(x); } const_iterator find(const key_type& x) const { return t.find(x); } size_type count(const key_type& x) const { return t.count(x); } iterator lower_bound(const key_type& x) {return t.lower_bound(x); } const_iterator lower_bound(const key_type& x) const { return t.lower_bound(x); } iterator upper_bound(const key_type& x) {return t.upper_bound(x); } const_iterator upper_bound(const key_type& x) const { return t.upper_bound(x); } pair equal_range(const key_type& x) { return t.equal_range(x); } pair equal_range(const key_type& x) const { return t.equal_range(x); } friend bool operator== __STL_NULL_TMPL_ARGS (const map&, const map&); friend bool operator< __STL_NULL_TMPL_ARGS (const map&, const map&); }; template inline bool operator==(const map& x, const map& y) { return x.t == y.t; } template inline bool operator<(const map& x, const map& y) { return x.t < y.t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(map& x, map& y) { x.swap(y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_MAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_multimap.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_MULTIMAP_H #define __SGI_STL_INTERNAL_MULTIMAP_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template , class Alloc = alloc> #else template #endif class multimap { public: // typedefs: typedef Key key_type; typedef T data_type; typedef T mapped_type; typedef pair value_type; typedef Compare key_compare; class value_compare : public binary_function { friend class multimap; 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: typedef rb_tree, key_compare, Alloc> rep_type; rep_type t; // red-black tree representing multimap public: typedef typename rep_type::pointer pointer; typedef typename rep_type::const_pointer const_pointer; typedef typename rep_type::reference reference; typedef typename rep_type::const_reference const_reference; typedef typename rep_type::iterator iterator; typedef typename rep_type::const_iterator const_iterator; typedef typename rep_type::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 multimap() : t(Compare()) { } explicit multimap(const Compare& comp) : t(comp) { } #ifdef __STL_MEMBER_TEMPLATES template multimap(InputIterator first, InputIterator last) : t(Compare()) { t.insert_equal(first, last); } template multimap(InputIterator first, InputIterator last, const Compare& comp) : t(comp) { t.insert_equal(first, last); } #else multimap(const value_type* first, const value_type* last) : t(Compare()) { t.insert_equal(first, last); } multimap(const value_type* first, const value_type* last, const Compare& comp) : t(comp) { t.insert_equal(first, last); } multimap(const_iterator first, const_iterator last) : t(Compare()) { t.insert_equal(first, last); } multimap(const_iterator first, const_iterator last, const Compare& comp) : t(comp) { t.insert_equal(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ multimap(const multimap& x) : t(x.t) { } multimap& operator=(const multimap& x) { t = x.t; return *this; } // accessors: key_compare key_comp() const { return t.key_comp(); } value_compare value_comp() const { return value_compare(t.key_comp()); } iterator begin() { return t.begin(); } const_iterator begin() const { return t.begin(); } iterator end() { return t.end(); } const_iterator end() const { return t.end(); } reverse_iterator rbegin() { return t.rbegin(); } const_reverse_iterator rbegin() const { return t.rbegin(); } reverse_iterator rend() { return t.rend(); } const_reverse_iterator rend() const { return t.rend(); } bool empty() const { return t.empty(); } size_type size() const { return t.size(); } size_type max_size() const { return t.max_size(); } void swap(multimap& x) { t.swap(x.t); } // insert/erase iterator insert(const value_type& x) { return t.insert_equal(x); } iterator insert(iterator position, const value_type& x) { return t.insert_equal(position, x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(InputIterator first, InputIterator last) { t.insert_equal(first, last); } #else void insert(const value_type* first, const value_type* last) { t.insert_equal(first, last); } void insert(const_iterator first, const_iterator last) { t.insert_equal(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator position) { t.erase(position); } size_type erase(const key_type& x) { return t.erase(x); } void erase(iterator first, iterator last) { t.erase(first, last); } void clear() { t.clear(); } // multimap operations: iterator find(const key_type& x) { return t.find(x); } const_iterator find(const key_type& x) const { return t.find(x); } size_type count(const key_type& x) const { return t.count(x); } iterator lower_bound(const key_type& x) {return t.lower_bound(x); } const_iterator lower_bound(const key_type& x) const { return t.lower_bound(x); } iterator upper_bound(const key_type& x) {return t.upper_bound(x); } const_iterator upper_bound(const key_type& x) const { return t.upper_bound(x); } pair equal_range(const key_type& x) { return t.equal_range(x); } pair equal_range(const key_type& x) const { return t.equal_range(x); } friend bool operator== __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); friend bool operator< __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); }; template inline bool operator==(const multimap& x, const multimap& y) { return x.t == y.t; } template inline bool operator<(const multimap& x, const multimap& y) { return x.t < y.t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(multimap& x, multimap& y) { x.swap(y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_MULTIMAP_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_multiset.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_MULTISET_H #define __SGI_STL_INTERNAL_MULTISET_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template , class Alloc = alloc> #else template #endif class multiset { public: // typedefs: typedef Key key_type; typedef Key value_type; typedef Compare key_compare; typedef Compare value_compare; private: typedef rb_tree, key_compare, Alloc> rep_type; rep_type t; // red-black tree representing multiset public: typedef typename rep_type::const_pointer pointer; typedef typename rep_type::const_pointer const_pointer; typedef typename rep_type::const_reference reference; typedef typename rep_type::const_reference const_reference; 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 multiset() : t(Compare()) {} explicit multiset(const Compare& comp) : t(comp) {} #ifdef __STL_MEMBER_TEMPLATES template multiset(InputIterator first, InputIterator last) : t(Compare()) { t.insert_equal(first, last); } template multiset(InputIterator first, InputIterator last, const Compare& comp) : t(comp) { t.insert_equal(first, last); } #else multiset(const value_type* first, const value_type* last) : t(Compare()) { t.insert_equal(first, last); } multiset(const value_type* first, const value_type* last, const Compare& comp) : t(comp) { t.insert_equal(first, last); } multiset(const_iterator first, const_iterator last) : t(Compare()) { t.insert_equal(first, last); } multiset(const_iterator first, const_iterator last, const Compare& comp) : t(comp) { t.insert_equal(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ multiset(const multiset& x) : t(x.t) {} multiset& operator=(const multiset& x) { t = x.t; return *this; } // accessors: key_compare key_comp() const { return t.key_comp(); } value_compare value_comp() const { return t.key_comp(); } iterator begin() const { return t.begin(); } iterator end() const { return t.end(); } reverse_iterator rbegin() const { return t.rbegin(); } reverse_iterator rend() const { return t.rend(); } bool empty() const { return t.empty(); } size_type size() const { return t.size(); } size_type max_size() const { return t.max_size(); } void swap(multiset& x) { t.swap(x.t); } // insert/erase iterator insert(const value_type& x) { return t.insert_equal(x); } iterator insert(iterator position, const value_type& x) { typedef typename rep_type::iterator rep_iterator; return t.insert_equal((rep_iterator&)position, x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(InputIterator first, InputIterator last) { t.insert_equal(first, last); } #else void insert(const value_type* first, const value_type* last) { t.insert_equal(first, last); } void insert(const_iterator first, const_iterator last) { t.insert_equal(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator position) { typedef typename rep_type::iterator rep_iterator; t.erase((rep_iterator&)position); } size_type erase(const key_type& x) { return t.erase(x); } void erase(iterator first, iterator last) { typedef typename rep_type::iterator rep_iterator; t.erase((rep_iterator&)first, (rep_iterator&)last); } void clear() { t.clear(); } // multiset operations: iterator find(const key_type& x) const { return t.find(x); } size_type count(const key_type& x) const { return t.count(x); } iterator lower_bound(const key_type& x) const { return t.lower_bound(x); } iterator upper_bound(const key_type& x) const { return t.upper_bound(x); } pair equal_range(const key_type& x) const { return t.equal_range(x); } friend bool operator== __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); friend bool operator< __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); }; template inline bool operator==(const multiset& x, const multiset& y) { return x.t == y.t; } template inline bool operator<(const multiset& x, const multiset& y) { return x.t < y.t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(multiset& x, multiset& y) { x.swap(y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_MULTISET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_numeric.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_NUMERIC_H #define __SGI_STL_INTERNAL_NUMERIC_H __STL_BEGIN_NAMESPACE template T accumulate(InputIterator first, InputIterator last, T init) { for ( ; first != last; ++first) init = init + *first; return init; } template T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op) { for ( ; first != last; ++first) init = binary_op(init, *first); return init; } template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init) { for ( ; first1 != last1; ++first1, ++first2) init = init + (*first1 * *first2); return init; } template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2) { for ( ; first1 != last1; ++first1, ++first2) init = binary_op1(init, binary_op2(*first1, *first2)); return init; } template OutputIterator __partial_sum(InputIterator first, InputIterator last, OutputIterator result, T*) { T value = *first; while (++first != last) { value = value + *first; *++result = value; } return ++result; } template OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result) { if (first == last) return result; *result = *first; return __partial_sum(first, last, result, value_type(first)); } template OutputIterator __partial_sum(InputIterator first, InputIterator last, OutputIterator result, T*, BinaryOperation binary_op) { T value = *first; while (++first != last) { value = binary_op(value, *first); *++result = value; } return ++result; } template OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op) { if (first == last) return result; *result = *first; return __partial_sum(first, last, result, value_type(first), binary_op); } template OutputIterator __adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, T*) { T value = *first; while (++first != last) { T tmp = *first; *++result = tmp - value; value = tmp; } return ++result; } template OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result) { if (first == last) return result; *result = *first; return __adjacent_difference(first, last, result, value_type(first)); } template OutputIterator __adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, T*, BinaryOperation binary_op) { T value = *first; while (++first != last) { T tmp = *first; *++result = binary_op(tmp, value); value = tmp; } return ++result; } template OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op) { if (first == last) return result; *result = *first; return __adjacent_difference(first, last, result, value_type(first), binary_op); } // Returns x ** n, where n >= 0. Note that "multiplication" // is required to be associative, but not necessarily commutative. template T power(T x, Integer n, MonoidOperation op) { if (n == 0) return identity_element(op); else { while ((n & 1) == 0) { n >>= 1; x = op(x, x); } T result = x; n >>= 1; while (n != 0) { x = op(x, x); if ((n & 1) != 0) result = op(result, x); n >>= 1; } return result; } } template inline T power(T x, Integer n) { return power(x, n, multiplies()); } template void iota(ForwardIterator first, ForwardIterator last, T value) { while (first != last) *first++ = value++; } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_NUMERIC_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_pair.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_PAIR_H #define __SGI_STL_INTERNAL_PAIR_H __STL_BEGIN_NAMESPACE template struct pair { typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair() : first(T1()), second(T2()) {} pair(const T1& a, const T2& b) : first(a), second(b) {} #ifdef __STL_MEMBER_TEMPLATES template pair(const pair& p) : first(p.first), second(p.second) {} #endif }; template inline bool operator==(const pair& x, const pair& y) { return x.first == y.first && x.second == y.second; } template inline bool operator<(const pair& x, const pair& y) { return x.first < y.first || (!(y.first < x.first) && x.second < y.second); } template inline pair make_pair(const T1& x, const T2& y) { return pair(x, y); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_PAIR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_queue.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_QUEUE_H #define __SGI_STL_INTERNAL_QUEUE_H __STL_BEGIN_NAMESPACE #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template > #else template #endif class queue { friend bool operator== __STL_NULL_TMPL_ARGS (const queue& x, const queue& y); friend bool operator< __STL_NULL_TMPL_ARGS (const queue& x, const queue& y); public: typedef typename Sequence::value_type value_type; typedef typename Sequence::size_type size_type; typedef typename Sequence::reference reference; typedef typename Sequence::const_reference const_reference; protected: Sequence c; public: bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference front() { return c.front(); } const_reference front() const { return c.front(); } reference back() { return c.back(); } const_reference back() const { return c.back(); } void push(const value_type& x) { c.push_back(x); } void pop() { c.pop_front(); } }; template bool operator==(const queue& x, const queue& y) { return x.c == y.c; } template bool operator<(const queue& x, const queue& y) { return x.c < y.c; } #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template , class Compare = less > #else template #endif class priority_queue { public: typedef typename Sequence::value_type value_type; typedef typename Sequence::size_type size_type; typedef typename Sequence::reference reference; typedef typename Sequence::const_reference const_reference; protected: Sequence c; Compare comp; public: priority_queue() : c() {} explicit priority_queue(const Compare& x) : c(), comp(x) {} #ifdef __STL_MEMBER_TEMPLATES template priority_queue(InputIterator first, InputIterator last, const Compare& x) : c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); } template priority_queue(InputIterator first, InputIterator last) : c(first, last) { make_heap(c.begin(), c.end(), comp); } #else /* __STL_MEMBER_TEMPLATES */ priority_queue(const value_type* first, const value_type* last, const Compare& x) : c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); } priority_queue(const value_type* first, const value_type* last) : c(first, last) { make_heap(c.begin(), c.end(), comp); } #endif /* __STL_MEMBER_TEMPLATES */ bool empty() const { return c.empty(); } size_type size() const { return c.size(); } const_reference top() const { return c.front(); } void push(const value_type& x) { __STL_TRY { c.push_back(x); push_heap(c.begin(), c.end(), comp); } __STL_UNWIND(c.clear()); } void pop() { __STL_TRY { pop_heap(c.begin(), c.end(), comp); c.pop_back(); } __STL_UNWIND(c.clear()); } }; // no equality is provided __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_QUEUE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_raw_storage_iter.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H #define __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H __STL_BEGIN_NAMESPACE template class raw_storage_iterator { protected: ForwardIterator iter; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit raw_storage_iterator(ForwardIterator x) : iter(x) {} raw_storage_iterator& operator*() { return *this; } raw_storage_iterator& operator=(const T& element) { construct(&*iter, element); return *this; } raw_storage_iterator& operator++() { ++iter; return *this; } raw_storage_iterator operator++(int) { raw_storage_iterator tmp = *this; ++iter; return tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const raw_storage_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ #endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */ __STL_END_NAMESPACE // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_relops.h ================================================ /* * * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_RELOPS #define __SGI_STL_INTERNAL_RELOPS __STL_BEGIN_RELOPS_NAMESPACE template inline bool operator!=(const T& x, const T& y) { return !(x == y); } template inline bool operator>(const T& x, const T& y) { return y < x; } template inline bool operator<=(const T& x, const T& y) { return !(y < x); } template inline bool operator>=(const T& x, const T& y) { return !(x < y); } __STL_END_RELOPS_NAMESPACE #endif /* __SGI_STL_INTERNAL_RELOPS */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_rope.h ================================================ /* * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_ROPE_H # define __SGI_STL_INTERNAL_ROPE_H # ifdef __GC # define __GC_CONST const # else # define __GC_CONST // constant except for deallocation # endif # ifdef __STL_SGI_THREADS # include # endif __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif // The end-of-C-string character. // This is what the draft standard says it should be. template inline charT __eos(charT*) { return charT(); } // Test for basic character types. // For basic character types leaves having a trailing eos. template inline bool __is_basic_char_type(charT *) { return false; } template inline bool __is_one_byte_char_type(charT *) { return false; } inline bool __is_basic_char_type(char *) { return true; } inline bool __is_one_byte_char_type(char *) { return true; } inline bool __is_basic_char_type(wchar_t *) { return true; } // Store an eos iff charT is a basic character type. // Do not reference __eos if it isn't. template inline void __cond_store_eos(charT&) {} inline void __cond_store_eos(char& c) { c = 0; } inline void __cond_store_eos(wchar_t& c) { c = 0; } // rope is a sequence of charT. // Ropes appear to be mutable, but update operations // really copy enough of the data structure to leave the original // valid. Thus ropes can be logically copied by just copying // a pointer value. // The __eos function is used for those functions that // convert to/from C-like strings to detect the end of the string. // __compare is used as the character comparison function. template 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 // 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 and a // little like containers. template // The 3rd parameter works around a common compiler bug. class sequence_buffer : public output_iterator { public: # ifndef __TYPEDEF_WORKAROUND typedef typename sequence::value_type value_type; # else typedef v value_type; # endif protected: sequence *prefix; value_type buffer[buf_sz]; size_t buf_count; public: void flush() { prefix->append(buffer, buffer + buf_count); buf_count = 0; } ~sequence_buffer() { flush(); } sequence_buffer() : prefix(0), buf_count(0) {} sequence_buffer(const sequence_buffer & x) { prefix = x.prefix; buf_count = x.buf_count; copy(x.buffer, x.buffer + x.buf_count, buffer); } sequence_buffer(sequence_buffer & x) { x.flush(); prefix = x.prefix; buf_count = 0; } sequence_buffer(sequence& s) : prefix(&s), buf_count(0) {} sequence_buffer& operator= (sequence_buffer& x) { x.flush(); prefix = x.prefix; buf_count = 0; return *this; } sequence_buffer& operator= (const sequence_buffer& x) { prefix = x.prefix; buf_count = x.buf_count; copy(x.buffer, x.buffer + x.buf_count, buffer); return *this; } void push_back(value_type x) { if (buf_count < buf_sz) { buffer[buf_count] = x; ++buf_count; } else { flush(); buffer[0] = x; buf_count = 1; } } void append(value_type *s, size_t len) { if (len + buf_count <= buf_sz) { size_t i, j; for (i = buf_count, j = 0; j < len; i++, j++) { buffer[i] = s[j]; } buf_count += len; } else if (0 == buf_count) { 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 __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; }; // // 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 occurence 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. // template class rope; template struct __rope_RopeConcatenation; template struct __rope_RopeLeaf; template struct __rope_RopeFunction; template struct __rope_RopeSubstring; template class __rope_iterator; template class __rope_const_iterator; template class __rope_charT_ref_proxy; template class __rope_charT_ptr_proxy; // // 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 RopeBase. Most of the more complex algorithms // are implemented as rope members. // // Some of the static member functions of RopeBase have identically // named functions in rope that simply invoke the RopeBase versions. // template struct __rope_RopeBase { typedef rope my_rope; typedef simple_alloc DataAlloc; typedef simple_alloc<__rope_RopeConcatenation, Alloc> CAlloc; typedef simple_alloc<__rope_RopeLeaf, Alloc> LAlloc; typedef simple_alloc<__rope_RopeFunction, Alloc> FAlloc; typedef simple_alloc<__rope_RopeSubstring, Alloc> SAlloc; public: enum { max_rope_depth = 45 }; enum {leaf, concat, substringfn, function} tag:8; bool is_balanced:8; unsigned char depth; size_t size; __GC_CONST charT * c_string; /* 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. */ # ifndef __GC # if defined(__STL_WIN32THREADS) long refcount; // InterlockedIncrement wants a long * # else size_t refcount; # endif // We count references from rope instances // and references from other rope nodes. We // do not count const_iterator references. // Iterator references are counted so that rope modifications // can be detected after the fact. // Generally function results are counted, i.e. // a pointer returned by a function is included at the // point at which the pointer is returned. // The recipient should decrement the count if the // result is not needed. // Generally function arguments are not reflected // in the reference count. The callee should increment // the count before saving the argument someplace that // will outlive the call. # endif # ifndef __GC # ifdef __STL_SGI_THREADS // Reference counting with multiple threads and no // hardware or thread package support is pretty awful. // Mutexes are normally too expensive. // We'll assume a COMPARE_AND_SWAP(destp, old, new) // operation, which might be cheaper. # if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) # define __add_and_fetch(l,v) add_then_test((unsigned long *)l,v) # endif void init_refcount_lock() {} void incr_refcount () { __add_and_fetch(&refcount, 1); } size_t decr_refcount () { return __add_and_fetch(&refcount, (size_t)(-1)); } # elif defined(__STL_WIN32THREADS) void init_refcount_lock() {} void incr_refcount () { InterlockedIncrement(&refcount); } size_t decr_refcount () { return InterlockedDecrement(&refcount); } # elif defined(__STL_PTHREADS) // This should be portable, but performance is expected // to be quite awful. This really needs platform specific // code. pthread_mutex_t refcount_lock; void init_refcount_lock() { pthread_mutex_init(&refcount_lock, 0); } void incr_refcount () { pthread_mutex_lock(&refcount_lock); ++refcount; pthread_mutex_unlock(&refcount_lock); } size_t decr_refcount () { size_t result; pthread_mutex_lock(&refcount_lock); result = --refcount; pthread_mutex_unlock(&refcount_lock); return result; } # else void init_refcount_lock() {} void incr_refcount () { ++refcount; } size_t decr_refcount () { --refcount; return refcount; } # endif # else void incr_refcount () {} # endif static void free_string(charT *, size_t len); // 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 free_c_string(); void free_tree(); // Deallocate t. Assumes t is not 0. void unref_nonnil() { if (0 == decr_refcount()) free_tree(); } void ref_nonnil() { incr_refcount(); } static void unref(__rope_RopeBase* t) { if (0 != t) { t -> unref_nonnil(); } } static void ref(__rope_RopeBase* t) { if (0 != t) t -> incr_refcount(); } static void free_if_unref(__rope_RopeBase* t) { if (0 != t && 0 == t -> refcount) t -> free_tree(); } # else /* __GC */ void unref_nonnil() {} void ref_nonnil() {} static void unref(__rope_RopeBase* t) {} static void ref(__rope_RopeBase* t) {} static void fn_finalization_proc(void * tree, void *); static void free_if_unref(__rope_RopeBase* t) {} # endif // The data fields of leaves are allocated with some // extra space, to accomodate future growth and for basic // character types, to hold a trailing eos character. enum { alloc_granularity = 8 }; static size_t rounded_up_size(size_t n) { size_t size_with_eos; if (__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 + alloc_granularity-1) &~ (alloc_granularity-1); # endif } }; template struct __rope_RopeLeaf : public __rope_RopeBase { public: // Apparently needed by VC++ __GC_CONST charT* data; /* Not necessarily 0 terminated. */ /* The allocated size is */ /* rounded_up_size(size), except */ /* in the GC case, in which it */ /* doesn't matter. */ }; template struct __rope_RopeConcatenation : public __rope_RopeBase { public: __rope_RopeBase* left; __rope_RopeBase* right; }; template struct __rope_RopeFunction : public __rope_RopeBase { public: char_producer* fn; # ifndef __GC bool 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. # endif }; // 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 struct __rope_RopeSubstring: public __rope_RopeFunction, public char_producer { public: __rope_RopeBase * base; // not 0 size_t start; virtual ~__rope_RopeSubstring() {} virtual void operator()(size_t start_pos, size_t req_len, charT *buffer) { switch(base -> tag) { case function: case substringfn: { char_producer *fn = ((__rope_RopeFunction *)base) -> fn; __stl_assert(start_pos + req_len <= size); __stl_assert(start + size <= base -> size); (*fn)(start_pos + start, req_len, buffer); } break; case leaf: { __GC_CONST charT * s = ((__rope_RopeLeaf *)base) -> data; uninitialized_copy_n(s + start_pos + start, req_len, buffer); } break; default: __stl_assert(false); } } __rope_RopeSubstring(__rope_RopeBase * b, size_t s, size_t l) : base(b), start(s) { # ifndef __GC refcount = 1; init_refcount_lock(); base -> ref_nonnil(); # endif size = l; tag = substringfn; depth = 0; c_string = 0; fn = this; } }; // Self-destructing pointers to RopeBase. // 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 struct __rope_self_destruct_ptr { __rope_RopeBase * ptr; ~__rope_self_destruct_ptr() { __rope_RopeBase::unref(ptr); } # ifdef __STL_USE_EXCEPTIONS __rope_self_destruct_ptr() : ptr(0) {}; # else __rope_self_destruct_ptr() {}; # endif __rope_self_destruct_ptr(__rope_RopeBase * p) : ptr(p) {} __rope_RopeBase & operator*() { return *ptr; } __rope_RopeBase * operator->() { return ptr; } operator __rope_RopeBase *() { return ptr; } __rope_self_destruct_ptr & operator= (__rope_RopeBase * x) { 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 __rope_charT_ref_proxy { friend class rope; friend class __rope_iterator; friend class __rope_charT_ptr_proxy; # ifdef __GC typedef __rope_RopeBase * self_destruct_ptr; # else typedef __rope_self_destruct_ptr self_destruct_ptr; # endif typedef __rope_RopeBase RopeBase; typedef rope my_rope; size_t pos; charT current; bool current_valid; my_rope * root; // The whole rope. public: __rope_charT_ref_proxy(my_rope * r, size_t p) : pos(p), root(r), current_valid(false) {} __rope_charT_ref_proxy(my_rope * r, size_t p, charT c) : pos(p), root(r), current(c), current_valid(true) {} operator charT () const; __rope_charT_ref_proxy& operator= (charT c); __rope_charT_ptr_proxy operator& () const; __rope_charT_ref_proxy& operator= (const __rope_charT_ref_proxy& c) { return operator=((charT)c); } }; template class __rope_charT_ptr_proxy { friend class __rope_charT_ref_proxy; size_t pos; charT current; bool current_valid; rope * root; // The whole rope. public: __rope_charT_ptr_proxy(const __rope_charT_ref_proxy & x) : pos(x.pos), root(x.root), current_valid(x.current_valid), current(x.current) {} __rope_charT_ptr_proxy(const __rope_charT_ptr_proxy & x) : pos(x.pos), root(x.root), current_valid(x.current_valid), current(x.current) {} __rope_charT_ptr_proxy() {} __rope_charT_ptr_proxy(charT * x) : root(0), pos(0) { __stl_assert(0 == x); } __rope_charT_ptr_proxy& operator= (const __rope_charT_ptr_proxy& x) { pos = x.pos; current = x.current; current_valid = x.current_valid; root = x.root; return *this; } friend bool operator== __STL_NULL_TMPL_ARGS (const __rope_charT_ptr_proxy & x, const __rope_charT_ptr_proxy & y); __rope_charT_ref_proxy operator *() const { if (current_valid) { return __rope_charT_ref_proxy(root, pos, current); } else { return __rope_charT_ref_proxy(root, 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. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1375 #endif template class __rope_iterator_base: public random_access_iterator { friend class rope; public: typedef __rope_RopeBase RopeBase; // Borland doesnt want this to be protected. protected: enum { path_cache_len = 4 }; // Must be <= 9. enum { iterator_buf_len = 15 }; size_t current_pos; RopeBase * root; // The whole rope. size_t leaf_pos; // Starting position for current leaf __GC_CONST charT * buf_start; // Buffer possibly // containing current char. __GC_CONST charT * buf_ptr; // Pointer to current char in buffer. // != 0 ==> buffer valid. __GC_CONST charT * 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 RopeBase * path_end[path_cache_len]; int leaf_index; // Last valid pos in path_end; // path_end[0] ... path_end[leaf_index-1] // point to concatenation nodes. unsigned char path_directions; // (path_directions >> i) & 1 is 1 // iff we got from path_end[leaf_index - i - 1] // to path_end[leaf_index - i] by going to the // right. Assumes path_cache_len <= 9. charT tmp_buf[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 setbuf(__rope_iterator_base &x); // Set buffer contents given // path cache. static void setcache(__rope_iterator_base &x); // Set buffer contents and // path cache. static void setcache_for_incr(__rope_iterator_base &x); // As above, but assumes path // cache is valid for previous posn. __rope_iterator_base() {} __rope_iterator_base(RopeBase * root, size_t pos): root(root), current_pos(pos), buf_ptr(0) {} __rope_iterator_base(const __rope_iterator_base& x) { if (0 != x.buf_ptr) { *this = x; } else { current_pos = x.current_pos; root = x.root; buf_ptr = 0; } } void incr(size_t n); void decr(size_t n); public: size_t index() const { return current_pos; } }; template class __rope_iterator; template class __rope_const_iterator : public __rope_iterator_base { friend class rope; protected: __rope_const_iterator(const RopeBase * root, size_t pos): __rope_iterator_base( const_cast(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(x) { } __rope_const_iterator(const __rope_iterator & x); __rope_const_iterator(const rope &r, size_t pos) : __rope_iterator_base(r.tree_ptr, pos) {} __rope_const_iterator& operator= (const __rope_const_iterator & x) { if (0 != x.buf_ptr) { *this = x; } else { current_pos = x.current_pos; root = x.root; buf_ptr = 0; } return(*this); } reference operator*() { if (0 == buf_ptr) setcache(*this); return *buf_ptr; } __rope_const_iterator& operator++() { __GC_CONST charT * next; if (0 != buf_ptr && (next = buf_ptr + 1) < buf_end) { buf_ptr = next; ++current_pos; } else { incr(1); } return *this; } __rope_const_iterator& operator+=(ptrdiff_t n) { if (n >= 0) { incr(n); } else { decr(-n); } return *this; } __rope_const_iterator& operator--() { decr(1); return *this; } __rope_const_iterator& operator-=(ptrdiff_t n) { if (n >= 0) { decr(n); } else { incr(-n); } return *this; } __rope_const_iterator operator++(int) { size_t old_pos = current_pos; incr(1); return __rope_const_iterator(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 = current_pos; decr(1); return __rope_const_iterator(root, old_pos); } friend __rope_const_iterator operator- __STL_NULL_TMPL_ARGS (const __rope_const_iterator & x, ptrdiff_t n); friend __rope_const_iterator operator+ __STL_NULL_TMPL_ARGS (const __rope_const_iterator & x, ptrdiff_t n); friend __rope_const_iterator operator+ __STL_NULL_TMPL_ARGS (ptrdiff_t n, const __rope_const_iterator & x); reference operator[](size_t n) { return rope::fetch(root, current_pos + n); } friend bool operator== __STL_NULL_TMPL_ARGS (const __rope_const_iterator & x, const __rope_const_iterator & y); friend bool operator< __STL_NULL_TMPL_ARGS (const __rope_const_iterator & x, const __rope_const_iterator & y); friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS (const __rope_const_iterator & x, const __rope_const_iterator & y); }; template class __rope_iterator : public __rope_iterator_base { friend class rope; protected: rope * 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 * r, size_t pos): __rope_iterator_base(r -> tree_ptr, pos), root_rope(r) { RopeBase::ref(root); } void check(); public: typedef __rope_charT_ref_proxy reference; typedef __rope_charT_ref_proxy* pointer; public: rope& container() { return *root_rope; } __rope_iterator() { root = 0; // Needed for reference counting. }; __rope_iterator(const __rope_iterator & x) : __rope_iterator_base(x) { root_rope = x.root_rope; RopeBase::ref(root); } __rope_iterator(rope& r, size_t pos); ~__rope_iterator() { RopeBase::unref(root); } __rope_iterator& operator= (const __rope_iterator & x) { RopeBase *old = root; RopeBase::ref(x.root); if (0 != x.buf_ptr) { *this = x; } else { current_pos = x.current_pos; root = x.root; root_rope = x.root_rope; buf_ptr = 0; } RopeBase::unref(old); return(*this); } reference operator*() { check(); if (0 == buf_ptr) { return __rope_charT_ref_proxy(root_rope, current_pos); } else { return __rope_charT_ref_proxy(root_rope, current_pos, *buf_ptr); } } __rope_iterator& operator++() { incr(1); return *this; } __rope_iterator& operator+=(difference_type n) { if (n >= 0) { incr(n); } else { decr(-n); } return *this; } __rope_iterator& operator--() { decr(1); return *this; } __rope_iterator& operator-=(difference_type n) { if (n >= 0) { decr(n); } else { incr(-n); } return *this; } __rope_iterator operator++(int) { size_t old_pos = current_pos; incr(1); return __rope_iterator(root_rope, old_pos); } __rope_iterator operator--(int) { size_t old_pos = current_pos; decr(1); return __rope_iterator(root_rope, old_pos); } reference operator[](ptrdiff_t n) { return __rope_charT_ref_proxy(root_rope, current_pos + n); } friend bool operator== __STL_NULL_TMPL_ARGS (const __rope_iterator & x, const __rope_iterator & y); friend bool operator< __STL_NULL_TMPL_ARGS (const __rope_iterator & x, const __rope_iterator & y); friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS (const __rope_iterator & x, const __rope_iterator & y); friend __rope_iterator operator- __STL_NULL_TMPL_ARGS (const __rope_iterator & x, ptrdiff_t n); friend __rope_iterator operator+ __STL_NULL_TMPL_ARGS (const __rope_iterator & x, ptrdiff_t n); friend __rope_iterator operator+ __STL_NULL_TMPL_ARGS (ptrdiff_t n, const __rope_iterator & x); }; #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1375 #endif template class rope { 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 iterator; typedef __rope_const_iterator const_iterator; typedef __rope_charT_ref_proxy reference; typedef __rope_charT_ptr_proxy pointer; friend class __rope_iterator; friend class __rope_const_iterator; friend struct __rope_RopeBase; friend class __rope_iterator_base; friend class __rope_charT_ptr_proxy; friend class __rope_charT_ref_proxy; friend struct __rope_RopeSubstring; protected: typedef __GC_CONST charT * cstrptr; # ifdef __STL_SGI_THREADS static cstrptr atomic_swap(cstrptr *p, cstrptr q) { # if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) return (cstrptr) test_and_set((unsigned long *)p, (unsigned long)q); # else return (cstrptr) __test_and_set((unsigned long *)p, (unsigned long)q); # endif } # elif defined(__STL_WIN32THREADS) static cstrptr atomic_swap(cstrptr *p, cstrptr q) { return (cstrptr) InterlockedExchange((LPLONG)p, (LONG)q); } # elif defined(__STL_PTHREADS) // This should be portable, but performance is expected // to be quite awful. This really needs platform specific // code. static pthread_mutex_t swap_lock; static cstrptr atomic_swap(cstrptr *p, cstrptr q) { pthread_mutex_lock(&swap_lock); cstrptr result = *p; *p = q; pthread_mutex_unlock(&swap_lock); return result; } # else static cstrptr atomic_swap(cstrptr *p, cstrptr q) { cstrptr result = *p; *p = q; return result; } # endif static charT empty_c_str[1]; typedef simple_alloc DataAlloc; typedef simple_alloc<__rope_RopeConcatenation, Alloc> CAlloc; typedef simple_alloc<__rope_RopeLeaf, Alloc> LAlloc; typedef simple_alloc<__rope_RopeFunction, Alloc> FAlloc; typedef simple_alloc<__rope_RopeSubstring, Alloc> SAlloc; static bool is0(charT c) { return c == __eos((charT *)0); } enum { copy_max = 23 }; // For strings shorter than copy_max, we copy to // concatenate. typedef __rope_RopeBase RopeBase; typedef __rope_RopeConcatenation RopeConcatenation; typedef __rope_RopeLeaf RopeLeaf; typedef __rope_RopeFunction RopeFunction; typedef __rope_RopeSubstring RopeSubstring; // The only data member of a rope: RopeBase *tree_ptr; // Retrieve a character at the indicated position. static charT fetch(RopeBase * 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 * fetch_ptr(RopeBase * r, size_type pos); # endif static bool apply_to_pieces( // should be template parameter __rope_char_consumer& c, const RopeBase * r, size_t begin, size_t end); // begin and end are assumed to be in range. # ifndef __GC static void unref(RopeBase* t) { RopeBase::unref(t); } static void ref(RopeBase* t) { RopeBase::ref(t); } # else /* __GC */ static void unref(RopeBase* t) {} static void ref(RopeBase* t) {} # endif # ifdef __GC typedef __rope_RopeBase * self_destruct_ptr; # else typedef __rope_self_destruct_ptr self_destruct_ptr; # endif // Result is counted in refcount. static RopeBase * substring(RopeBase * base, size_t start, size_t endp1); static RopeBase * concat_char_iter(RopeBase * 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 RopeBase * destr_concat_char_iter(RopeBase * 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 // relevent reference counts are 1. # ifdef __GC // We can't really do anything since refcounts are unavailable. { return concat_char_iter(r, iter, slen); } # else ; # endif static RopeBase * concat(RopeBase *left, RopeBase *right); // General concatenation on RopeBase. Result // has refcount of 1. Adjusts argument refcounts. public: void apply_to_pieces( size_t begin, size_t end, __rope_char_consumer& c) const { apply_to_pieces(c, tree_ptr, begin, end); } protected: static size_t rounded_up_size(size_t n) { return RopeBase::rounded_up_size(n); } static size_t allocated_capacity(size_t n) { if (__is_basic_char_type((charT *)0)) { return rounded_up_size(n) - 1; } else { return rounded_up_size(n); } } // s should really be an arbitrary input iterator. // Adds a trailing NULL for basic char types. static charT * alloc_copy(const charT *s, size_t size) { charT * result = DataAlloc::allocate(rounded_up_size(size)); uninitialized_copy_n(s, size, result); __cond_store_eos(result[size]); return(result); } // Basic constructors for rope tree nodes. // These return tree nodes with a 0 reference count. static RopeLeaf * RopeLeaf_from_char_ptr(__GC_CONST charT *s, size_t size); // Takes ownership of its argument. // Result has refcount 1. // In the nonGC, basic_char_type case it assumes that s // is eos-terminated. // In the nonGC case, it was allocated from Alloc with // rounded_up_size(size). static RopeLeaf * RopeLeaf_from_unowned_char_ptr(const charT *s, size_t size) { charT * buf = alloc_copy(s, size); __STL_TRY { return RopeLeaf_from_char_ptr(buf, size); } __STL_UNWIND(RopeBase::free_string(buf, size)) } // 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 RopeBase * tree_concat(RopeBase * left, RopeBase * right); // Result has refcount 1. // If delete_fn is true, then fn is deleted when the rope // becomes inaccessible. static RopeFunction * RopeFunction_from_fn (char_producer *fn, size_t size, bool delete_fn); // Concatenation helper functions static RopeLeaf * 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 * destr_leaf_concat_char_iter (RopeLeaf * r, const charT * iter, size_t slen); // A version that potentially clobbers r if r -> refcount == 1. # endif // A helper function for exponentiating strings. // This uses a nonstandard refcount convention. // The result has refcount 0. struct concat_fn; friend struct rope::concat_fn; struct concat_fn : public binary_function, rope, rope > { rope operator() (const rope& x, const rope& y) { return x + y; } }; friend rope identity_element(concat_fn) { return rope(); } static size_t char_ptr_len(const charT * s); // slightly generalized strlen rope(RopeBase *t) : tree_ptr(t) { } // Copy r to the CharT buffer. // Returns buffer + r -> size. // Assumes that buffer is uninitialized. static charT * flatten(RopeBase * r, charT * buffer); // Again, with explicit starting position and length. // Assumes that buffer is uninitialized. static charT * flatten(RopeBase * r, size_t start, size_t len, charT * buffer); static const unsigned long min_len[RopeBase::max_rope_depth + 1]; static bool is_balanced(RopeBase *r) { return (r -> size >= min_len[r -> depth]); } static bool is_almost_balanced(RopeBase *r) { return (r -> depth == 0 || r -> size >= min_len[r -> depth - 1]); } static bool is_roughly_balanced(RopeBase *r) { return (r -> depth <= 1 || r -> size >= min_len[r -> depth - 2]); } // Assumes the result is not empty. static RopeBase * concat_and_set_balanced(RopeBase *left, RopeBase *right) { RopeBase * result = concat(left, right); if (is_balanced(result)) result -> 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 isd within height 2 of balanced by the above // definition. static RopeBase * balance(RopeBase * r); // Add all unbalanced subtrees to the forest of balanceed trees. // Used only by balance. static void add_to_forest(RopeBase *r, RopeBase **forest); // Add r to forest, assuming r is already balanced. static void add_leaf_to_forest(RopeBase *r, RopeBase **forest); // Print to stdout, exposing structure static void dump(RopeBase * r, int indent = 0); // Return -1, 0, or 1 if x < y, x == y, or x > y resp. static int compare(const RopeBase *x, const RopeBase *y); public: bool empty() const { return 0 == 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 compare(tree_ptr, y.tree_ptr); } rope(const charT *s) { size_t len = char_ptr_len(s); if (0 == len) { tree_ptr = 0; } else { tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); # ifndef __GC __stl_assert(1 == tree_ptr -> refcount); # endif } } rope(const charT *s, size_t len) { if (0 == len) { tree_ptr = 0; } else { tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); } } rope(const charT *s, charT *e) { size_t len = e - s; if (0 == len) { tree_ptr = 0; } else { tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); } } rope(const const_iterator& s, const const_iterator& e) { tree_ptr = substring(s.root, s.current_pos, e.current_pos); } rope(const iterator& s, const iterator& e) { tree_ptr = substring(s.root, s.current_pos, e.current_pos); } rope(charT c) { charT * buf = DataAlloc::allocate(rounded_up_size(1)); construct(buf, c); __STL_TRY { tree_ptr = RopeLeaf_from_char_ptr(buf, 1); } __STL_UNWIND(RopeBase::free_string(buf, 1)) } rope(size_t n, charT c); // Should really be templatized with respect to the iterator type // and use sequence_buffer. (It should perhaps use sequence_buffer // even now.) rope(const charT *i, const charT *j) { if (i == j) { tree_ptr = 0; } else { size_t len = j - i; tree_ptr = RopeLeaf_from_unowned_char_ptr(i, len); } } rope() { tree_ptr = 0; } // Construct a rope from a function that can compute its members rope(char_producer *fn, size_t len, bool delete_fn) { tree_ptr = RopeFunction_from_fn(fn, len, delete_fn); } rope(const rope &x) { tree_ptr = x.tree_ptr; ref(tree_ptr); } ~rope() { unref(tree_ptr); } rope& operator=(const rope& x) { RopeBase *old = tree_ptr; tree_ptr = x.tree_ptr; ref(tree_ptr); unref(old); return(*this); } void push_back(charT x) { RopeBase *old = tree_ptr; tree_ptr = concat_char_iter(tree_ptr, &x, 1); unref(old); } void pop_back() { RopeBase *old = tree_ptr; tree_ptr = substring(tree_ptr, 0, tree_ptr -> size - 1); unref(old); } charT back() const { return fetch(tree_ptr, tree_ptr -> size - 1); } void push_front(charT x) { RopeBase *old = tree_ptr; RopeBase *left; left = RopeLeaf_from_unowned_char_ptr(&x, 1); __STL_TRY { tree_ptr = concat(left, tree_ptr); unref(old); unref(left); } __STL_UNWIND(unref(left)) } void pop_front() { RopeBase *old = tree_ptr; tree_ptr = substring(tree_ptr, 1, tree_ptr -> size); unref(old); } charT front() const { return fetch(tree_ptr, 0); } void balance() { RopeBase *old = tree_ptr; tree_ptr = balance(tree_ptr); unref(old); } void copy(charT * buffer) const { destroy(buffer, buffer + size()); flatten(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 sz = size(); size_t len = (pos + n > sz? sz - pos : n); destroy(buffer, buffer + len); flatten(tree_ptr, pos, len, buffer); return len; } // Print to stdout, exposing structure. May be useful for // performance debugging. void dump() { dump(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 == tree_ptr) return; if (RopeBase::leaf == tree_ptr -> tag && ((RopeLeaf *)tree_ptr) -> data == tree_ptr -> c_string) { // Representation shared return; } # ifndef __GC tree_ptr -> free_c_string(); # endif tree_ptr -> c_string = 0; } charT operator[] (size_type pos) const { return fetch(tree_ptr, pos); } charT at(size_type pos) const { // if (pos >= size()) throw out_of_range; return (*this)[pos]; } const_iterator begin() const { return(const_iterator(tree_ptr, 0)); } // An easy way to get a const iterator from a non-const container. const_iterator const_begin() const { return(const_iterator(tree_ptr, 0)); } const_iterator end() const { return(const_iterator(tree_ptr, size())); } const_iterator const_end() const { return(const_iterator(tree_ptr, size())); } size_type size() const { return(0 == tree_ptr? 0 : tree_ptr -> size); } size_type length() const { return size(); } size_type max_size() const { return min_len[RopeBase::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. } # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; # else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator const_reverse_iterator; # endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 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()); } friend rope operator+ __STL_NULL_TMPL_ARGS (const rope &left, const rope &right); friend rope operator+ __STL_NULL_TMPL_ARGS (const rope &left, const charT* right); friend rope operator+ __STL_NULL_TMPL_ARGS (const rope &left, charT 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) { RopeBase* result = destr_concat_char_iter(tree_ptr, iter, n); unref(tree_ptr); tree_ptr = result; return *this; } rope& append(const charT* c_string) { size_t len = char_ptr_len(c_string); append(c_string, len); return(*this); } rope& append(const charT* s, const charT* e) { RopeBase* result = destr_concat_char_iter(tree_ptr, s, e - s); unref(tree_ptr); tree_ptr = result; return *this; } rope& append(const_iterator s, const_iterator e) { __stl_assert(s.root == e.root); self_destruct_ptr appendee(substring(s.root, s.current_pos, e.current_pos)); RopeBase* result = concat(tree_ptr, (RopeBase *)appendee); unref(tree_ptr); tree_ptr = result; return *this; } rope& append(charT c) { RopeBase* result = destr_concat_char_iter(tree_ptr, &c, 1); unref(tree_ptr); tree_ptr = result; return *this; } rope& append() { return append(charT()); } rope& append(const rope& y) { RopeBase* result = concat(tree_ptr, y.tree_ptr); unref(tree_ptr); tree_ptr = result; return *this; } rope& append(size_t n, charT c) { rope last(n, c); return append(last); } void swap(rope& b) { RopeBase * tmp = tree_ptr; tree_ptr = b.tree_ptr; b.tree_ptr = tmp; } protected: // Result is included in refcount. static RopeBase * replace(RopeBase *old, size_t pos1, size_t pos2, RopeBase *r) { if (0 == old) { ref(r); return r; } self_destruct_ptr left(substring(old, 0, pos1)); self_destruct_ptr right(substring(old, pos2, old -> size)); RopeBase * result; if (0 == r) { result = concat(left, right); } else { self_destruct_ptr left_result(concat(left, r)); result = concat(left_result, right); } return result; } public: void insert(size_t p, const rope& r) { RopeBase * result = replace(tree_ptr, p, p, r.tree_ptr); unref(tree_ptr); tree_ptr = result; } void insert(size_t p, size_t n, charT c) { rope r(n,c); insert(p, r); } void insert(size_t p, const charT * i, size_t n) { self_destruct_ptr left(substring(tree_ptr, 0, p)); self_destruct_ptr right(substring(tree_ptr, p, size())); self_destruct_ptr left_result(concat_char_iter(left, i, n)); RopeBase * result = concat(left_result, right); unref(tree_ptr); tree_ptr = result; } void insert(size_t p, const charT * c_string) { insert(p, c_string, 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) { RopeBase * result = replace(tree_ptr, p, p + n, r.tree_ptr); unref(tree_ptr); 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) { RopeBase * result = replace(tree_ptr, p, p + n, 0); unref(tree_ptr); 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( substring(tree_ptr, start, start + len)); } rope substr(iterator start, iterator end) const { return rope( substring(tree_ptr, start.index(), end.index())); } rope substr(iterator start) const { size_t pos = start.index(); return rope( substring(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 (substring(tree_ptr, start.index(), end.index())); } rope substr(const_iterator start) { size_t pos = start.index(); return rope(substring(tree_ptr, pos, pos + 1)); } size_type find(charT c, size_type pos = 0) const; size_type find(charT *s, size_type pos = 0) const { const_iterator result = search(const_begin() + pos, const_end(), s, s + char_ptr_len(s)); return result.index(); } iterator mutable_begin() { return(iterator(this, 0)); } iterator mutable_end() { return(iterator(this, size())); } # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator reverse_iterator; # else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator reverse_iterator; # endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 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 charT_ref_proxy(this, pos); } reference at(size_type pos) { // if (pos >= size()) throw out_of_range; 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 inline bool operator== (const __rope_const_iterator & x, const __rope_const_iterator & y) { return (x.current_pos == y.current_pos && x.root == y.root); } template inline bool operator< (const __rope_const_iterator & x, const __rope_const_iterator & y) { return (x.current_pos < y.current_pos); } template inline ptrdiff_t operator-(const __rope_const_iterator & x, const __rope_const_iterator & y) { return x.current_pos - y.current_pos; } template inline __rope_const_iterator operator-(const __rope_const_iterator & x, ptrdiff_t n) { return __rope_const_iterator(x.root, x.current_pos - n); } template inline __rope_const_iterator operator+(const __rope_const_iterator & x, ptrdiff_t n) { return __rope_const_iterator(x.root, x.current_pos + n); } template inline __rope_const_iterator operator+(ptrdiff_t n, const __rope_const_iterator & x) { return __rope_const_iterator(x.root, x.current_pos + n); } template inline bool operator== (const __rope_iterator & x, const __rope_iterator & y) { return (x.current_pos == y.current_pos && x.root_rope == y.root_rope); } template inline bool operator< (const __rope_iterator & x, const __rope_iterator & y) { return (x.current_pos < y.current_pos); } template inline ptrdiff_t operator-(const __rope_iterator & x, const __rope_iterator & y) { return x.current_pos - y.current_pos; } template inline __rope_iterator operator-(const __rope_iterator & x, ptrdiff_t n) { return __rope_iterator(x.root_rope, x.current_pos - n); } template inline __rope_iterator operator+(const __rope_iterator & x, ptrdiff_t n) { return __rope_iterator(x.root_rope, x.current_pos + n); } template inline __rope_iterator operator+(ptrdiff_t n, const __rope_iterator & x) { return __rope_iterator(x.root_rope, x.current_pos + n); } template inline rope operator+ (const rope &left, const rope &right) { return rope (rope::concat(left.tree_ptr, right.tree_ptr)); // Inlining this should make it possible to keep left and // right in registers. } template inline rope& operator+= (rope &left, const rope &right) { left.append(right); return left; } template inline rope operator+ (const rope &left, const charT* right) { size_t rlen = rope::char_ptr_len(right); return rope (rope::concat_char_iter(left.tree_ptr, right, rlen)); } template inline rope& operator+= (rope &left, const charT* right) { left.append(right); return left; } template inline rope operator+ (const rope &left, charT right) { return rope (rope::concat_char_iter(left.tree_ptr, &right, 1)); } template inline rope& operator+= (rope &left, charT right) { left.append(right); return left; } template bool operator< (const rope &left, const rope &right) { return left.compare(right) < 0; } template bool operator== (const rope &left, const rope &right) { return left.compare(right) == 0; } template inline bool operator== (const __rope_charT_ptr_proxy & x, const __rope_charT_ptr_proxy & y) { return (x.pos == y.pos && x.root == y.root); } template ostream& operator<< (ostream& o, const rope& r); typedef rope crope; typedef rope 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); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(rope& x, rope& y) { x.swap(y); } #else inline void swap(crope x, crope y) { x.swap(y); } inline void swap(wrope x, wrope y) { x.swap(y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Hash functions should probably be revisited later: __STL_TEMPLATE_NULL struct hash { size_t operator()(const crope& str) const { size_t sz = str.size(); if (0 == sz) return 0; return 13*str[0] + 5*str[sz - 1] + sz; } }; __STL_TEMPLATE_NULL struct hash { size_t operator()(const wrope& str) const { size_t sz = str.size(); if (0 == sz) return 0; return 13*str[0] + 5*str[sz - 1] + sz; } }; #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE # include # endif /* __SGI_STL_INTERNAL_ROPE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_set.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_SET_H #define __SGI_STL_INTERNAL_SET_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template , class Alloc = alloc> #else template #endif class set { public: // typedefs: typedef Key key_type; typedef Key value_type; typedef Compare key_compare; typedef Compare value_compare; private: typedef rb_tree, key_compare, Alloc> rep_type; rep_type t; // red-black tree representing set public: typedef typename rep_type::const_pointer pointer; typedef typename rep_type::const_pointer const_pointer; typedef typename rep_type::const_reference reference; typedef typename rep_type::const_reference const_reference; 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 set() : t(Compare()) {} explicit set(const Compare& comp) : t(comp) {} #ifdef __STL_MEMBER_TEMPLATES template set(InputIterator first, InputIterator last) : t(Compare()) { t.insert_unique(first, last); } template set(InputIterator first, InputIterator last, const Compare& comp) : t(comp) { t.insert_unique(first, last); } #else set(const value_type* first, const value_type* last) : t(Compare()) { t.insert_unique(first, last); } set(const value_type* first, const value_type* last, const Compare& comp) : t(comp) { t.insert_unique(first, last); } set(const_iterator first, const_iterator last) : t(Compare()) { t.insert_unique(first, last); } set(const_iterator first, const_iterator last, const Compare& comp) : t(comp) { t.insert_unique(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ set(const set& x) : t(x.t) {} set& operator=(const set& x) { t = x.t; return *this; } // accessors: key_compare key_comp() const { return t.key_comp(); } value_compare value_comp() const { return t.key_comp(); } iterator begin() const { return t.begin(); } iterator end() const { return t.end(); } reverse_iterator rbegin() const { return t.rbegin(); } reverse_iterator rend() const { return t.rend(); } bool empty() const { return t.empty(); } size_type size() const { return t.size(); } size_type max_size() const { return t.max_size(); } void swap(set& x) { t.swap(x.t); } // insert/erase typedef pair pair_iterator_bool; pair insert(const value_type& x) { pair p = t.insert_unique(x); return pair(p.first, p.second); } iterator insert(iterator position, const value_type& x) { typedef typename rep_type::iterator rep_iterator; return t.insert_unique((rep_iterator&)position, x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(InputIterator first, InputIterator last) { t.insert_unique(first, last); } #else void insert(const_iterator first, const_iterator last) { t.insert_unique(first, last); } void insert(const value_type* first, const value_type* last) { t.insert_unique(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator position) { typedef typename rep_type::iterator rep_iterator; t.erase((rep_iterator&)position); } size_type erase(const key_type& x) { return t.erase(x); } void erase(iterator first, iterator last) { typedef typename rep_type::iterator rep_iterator; t.erase((rep_iterator&)first, (rep_iterator&)last); } void clear() { t.clear(); } // set operations: iterator find(const key_type& x) const { return t.find(x); } size_type count(const key_type& x) const { return t.count(x); } iterator lower_bound(const key_type& x) const { return t.lower_bound(x); } iterator upper_bound(const key_type& x) const { return t.upper_bound(x); } pair equal_range(const key_type& x) const { return t.equal_range(x); } friend bool operator== __STL_NULL_TMPL_ARGS (const set&, const set&); friend bool operator< __STL_NULL_TMPL_ARGS (const set&, const set&); }; template inline bool operator==(const set& x, const set& y) { return x.t == y.t; } template inline bool operator<(const set& x, const set& y) { return x.t < y.t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(set& x, set& y) { x.swap(y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_SET_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_slist.h ================================================ /* * 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. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_SLIST_H #define __SGI_STL_INTERNAL_SLIST_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif struct __slist_node_base { __slist_node_base* next; }; inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node, __slist_node_base* new_node) { new_node->next = prev_node->next; prev_node->next = new_node; return new_node; } inline __slist_node_base* __slist_previous(__slist_node_base* head, const __slist_node_base* node) { while (head && head->next != node) head = head->next; return head; } inline const __slist_node_base* __slist_previous(const __slist_node_base* head, const __slist_node_base* node) { while (head && head->next != node) head = head->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->next; __slist_node_base* after = pos->next; before_first->next = before_last->next; pos->next = first; before_last->next = after; } } inline __slist_node_base* __slist_reverse(__slist_node_base* node) { __slist_node_base* result = node; node = node->next; result->next = 0; while(node) { __slist_node_base* next = node->next; node->next = result; result = node; node = next; } return result; } template struct __slist_node : public __slist_node_base { T data; }; struct __slist_iterator_base { typedef size_t size_type; typedef ptrdiff_t difference_type; typedef forward_iterator_tag iterator_category; __slist_node_base* node; __slist_iterator_base(__slist_node_base* x) : node(x) {} void incr() { node = node->next; } bool operator==(const __slist_iterator_base& x) const { return node == x.node; } bool operator!=(const __slist_iterator_base& x) const { return node != x.node; } }; template struct __slist_iterator : public __slist_iterator_base { typedef __slist_iterator iterator; typedef __slist_iterator const_iterator; typedef __slist_iterator self; typedef T value_type; typedef Ptr pointer; typedef Ref reference; typedef __slist_node list_node; __slist_iterator(list_node* x) : __slist_iterator_base(x) {} __slist_iterator() : __slist_iterator_base(0) {} __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {} reference operator*() const { return ((list_node*) node)->data; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ self& operator++() { incr(); return *this; } self operator++(int) { self tmp = *this; incr(); return tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION inline ptrdiff_t* distance_type(const __slist_iterator_base&) { return 0; } inline forward_iterator_tag iterator_category(const __slist_iterator_base&) { return forward_iterator_tag(); } template inline T* value_type(const __slist_iterator&) { return 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ inline size_t __slist_size(__slist_node_base* node) { size_t result = 0; for ( ; node != 0; node = node->next) ++result; return result; } template class slist { public: typedef T 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 iterator; typedef __slist_iterator const_iterator; private: typedef __slist_node list_node; typedef __slist_node_base list_node_base; typedef __slist_iterator_base iterator_base; typedef simple_alloc list_node_allocator; static list_node* create_node(const value_type& x) { list_node* node = list_node_allocator::allocate(); __STL_TRY { construct(&node->data, x); node->next = 0; } __STL_UNWIND(list_node_allocator::deallocate(node)); return node; } static void destroy_node(list_node* node) { destroy(&node->data); list_node_allocator::deallocate(node); } void fill_initialize(size_type n, const value_type& x) { head.next = 0; __STL_TRY { _insert_after_fill(&head, n, x); } __STL_UNWIND(clear()); } #ifdef __STL_MEMBER_TEMPLATES template void range_initialize(InputIterator first, InputIterator last) { head.next = 0; __STL_TRY { _insert_after_range(&head, first, last); } __STL_UNWIND(clear()); } #else /* __STL_MEMBER_TEMPLATES */ void range_initialize(const value_type* first, const value_type* last) { head.next = 0; __STL_TRY { _insert_after_range(&head, first, last); } __STL_UNWIND(clear()); } void range_initialize(const_iterator first, const_iterator last) { head.next = 0; __STL_TRY { _insert_after_range(&head, first, last); } __STL_UNWIND(clear()); } #endif /* __STL_MEMBER_TEMPLATES */ private: list_node_base head; public: slist() { head.next = 0; } slist(size_type n, const value_type& x) { fill_initialize(n, x); } slist(int n, const value_type& x) { fill_initialize(n, x); } slist(long n, const value_type& x) { fill_initialize(n, x); } explicit slist(size_type n) { fill_initialize(n, value_type()); } #ifdef __STL_MEMBER_TEMPLATES template slist(InputIterator first, InputIterator last) { range_initialize(first, last); } #else /* __STL_MEMBER_TEMPLATES */ slist(const_iterator first, const_iterator last) { range_initialize(first, last); } slist(const value_type* first, const value_type* last) { range_initialize(first, last); } #endif /* __STL_MEMBER_TEMPLATES */ slist(const slist& L) { range_initialize(L.begin(), L.end()); } slist& operator= (const slist& L); ~slist() { clear(); } public: iterator begin() { return iterator((list_node*)head.next); } const_iterator begin() const { return const_iterator((list_node*)head.next);} iterator end() { return iterator(0); } const_iterator end() const { return const_iterator(0); } size_type size() const { return __slist_size(head.next); } size_type max_size() const { return size_type(-1); } bool empty() const { return head.next == 0; } void swap(slist& L) { list_node_base* tmp = head.next; head.next = L.head.next; L.head.next = tmp; } public: friend bool operator== __STL_NULL_TMPL_ARGS(const slist& L1, const slist& L2); public: reference front() { return ((list_node*) head.next)->data; } const_reference front() const { return ((list_node*) head.next)->data; } void push_front(const value_type& x) { __slist_make_link(&head, create_node(x)); } void pop_front() { list_node* node = (list_node*) head.next; head.next = node->next; destroy_node(node); } iterator previous(const_iterator pos) { return iterator((list_node*) __slist_previous(&head, pos.node)); } const_iterator previous(const_iterator pos) const { return const_iterator((list_node*) __slist_previous(&head, pos.node)); } private: list_node* _insert_after(list_node_base* pos, const value_type& x) { return (list_node*) (__slist_make_link(pos, create_node(x))); } void _insert_after_fill(list_node_base* pos, size_type n, const value_type& x) { for (size_type i = 0; i < n; ++i) pos = __slist_make_link(pos, create_node(x)); } #ifdef __STL_MEMBER_TEMPLATES template void _insert_after_range(list_node_base* pos, InIter first, InIter last) { while (first != last) { pos = __slist_make_link(pos, create_node(*first)); ++first; } } #else /* __STL_MEMBER_TEMPLATES */ void _insert_after_range(list_node_base* pos, const_iterator first, const_iterator last) { while (first != last) { pos = __slist_make_link(pos, create_node(*first)); ++first; } } void _insert_after_range(list_node_base* pos, const value_type* first, const value_type* last) { while (first != last) { pos = __slist_make_link(pos, create_node(*first)); ++first; } } #endif /* __STL_MEMBER_TEMPLATES */ list_node_base* erase_after(list_node_base* pos) { list_node* next = (list_node*) (pos->next); list_node_base* next_next = next->next; pos->next = next_next; destroy_node(next); return next_next; } list_node_base* erase_after(list_node_base* before_first, list_node_base* last_node) { list_node* cur = (list_node*) (before_first->next); while (cur != last_node) { list_node* tmp = cur; cur = (list_node*) cur->next; destroy_node(tmp); } before_first->next = last_node; return last_node; } public: iterator insert_after(iterator pos, const value_type& x) { return iterator(_insert_after(pos.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) { _insert_after_fill(pos.node, n, x); } void insert_after(iterator pos, int n, const value_type& x) { _insert_after_fill(pos.node, (size_type) n, x); } void insert_after(iterator pos, long n, const value_type& x) { _insert_after_fill(pos.node, (size_type) n, x); } #ifdef __STL_MEMBER_TEMPLATES template void insert_after(iterator pos, InIter first, InIter last) { _insert_after_range(pos.node, first, last); } #else /* __STL_MEMBER_TEMPLATES */ void insert_after(iterator pos, const_iterator first, const_iterator last) { _insert_after_range(pos.node, first, last); } void insert_after(iterator pos, const value_type* first, const value_type* last) { _insert_after_range(pos.node, first, last); } #endif /* __STL_MEMBER_TEMPLATES */ iterator insert(iterator pos, const value_type& x) { return iterator(_insert_after(__slist_previous(&head, pos.node), x)); } iterator insert(iterator pos) { return iterator(_insert_after(__slist_previous(&head, pos.node), value_type())); } void insert(iterator pos, size_type n, const value_type& x) { _insert_after_fill(__slist_previous(&head, pos.node), n, x); } void insert(iterator pos, int n, const value_type& x) { _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x); } void insert(iterator pos, long n, const value_type& x) { _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x); } #ifdef __STL_MEMBER_TEMPLATES template void insert(iterator pos, InIter first, InIter last) { _insert_after_range(__slist_previous(&head, pos.node), first, last); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator pos, const_iterator first, const_iterator last) { _insert_after_range(__slist_previous(&head, pos.node), first, last); } void insert(iterator pos, const value_type* first, const value_type* last) { _insert_after_range(__slist_previous(&head, pos.node), first, last); } #endif /* __STL_MEMBER_TEMPLATES */ public: iterator erase_after(iterator pos) { return iterator((list_node*)erase_after(pos.node)); } iterator erase_after(iterator before_first, iterator last) { return iterator((list_node*)erase_after(before_first.node, last.node)); } iterator erase(iterator pos) { return (list_node*) erase_after(__slist_previous(&head, pos.node)); } iterator erase(iterator first, iterator last) { return (list_node*) erase_after(__slist_previous(&head, first.node), last.node); } void resize(size_type new_size, const T& x); void resize(size_type new_size) { resize(new_size, T()); } void clear() { erase_after(&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.node, before_first.node, before_last.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.node, prev.node, prev.node->next); } // Linear in distance(begin(), pos), and linear in L.size(). void splice(iterator pos, slist& L) { if (L.head.next) __slist_splice_after(__slist_previous(&head, pos.node), &L.head, __slist_previous(&L.head, 0)); } // Linear in distance(begin(), pos), and in distance(L.begin(), i). void splice(iterator pos, slist& L, iterator i) { __slist_splice_after(__slist_previous(&head, pos.node), __slist_previous(&L.head, i.node), i.node); } // Linear in distance(begin(), pos), in distance(L.begin(), first), // and in distance(first, last). void splice(iterator pos, slist& L, iterator first, iterator last) { if (first != last) __slist_splice_after(__slist_previous(&head, pos.node), __slist_previous(&L.head, first.node), __slist_previous(first.node, last.node)); } public: void reverse() { if (head.next) head.next = __slist_reverse(head.next); } void remove(const T& val); void unique(); void merge(slist& L); void sort(); #ifdef __STL_MEMBER_TEMPLATES template void remove_if(Predicate pred); template void unique(BinaryPredicate pred); template void merge(slist&, StrictWeakOrdering); template void sort(StrictWeakOrdering comp); #endif /* __STL_MEMBER_TEMPLATES */ }; template slist& slist::operator=(const slist& L) { if (&L != this) { list_node_base* p1 = &head; list_node* n1 = (list_node*) head.next; const list_node* n2 = (const list_node*) L.head.next; while (n1 && n2) { n1->data = n2->data; p1 = n1; n1 = (list_node*) n1->next; n2 = (const list_node*) n2->next; } if (n2 == 0) erase_after(p1, 0); else _insert_after_range(p1, const_iterator((list_node*)n2), const_iterator(0)); } return *this; } template bool operator==(const slist& L1, const slist& L2) { typedef typename slist::list_node list_node; list_node* n1 = (list_node*) L1.head.next; list_node* n2 = (list_node*) L2.head.next; while (n1 && n2 && n1->data == n2->data) { n1 = (list_node*) n1->next; n2 = (list_node*) n2->next; } return n1 == 0 && n2 == 0; } template inline bool operator<(const slist& L1, const slist& L2) { return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(slist& x, slist& y) { x.swap(y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template void slist::resize(size_type len, const T& x) { list_node_base* cur = &head; while (cur->next != 0 && len > 0) { --len; cur = cur->next; } if (cur->next) erase_after(cur, 0); else _insert_after_fill(cur, len, x); } template void slist::remove(const T& val) { list_node_base* cur = &head; while (cur && cur->next) { if (((list_node*) cur->next)->data == val) erase_after(cur); else cur = cur->next; } } template void slist::unique() { list_node_base* cur = head.next; if (cur) { while (cur->next) { if (((list_node*)cur)->data == ((list_node*)(cur->next))->data) erase_after(cur); else cur = cur->next; } } } template void slist::merge(slist& L) { list_node_base* n1 = &head; while (n1->next && L.head.next) { if (((list_node*) L.head.next)->data < ((list_node*) n1->next)->data) __slist_splice_after(n1, &L.head, L.head.next); n1 = n1->next; } if (L.head.next) { n1->next = L.head.next; L.head.next = 0; } } template void slist::sort() { if (head.next && head.next->next) { slist carry; slist counter[64]; int fill = 0; while (!empty()) { __slist_splice_after(&carry.head, &head, head.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]); } } #ifdef __STL_MEMBER_TEMPLATES template template void slist::remove_if(Predicate pred) { list_node_base* cur = &head; while (cur->next) { if (pred(((list_node*) cur->next)->data)) erase_after(cur); else cur = cur->next; } } template template void slist::unique(BinaryPredicate pred) { list_node* cur = (list_node*) head.next; if (cur) { while (cur->next) { if (pred(((list_node*)cur)->data, ((list_node*)(cur->next))->data)) erase_after(cur); else cur = (list_node*) cur->next; } } } template template void slist::merge(slist& L, StrictWeakOrdering comp) { list_node_base* n1 = &head; while (n1->next && L.head.next) { if (comp(((list_node*) L.head.next)->data, ((list_node*) n1->next)->data)) __slist_splice_after(n1, &L.head, L.head.next); n1 = n1->next; } if (L.head.next) { n1->next = L.head.next; L.head.next = 0; } } template template void slist::sort(StrictWeakOrdering comp) { if (head.next && head.next->next) { slist carry; slist counter[64]; int fill = 0; while (!empty()) { __slist_splice_after(&carry.head, &head, head.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]); } } #endif /* __STL_MEMBER_TEMPLATES */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_SLIST_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_stack.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_STACK_H #define __SGI_STL_INTERNAL_STACK_H __STL_BEGIN_NAMESPACE #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template > #else template #endif class stack { friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&); friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&); public: typedef typename Sequence::value_type value_type; typedef typename Sequence::size_type size_type; typedef typename Sequence::reference reference; typedef typename Sequence::const_reference const_reference; protected: Sequence c; public: bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference top() { return c.back(); } const_reference top() const { return c.back(); } void push(const value_type& x) { c.push_back(x); } void pop() { c.pop_back(); } }; template bool operator==(const stack& x, const stack& y) { return x.c == y.c; } template bool operator<(const stack& x, const stack& y) { return x.c < y.c; } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_STACK_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_tempbuf.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_TEMPBUF_H #define __SGI_STL_INTERNAL_TEMPBUF_H __STL_BEGIN_NAMESPACE template pair get_temporary_buffer(ptrdiff_t len, T*) { if (len > ptrdiff_t(INT_MAX / sizeof(T))) len = INT_MAX / sizeof(T); while (len > 0) { T* tmp = (T*) malloc((size_t)len * sizeof(T)); if (tmp != 0) return pair(tmp, len); len /= 2; } return pair((T*)0, 0); } template void return_temporary_buffer(T* p) { free(p); } template ::value_type #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ > class temporary_buffer { private: ptrdiff_t original_len; ptrdiff_t len; T* buffer; void allocate_buffer() { original_len = len; buffer = 0; if (len > (ptrdiff_t)(INT_MAX / sizeof(T))) len = INT_MAX / sizeof(T); while (len > 0) { buffer = (T*) malloc(len * sizeof(T)); if (buffer) break; len /= 2; } } void initialize_buffer(const T&, __true_type) {} void initialize_buffer(const T& val, __false_type) { uninitialized_fill_n(buffer, len, val); } public: ptrdiff_t size() const { return len; } ptrdiff_t requested_size() const { return original_len; } T* begin() { return buffer; } T* end() { return buffer + len; } temporary_buffer(ForwardIterator first, ForwardIterator last) { __STL_TRY { len = 0; distance(first, last, len); allocate_buffer(); if (len > 0) initialize_buffer(*first, typename __type_traits::has_trivial_default_constructor()); } __STL_UNWIND(free(buffer); buffer = 0; len = 0); } ~temporary_buffer() { destroy(buffer, buffer + len); free(buffer); } private: temporary_buffer(const temporary_buffer&) {} void operator=(const temporary_buffer&) {} }; __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_TEMPBUF_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_tree.h ================================================ /* * * 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 __SGI_STL_INTERNAL_TREE_H #define __SGI_STL_INTERNAL_TREE_H /* 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. */ #include #include #include #include __STL_BEGIN_NAMESPACE typedef bool __rb_tree_color_type; const __rb_tree_color_type __rb_tree_red = false; const __rb_tree_color_type __rb_tree_black = true; struct __rb_tree_node_base { typedef __rb_tree_color_type color_type; typedef __rb_tree_node_base* base_ptr; color_type color; base_ptr parent; base_ptr left; base_ptr right; static base_ptr minimum(base_ptr x) { while (x->left != 0) x = x->left; return x; } static base_ptr maximum(base_ptr x) { while (x->right != 0) x = x->right; return x; } }; template struct __rb_tree_node : public __rb_tree_node_base { typedef __rb_tree_node* link_type; Value value_field; }; struct __rb_tree_base_iterator { typedef __rb_tree_node_base::base_ptr base_ptr; typedef bidirectional_iterator_tag iterator_category; typedef ptrdiff_t difference_type; base_ptr node; void increment() { if (node->right != 0) { node = node->right; while (node->left != 0) node = node->left; } else { base_ptr y = node->parent; while (node == y->right) { node = y; y = y->parent; } if (node->right != y) node = y; } } void decrement() { if (node->color == __rb_tree_red && node->parent->parent == node) node = node->right; else if (node->left != 0) { base_ptr y = node->left; while (y->right != 0) y = y->right; node = y; } else { base_ptr y = node->parent; while (node == y->left) { node = y; y = y->parent; } node = y; } } }; template struct __rb_tree_iterator : public __rb_tree_base_iterator { typedef Value value_type; typedef Ref reference; typedef Ptr pointer; typedef __rb_tree_iterator iterator; typedef __rb_tree_iterator const_iterator; typedef __rb_tree_iterator self; typedef __rb_tree_node* link_type; __rb_tree_iterator() {} __rb_tree_iterator(link_type x) { node = x; } __rb_tree_iterator(const iterator& it) { node = it.node; } reference operator*() const { return link_type(node)->value_field; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ self& operator++() { increment(); return *this; } self operator++(int) { self tmp = *this; increment(); return tmp; } self& operator--() { decrement(); return *this; } self operator--(int) { self tmp = *this; decrement(); return tmp; } }; inline bool operator==(const __rb_tree_base_iterator& x, const __rb_tree_base_iterator& y) { return x.node == y.node; } inline bool operator!=(const __rb_tree_base_iterator& x, const __rb_tree_base_iterator& y) { return x.node != y.node; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION inline bidirectional_iterator_tag iterator_category(const __rb_tree_base_iterator&) { return bidirectional_iterator_tag(); } inline __rb_tree_base_iterator::difference_type* distance_type(const __rb_tree_base_iterator&) { return (__rb_tree_base_iterator::difference_type*) 0; } template inline Value* value_type(const __rb_tree_iterator&) { return (Value*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ inline void __rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root) { __rb_tree_node_base* y = x->right; x->right = y->left; if (y->left !=0) y->left->parent = x; y->parent = x->parent; if (x == root) root = y; else if (x == x->parent->left) x->parent->left = y; else x->parent->right = y; y->left = x; x->parent = y; } inline void __rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root) { __rb_tree_node_base* y = x->left; x->left = y->right; if (y->right != 0) y->right->parent = x; y->parent = x->parent; if (x == root) root = y; else if (x == x->parent->right) x->parent->right = y; else x->parent->left = y; y->right = x; x->parent = y; } inline void __rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root) { x->color = __rb_tree_red; while (x != root && x->parent->color == __rb_tree_red) { if (x->parent == x->parent->parent->left) { __rb_tree_node_base* y = x->parent->parent->right; if (y && y->color == __rb_tree_red) { x->parent->color = __rb_tree_black; y->color = __rb_tree_black; x->parent->parent->color = __rb_tree_red; x = x->parent->parent; } else { if (x == x->parent->right) { x = x->parent; __rb_tree_rotate_left(x, root); } x->parent->color = __rb_tree_black; x->parent->parent->color = __rb_tree_red; __rb_tree_rotate_right(x->parent->parent, root); } } else { __rb_tree_node_base* y = x->parent->parent->left; if (y && y->color == __rb_tree_red) { x->parent->color = __rb_tree_black; y->color = __rb_tree_black; x->parent->parent->color = __rb_tree_red; x = x->parent->parent; } else { if (x == x->parent->left) { x = x->parent; __rb_tree_rotate_right(x, root); } x->parent->color = __rb_tree_black; x->parent->parent->color = __rb_tree_red; __rb_tree_rotate_left(x->parent->parent, root); } } } root->color = __rb_tree_black; } inline __rb_tree_node_base* __rb_tree_rebalance_for_erase(__rb_tree_node_base* z, __rb_tree_node_base*& root, __rb_tree_node_base*& leftmost, __rb_tree_node_base*& rightmost) { __rb_tree_node_base* y = z; __rb_tree_node_base* x = 0; __rb_tree_node_base* x_parent = 0; if (y->left == 0) // z has at most one non-null child. y == z. x = y->right; // x might be null. else if (y->right == 0) // z has exactly one non-null child. y == z. x = y->left; // x is not null. else { // z has two non-null children. Set y to y = y->right; // z's successor. x might be null. while (y->left != 0) y = y->left; x = y->right; } if (y != z) { // relink y in place of z. y is z's successor z->left->parent = y; y->left = z->left; if (y != z->right) { x_parent = y->parent; if (x) x->parent = y->parent; y->parent->left = x; // y must be a left child y->right = z->right; z->right->parent = y; } else x_parent = y; if (root == z) root = y; else if (z->parent->left == z) z->parent->left = y; else z->parent->right = y; y->parent = z->parent; __STD::swap(y->color, z->color); y = z; // y now points to node to be actually deleted } else { // y == z x_parent = y->parent; if (x) x->parent = y->parent; if (root == z) root = x; else if (z->parent->left == z) z->parent->left = x; else z->parent->right = x; if (leftmost == z) if (z->right == 0) // z->left must be null also leftmost = z->parent; // makes leftmost == header if z == root else leftmost = __rb_tree_node_base::minimum(x); if (rightmost == z) if (z->left == 0) // z->right must be null also rightmost = z->parent; // makes rightmost == header if z == root else // x == z->left rightmost = __rb_tree_node_base::maximum(x); } if (y->color != __rb_tree_red) { while (x != root && (x == 0 || x->color == __rb_tree_black)) if (x == x_parent->left) { __rb_tree_node_base* w = x_parent->right; if (w->color == __rb_tree_red) { w->color = __rb_tree_black; x_parent->color = __rb_tree_red; __rb_tree_rotate_left(x_parent, root); w = x_parent->right; } if ((w->left == 0 || w->left->color == __rb_tree_black) && (w->right == 0 || w->right->color == __rb_tree_black)) { w->color = __rb_tree_red; x = x_parent; x_parent = x_parent->parent; } else { if (w->right == 0 || w->right->color == __rb_tree_black) { if (w->left) w->left->color = __rb_tree_black; w->color = __rb_tree_red; __rb_tree_rotate_right(w, root); w = x_parent->right; } w->color = x_parent->color; x_parent->color = __rb_tree_black; if (w->right) w->right->color = __rb_tree_black; __rb_tree_rotate_left(x_parent, root); break; } } else { // same as above, with right <-> left. __rb_tree_node_base* w = x_parent->left; if (w->color == __rb_tree_red) { w->color = __rb_tree_black; x_parent->color = __rb_tree_red; __rb_tree_rotate_right(x_parent, root); w = x_parent->left; } if ((w->right == 0 || w->right->color == __rb_tree_black) && (w->left == 0 || w->left->color == __rb_tree_black)) { w->color = __rb_tree_red; x = x_parent; x_parent = x_parent->parent; } else { if (w->left == 0 || w->left->color == __rb_tree_black) { if (w->right) w->right->color = __rb_tree_black; w->color = __rb_tree_red; __rb_tree_rotate_left(w, root); w = x_parent->left; } w->color = x_parent->color; x_parent->color = __rb_tree_black; if (w->left) w->left->color = __rb_tree_black; __rb_tree_rotate_right(x_parent, root); break; } } if (x) x->color = __rb_tree_black; } return y; } template class rb_tree { protected: typedef void* void_pointer; typedef __rb_tree_node_base* base_ptr; typedef __rb_tree_node rb_tree_node; typedef simple_alloc rb_tree_node_allocator; typedef __rb_tree_color_type color_type; public: typedef Key key_type; typedef Value 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 size_t size_type; typedef ptrdiff_t difference_type; protected: link_type get_node() { return rb_tree_node_allocator::allocate(); } void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); } link_type create_node(const value_type& x) { link_type tmp = get_node(); __STL_TRY { construct(&tmp->value_field, x); } __STL_UNWIND(put_node(tmp)); return tmp; } link_type clone_node(link_type x) { link_type tmp = create_node(x->value_field); tmp->color = x->color; tmp->left = 0; tmp->right = 0; return tmp; } void destroy_node(link_type p) { destroy(&p->value_field); put_node(p); } protected: size_type node_count; // keeps track of size of tree link_type header; Compare key_compare; link_type& root() const { return (link_type&) header->parent; } link_type& leftmost() const { return (link_type&) header->left; } link_type& rightmost() const { return (link_type&) header->right; } static link_type& left(link_type x) { return (link_type&)(x->left); } static link_type& right(link_type x) { return (link_type&)(x->right); } static link_type& parent(link_type x) { return (link_type&)(x->parent); } static reference value(link_type x) { return x->value_field; } static const Key& key(link_type x) { return KeyOfValue()(value(x)); } static color_type& color(link_type x) { return (color_type&)(x->color); } static link_type& left(base_ptr x) { return (link_type&)(x->left); } static link_type& right(base_ptr x) { return (link_type&)(x->right); } static link_type& parent(base_ptr x) { return (link_type&)(x->parent); } static reference value(base_ptr x) { return ((link_type)x)->value_field; } static const Key& key(base_ptr x) { return KeyOfValue()(value(link_type(x)));} static color_type& color(base_ptr x) { return (color_type&)(link_type(x)->color); } static link_type minimum(link_type x) { return (link_type) __rb_tree_node_base::minimum(x); } static link_type maximum(link_type x) { return (link_type) __rb_tree_node_base::maximum(x); } public: typedef __rb_tree_iterator iterator; typedef __rb_tree_iterator const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_bidirectional_iterator reverse_iterator; typedef reverse_bidirectional_iterator const_reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ private: iterator __insert(base_ptr x, base_ptr y, const value_type& v); link_type __copy(link_type x, link_type p); void __erase(link_type x); void init() { header = get_node(); color(header) = __rb_tree_red; // used to distinguish header from // root, in iterator.operator++ root() = 0; leftmost() = header; rightmost() = header; } public: // allocation/deallocation rb_tree(const Compare& comp = Compare()) : node_count(0), key_compare(comp) { init(); } rb_tree(const rb_tree& x) : node_count(0), key_compare(x.key_compare) { header = get_node(); color(header) = __rb_tree_red; if (x.root() == 0) { root() = 0; leftmost() = header; rightmost() = header; } else { __STL_TRY { root() = __copy(x.root(), header); } __STL_UNWIND(put_node(header)); leftmost() = minimum(root()); rightmost() = maximum(root()); } node_count = x.node_count; } ~rb_tree() { clear(); put_node(header); } rb_tree& operator=(const rb_tree& x); public: // accessors: Compare key_comp() const { return key_compare; } iterator begin() { return leftmost(); } const_iterator begin() const { return leftmost(); } iterator end() { return header; } const_iterator end() const { return 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 node_count == 0; } size_type size() const { return node_count; } size_type max_size() const { return size_type(-1); } void swap(rb_tree& t) { __STD::swap(header, t.header); __STD::swap(node_count, t.node_count); __STD::swap(key_compare, t.key_compare); } public: // insert/erase pair insert_unique(const value_type& x); iterator insert_equal(const value_type& x); iterator insert_unique(iterator position, const value_type& x); iterator insert_equal(iterator position, const value_type& x); #ifdef __STL_MEMBER_TEMPLATES template void insert_unique(InputIterator first, InputIterator last); template void insert_equal(InputIterator first, InputIterator last); #else /* __STL_MEMBER_TEMPLATES */ void insert_unique(const_iterator first, const_iterator last); void insert_unique(const value_type* first, const value_type* last); void insert_equal(const_iterator first, const_iterator last); void insert_equal(const value_type* first, const value_type* last); #endif /* __STL_MEMBER_TEMPLATES */ void erase(iterator position); size_type erase(const key_type& x); void erase(iterator first, iterator last); void erase(const key_type* first, const key_type* last); void clear() { if (node_count != 0) { __erase(root()); leftmost() = header; root() = 0; rightmost() = header; node_count = 0; } } public: // 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 equal_range(const key_type& x); pair equal_range(const key_type& x) const; public: // Debugging. bool __rb_verify() const; }; template inline bool operator==(const rb_tree& x, const rb_tree& y) { return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); } template inline bool operator<(const rb_tree& x, const rb_tree& y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(rb_tree& x, rb_tree& y) { x.swap(y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template rb_tree& rb_tree:: operator=(const rb_tree& x) { if (this != &x) { // Note that Key may be a constant type. clear(); node_count = 0; key_compare = x.key_compare; if (x.root() == 0) { root() = 0; leftmost() = header; rightmost() = header; } else { root() = __copy(x.root(), header); leftmost() = minimum(root()); rightmost() = maximum(root()); node_count = x.node_count; } } return *this; } template typename rb_tree::iterator rb_tree:: __insert(base_ptr x_, base_ptr y_, const Value& v) { link_type x = (link_type) x_; link_type y = (link_type) y_; link_type z; if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) { z = create_node(v); left(y) = z; // also makes leftmost() = z when y == header if (y == header) { root() = z; rightmost() = z; } else if (y == leftmost()) leftmost() = z; // maintain leftmost() pointing to min node } else { z = create_node(v); right(y) = z; if (y == rightmost()) rightmost() = z; // maintain rightmost() pointing to max node } parent(z) = y; left(z) = 0; right(z) = 0; __rb_tree_rebalance(z, header->parent); ++node_count; return iterator(z); } template typename rb_tree::iterator rb_tree::insert_equal(const Value& v) { link_type y = header; link_type x = root(); while (x != 0) { y = x; x = key_compare(KeyOfValue()(v), key(x)) ? left(x) : right(x); } return __insert(x, y, v); } template pair::iterator, bool> rb_tree::insert_unique(const Value& v) { link_type y = header; link_type x = root(); bool comp = true; while (x != 0) { y = x; comp = key_compare(KeyOfValue()(v), key(x)); x = comp ? left(x) : right(x); } iterator j = iterator(y); if (comp) if (j == begin()) return pair(__insert(x, y, v), true); else --j; if (key_compare(key(j.node), KeyOfValue()(v))) return pair(__insert(x, y, v), true); return pair(j, false); } template typename rb_tree::iterator rb_tree::insert_unique(iterator position, const Val& v) { if (position.node == header->left) // begin() if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) return __insert(position.node, position.node, v); // first argument just needs to be non-null else return insert_unique(v).first; else if (position.node == header) // end() if (key_compare(key(rightmost()), KeyOfValue()(v))) return __insert(0, rightmost(), v); else return insert_unique(v).first; else { iterator before = position; --before; if (key_compare(key(before.node), KeyOfValue()(v)) && key_compare(KeyOfValue()(v), key(position.node))) if (right(before.node) == 0) return __insert(0, before.node, v); else return __insert(position.node, position.node, v); // first argument just needs to be non-null else return insert_unique(v).first; } } template typename rb_tree::iterator rb_tree::insert_equal(iterator position, const Val& v) { if (position.node == header->left) // begin() if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) return __insert(position.node, position.node, v); // first argument just needs to be non-null else return insert_equal(v); else if (position.node == header) // end() if (!key_compare(KeyOfValue()(v), key(rightmost()))) return __insert(0, rightmost(), v); else return insert_equal(v); else { iterator before = position; --before; if (!key_compare(KeyOfValue()(v), key(before.node)) && !key_compare(key(position.node), KeyOfValue()(v))) if (right(before.node) == 0) return __insert(0, before.node, v); else return __insert(position.node, position.node, v); // first argument just needs to be non-null else return insert_equal(v); } } #ifdef __STL_MEMBER_TEMPLATES template template void rb_tree::insert_equal(II first, II last) { for ( ; first != last; ++first) insert_equal(*first); } template template void rb_tree::insert_unique(II first, II last) { for ( ; first != last; ++first) insert_unique(*first); } #else /* __STL_MEMBER_TEMPLATES */ template void rb_tree::insert_equal(const V* first, const V* last) { for ( ; first != last; ++first) insert_equal(*first); } template void rb_tree::insert_equal(const_iterator first, const_iterator last) { for ( ; first != last; ++first) insert_equal(*first); } template void rb_tree::insert_unique(const V* first, const V* last) { for ( ; first != last; ++first) insert_unique(*first); } template void rb_tree::insert_unique(const_iterator first, const_iterator last) { for ( ; first != last; ++first) insert_unique(*first); } #endif /* __STL_MEMBER_TEMPLATES */ template inline void rb_tree::erase(iterator position) { link_type y = (link_type) __rb_tree_rebalance_for_erase(position.node, header->parent, header->left, header->right); destroy_node(y); --node_count; } template typename rb_tree::size_type rb_tree::erase(const Key& x) { pair p = equal_range(x); size_type n = 0; distance(p.first, p.second, n); erase(p.first, p.second); return n; } template typename rb_tree::link_type rb_tree::__copy(link_type x, link_type p) { // structural copy. x and p must be non-null. link_type top = clone_node(x); top->parent = p; __STL_TRY { if (x->right) top->right = __copy(right(x), top); p = top; x = left(x); while (x != 0) { link_type y = clone_node(x); p->left = y; y->parent = p; if (x->right) y->right = __copy(right(x), y); p = y; x = left(x); } } __STL_UNWIND(__erase(top)); return top; } template void rb_tree::__erase(link_type x) { // erase without rebalancing while (x != 0) { __erase(right(x)); link_type y = left(x); destroy_node(x); x = y; } } template void rb_tree::erase(iterator first, iterator last) { if (first == begin() && last == end()) clear(); else while (first != last) erase(first++); } template void rb_tree::erase(const Key* first, const Key* last) { while (first != last) erase(*first++); } template typename rb_tree::iterator rb_tree::find(const Key& k) { link_type y = header; // Last node which is not less than k. link_type x = root(); // Current node. while (x != 0) if (!key_compare(key(x), k)) y = x, x = left(x); else x = right(x); iterator j = iterator(y); return (j == end() || key_compare(k, key(j.node))) ? end() : j; } template typename rb_tree::const_iterator rb_tree::find(const Key& k) const { link_type y = header; /* Last node which is not less than k. */ link_type x = root(); /* Current node. */ while (x != 0) { if (!key_compare(key(x), k)) y = x, x = left(x); else x = right(x); } const_iterator j = const_iterator(y); return (j == end() || key_compare(k, key(j.node))) ? end() : j; } template typename rb_tree::size_type rb_tree::count(const Key& k) const { pair p = equal_range(k); size_type n = 0; distance(p.first, p.second, n); return n; } template typename rb_tree::iterator rb_tree::lower_bound(const Key& k) { link_type y = header; /* Last node which is not less than k. */ link_type x = root(); /* Current node. */ while (x != 0) if (!key_compare(key(x), k)) y = x, x = left(x); else x = right(x); return iterator(y); } template typename rb_tree::const_iterator rb_tree::lower_bound(const Key& k) const { link_type y = header; /* Last node which is not less than k. */ link_type x = root(); /* Current node. */ while (x != 0) if (!key_compare(key(x), k)) y = x, x = left(x); else x = right(x); return const_iterator(y); } template typename rb_tree::iterator rb_tree::upper_bound(const Key& k) { link_type y = header; /* Last node which is greater than k. */ link_type x = root(); /* Current node. */ while (x != 0) if (key_compare(k, key(x))) y = x, x = left(x); else x = right(x); return iterator(y); } template typename rb_tree::const_iterator rb_tree::upper_bound(const Key& k) const { link_type y = header; /* Last node which is greater than k. */ link_type x = root(); /* Current node. */ while (x != 0) if (key_compare(k, key(x))) y = x, x = left(x); else x = right(x); return const_iterator(y); } template inline pair::iterator, typename rb_tree::iterator> rb_tree::equal_range(const Key& k) { return pair(lower_bound(k), upper_bound(k)); } template inline pair::const_iterator, typename rb_tree::const_iterator> rb_tree::equal_range(const Key& k) const { return pair(lower_bound(k), upper_bound(k)); } inline int __black_count(__rb_tree_node_base* node, __rb_tree_node_base* root) { if (node == 0) return 0; else { int bc = node->color == __rb_tree_black ? 1 : 0; if (node == root) return bc; else return bc + __black_count(node->parent, root); } } template bool rb_tree::__rb_verify() const { if (node_count == 0 || begin() == end()) return node_count == 0 && begin() == end() && header->left == header && header->right == header; int len = __black_count(leftmost(), root()); for (const_iterator it = begin(); it != end(); ++it) { link_type x = (link_type) it.node; link_type L = left(x); link_type R = right(x); if (x->color == __rb_tree_red) if ((L && L->color == __rb_tree_red) || (R && R->color == __rb_tree_red)) return false; if (L && key_compare(key(x), key(L))) return false; if (R && key_compare(key(R), key(x))) return false; if (!L && !R && __black_count(x, root()) != len) return false; } if (leftmost() != __rb_tree_node_base::minimum(root())) return false; if (rightmost() != __rb_tree_node_base::maximum(root())) return false; return true; } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_TREE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_uninitialized.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H #define __SGI_STL_INTERNAL_UNINITIALIZED_H __STL_BEGIN_NAMESPACE // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. template inline ForwardIterator __uninitialized_copy_aux(InputIterator first, InputIterator last, ForwardIterator result, __true_type) { return copy(first, last, result); } template ForwardIterator __uninitialized_copy_aux(InputIterator first, InputIterator last, ForwardIterator result, __false_type) { ForwardIterator cur = result; __STL_TRY { for ( ; first != last; ++first, ++cur) construct(&*cur, *first); return cur; } __STL_UNWIND(destroy(result, cur)); } template inline ForwardIterator __uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result, T*) { typedef typename __type_traits::is_POD_type is_POD; return __uninitialized_copy_aux(first, last, result, is_POD()); } template inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result) { return __uninitialized_copy(first, last, result, value_type(result)); } inline char* uninitialized_copy(const char* first, const char* last, char* result) { 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) { memmove(result, first, sizeof(wchar_t) * (last - first)); return result + (last - first); } template pair __uninitialized_copy_n(InputIterator first, Size count, ForwardIterator result, input_iterator_tag) { ForwardIterator cur = result; __STL_TRY { for ( ; count > 0 ; --count, ++first, ++cur) construct(&*cur, *first); return pair(first, cur); } __STL_UNWIND(destroy(result, cur)); } template inline pair __uninitialized_copy_n(RandomAccessIterator first, Size count, ForwardIterator result, random_access_iterator_tag) { RandomAccessIterator last = first + count; return make_pair(last, uninitialized_copy(first, last, result)); } template inline pair uninitialized_copy_n(InputIterator first, Size count, ForwardIterator result) { return __uninitialized_copy_n(first, count, result, iterator_category(first)); } // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. template inline void __uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, const T& x, __true_type) { fill(first, last, x); } template void __uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, const T& x, __false_type) { ForwardIterator cur = first; __STL_TRY { for ( ; cur != last; ++cur) construct(&*cur, x); } __STL_UNWIND(destroy(first, cur)); } template inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x, T1*) { typedef typename __type_traits::is_POD_type is_POD; __uninitialized_fill_aux(first, last, x, is_POD()); } template inline void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x) { __uninitialized_fill(first, last, x, value_type(first)); } // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. template inline ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, __true_type) { return fill_n(first, n, x); } template ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, __false_type) { ForwardIterator cur = first; __STL_TRY { for ( ; n > 0; --n, ++cur) construct(&*cur, x); return cur; } __STL_UNWIND(destroy(first, cur)); } template inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n, const T& x, T1*) { typedef typename __type_traits::is_POD_type is_POD; return __uninitialized_fill_n_aux(first, n, x, is_POD()); } template inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x) { return __uninitialized_fill_n(first, n, x, value_type(first)); } // Copies [first1, last1) into [result, result + (last1 - first1)), and // copies [first2, last2) into // [result, result + (last1 - first1) + (last2 - first2)). template inline ForwardIterator __uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, ForwardIterator result) { ForwardIterator mid = uninitialized_copy(first1, last1, result); __STL_TRY { return uninitialized_copy(first2, last2, mid); } __STL_UNWIND(destroy(result, mid)); } // Fills [result, mid) with x, and copies [first, last) into // [mid, mid + (last - first)). template inline ForwardIterator __uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid, const T& x, InputIterator first, InputIterator last) { uninitialized_fill(result, mid, x); __STL_TRY { return uninitialized_copy(first, last, mid); } __STL_UNWIND(destroy(result, mid)); } // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and // fills [first2 + (last1 - first1), last2) with x. template inline void __uninitialized_copy_fill(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, const T& x) { ForwardIterator mid2 = uninitialized_copy(first1, last1, first2); __STL_TRY { uninitialized_fill(mid2, last2, x); } __STL_UNWIND(destroy(first2, mid2)); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_UNINITIALIZED_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stl_vector.h ================================================ /* * * 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. */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_VECTOR_H #define __SGI_STL_INTERNAL_VECTOR_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif template class vector { public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type* iterator; typedef const value_type* const_iterator; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: typedef simple_alloc data_allocator; iterator start; iterator finish; iterator end_of_storage; void insert_aux(iterator position, const T& x); void deallocate() { if (start) data_allocator::deallocate(start, end_of_storage - start); } void fill_initialize(size_type n, const T& value) { start = allocate_and_fill(n, value); finish = start + n; end_of_storage = finish; } public: iterator begin() { return start; } const_iterator begin() const { return start; } iterator end() { return finish; } const_iterator end() const { return 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 { return size_type(-1) / sizeof(T); } size_type capacity() const { return size_type(end_of_storage - begin()); } bool empty() const { return begin() == end(); } reference operator[](size_type n) { return *(begin() + n); } const_reference operator[](size_type n) const { return *(begin() + n); } vector() : start(0), finish(0), end_of_storage(0) {} vector(size_type n, const T& value) { fill_initialize(n, value); } vector(int n, const T& value) { fill_initialize(n, value); } vector(long n, const T& value) { fill_initialize(n, value); } explicit vector(size_type n) { fill_initialize(n, T()); } vector(const vector& x) { start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end()); finish = start + (x.end() - x.begin()); end_of_storage = finish; } #ifdef __STL_MEMBER_TEMPLATES template vector(InputIterator first, InputIterator last) : start(0), finish(0), end_of_storage(0) { range_initialize(first, last, iterator_category(first)); } #else /* __STL_MEMBER_TEMPLATES */ vector(const_iterator first, const_iterator last) { size_type n = 0; distance(first, last, n); start = allocate_and_copy(n, first, last); finish = start + n; end_of_storage = finish; } #endif /* __STL_MEMBER_TEMPLATES */ ~vector() { destroy(start, finish); deallocate(); } vector& operator=(const vector& x); void reserve(size_type n) { if (capacity() < n) { const size_type old_size = size(); iterator tmp = allocate_and_copy(n, start, finish); destroy(start, finish); deallocate(); start = tmp; finish = tmp + old_size; end_of_storage = start + n; } } reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(end() - 1); } const_reference back() const { return *(end() - 1); } void push_back(const T& x) { if (finish != end_of_storage) { construct(finish, x); ++finish; } else insert_aux(end(), x); } void swap(vector& x) { __STD::swap(start, x.start); __STD::swap(finish, x.finish); __STD::swap(end_of_storage, x.end_of_storage); } iterator insert(iterator position, const T& x) { size_type n = position - begin(); if (finish != end_of_storage && position == end()) { construct(finish, x); ++finish; } else insert_aux(position, x); return begin() + n; } iterator insert(iterator position) { return insert(position, T()); } #ifdef __STL_MEMBER_TEMPLATES template void insert(iterator position, InputIterator first, InputIterator last) { range_insert(position, first, last, iterator_category(first)); } #else /* __STL_MEMBER_TEMPLATES */ void insert(iterator position, const_iterator first, const_iterator last); #endif /* __STL_MEMBER_TEMPLATES */ void insert (iterator pos, size_type n, const T& x); void insert (iterator pos, int n, const T& x) { insert(pos, (size_type) n, x); } void insert (iterator pos, long n, const T& x) { insert(pos, (size_type) n, x); } void pop_back() { --finish; destroy(finish); } iterator erase(iterator position) { if (position + 1 != end()) copy(position + 1, finish, position); --finish; destroy(finish); return position; } iterator erase(iterator first, iterator last) { iterator i = copy(last, finish, first); destroy(i, finish); finish = finish - (last - first); return first; } void resize(size_type new_size, const T& x) { if (new_size < size()) erase(begin() + new_size, end()); else insert(end(), new_size - size(), x); } void resize(size_type new_size) { resize(new_size, T()); } void clear() { erase(begin(), end()); } protected: iterator allocate_and_fill(size_type n, const T& x) { iterator result = data_allocator::allocate(n); __STL_TRY { uninitialized_fill_n(result, n, x); return result; } __STL_UNWIND(data_allocator::deallocate(result, n)); } #ifdef __STL_MEMBER_TEMPLATES template iterator allocate_and_copy(size_type n, ForwardIterator first, ForwardIterator last) { iterator result = data_allocator::allocate(n); __STL_TRY { uninitialized_copy(first, last, result); return result; } __STL_UNWIND(data_allocator::deallocate(result, n)); } #else /* __STL_MEMBER_TEMPLATES */ iterator allocate_and_copy(size_type n, const_iterator first, const_iterator last) { iterator result = data_allocator::allocate(n); __STL_TRY { uninitialized_copy(first, last, result); return result; } __STL_UNWIND(data_allocator::deallocate(result, n)); } #endif /* __STL_MEMBER_TEMPLATES */ #ifdef __STL_MEMBER_TEMPLATES template void range_initialize(InputIterator first, InputIterator last, input_iterator_tag) { for ( ; first != last; ++first) push_back(*first); } // This function is only called by the constructor. We have to worry // about resource leaks, but not about maintaining invariants. template void range_initialize(ForwardIterator first, ForwardIterator last, forward_iterator_tag) { size_type n = 0; distance(first, last, n); start = allocate_and_copy(n, first, last); finish = start + n; end_of_storage = finish; } template void range_insert(iterator pos, InputIterator first, InputIterator last, input_iterator_tag); template void range_insert(iterator pos, ForwardIterator first, ForwardIterator last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ }; template inline bool operator==(const vector& x, const vector& y) { return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); } template inline bool operator<(const vector& x, const vector& y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER template inline void swap(vector& x, vector& y) { x.swap(y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ template vector& vector::operator=(const vector& x) { if (&x != this) { if (x.size() > capacity()) { iterator tmp = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end()); destroy(start, finish); deallocate(); start = tmp; end_of_storage = start + (x.end() - x.begin()); } else if (size() >= x.size()) { iterator i = copy(x.begin(), x.end(), begin()); destroy(i, finish); } else { copy(x.begin(), x.begin() + size(), start); uninitialized_copy(x.begin() + size(), x.end(), finish); } finish = start + x.size(); } return *this; } template void vector::insert_aux(iterator position, const T& x) { if (finish != end_of_storage) { construct(finish, *(finish - 1)); ++finish; T x_copy = x; copy_backward(position, finish - 2, finish - 1); *position = x_copy; } else { const size_type old_size = size(); const size_type len = old_size != 0 ? 2 * old_size : 1; iterator new_start = data_allocator::allocate(len); iterator new_finish = new_start; __STL_TRY { new_finish = uninitialized_copy(start, position, new_start); construct(new_finish, x); ++new_finish; new_finish = uninitialized_copy(position, finish, new_finish); } # ifdef __STL_USE_EXCEPTIONS catch(...) { destroy(new_start, new_finish); data_allocator::deallocate(new_start, len); throw; } # endif /* __STL_USE_EXCEPTIONS */ destroy(begin(), end()); deallocate(); start = new_start; finish = new_finish; end_of_storage = new_start + len; } } template void vector::insert(iterator position, size_type n, const T& x) { if (n != 0) { if (size_type(end_of_storage - finish) >= n) { T x_copy = x; const size_type elems_after = finish - position; iterator old_finish = finish; if (elems_after > n) { uninitialized_copy(finish - n, finish, finish); finish += n; copy_backward(position, old_finish - n, old_finish); fill(position, position + n, x_copy); } else { uninitialized_fill_n(finish, n - elems_after, x_copy); finish += n - elems_after; uninitialized_copy(position, old_finish, finish); finish += elems_after; fill(position, old_finish, x_copy); } } else { const size_type old_size = size(); const size_type len = old_size + max(old_size, n); iterator new_start = data_allocator::allocate(len); iterator new_finish = new_start; __STL_TRY { new_finish = uninitialized_copy(start, position, new_start); new_finish = uninitialized_fill_n(new_finish, n, x); new_finish = uninitialized_copy(position, finish, new_finish); } # ifdef __STL_USE_EXCEPTIONS catch(...) { destroy(new_start, new_finish); data_allocator::deallocate(new_start, len); throw; } # endif /* __STL_USE_EXCEPTIONS */ destroy(start, finish); deallocate(); start = new_start; finish = new_finish; end_of_storage = new_start + len; } } } #ifdef __STL_MEMBER_TEMPLATES template template void vector::range_insert(iterator pos, InputIterator first, InputIterator last, input_iterator_tag) { for ( ; first != last; ++first) { pos = insert(pos, *first); ++pos; } } template template void vector::range_insert(iterator position, ForwardIterator first, ForwardIterator last, forward_iterator_tag) { if (first != last) { size_type n = 0; distance(first, last, n); if (size_type(end_of_storage - finish) >= n) { const size_type elems_after = finish - position; iterator old_finish = finish; if (elems_after > n) { uninitialized_copy(finish - n, finish, finish); finish += n; copy_backward(position, old_finish - n, old_finish); copy(first, last, position); } else { ForwardIterator mid = first; advance(mid, elems_after); uninitialized_copy(mid, last, finish); finish += n - elems_after; uninitialized_copy(position, old_finish, finish); finish += elems_after; copy(first, mid, position); } } else { const size_type old_size = size(); const size_type len = old_size + max(old_size, n); iterator new_start = data_allocator::allocate(len); iterator new_finish = new_start; __STL_TRY { new_finish = uninitialized_copy(start, position, new_start); new_finish = uninitialized_copy(first, last, new_finish); new_finish = uninitialized_copy(position, finish, new_finish); } # ifdef __STL_USE_EXCEPTIONS catch(...) { destroy(new_start, new_finish); data_allocator::deallocate(new_start, len); throw; } # endif /* __STL_USE_EXCEPTIONS */ destroy(start, finish); deallocate(); start = new_start; finish = new_finish; end_of_storage = new_start + len; } } } #else /* __STL_MEMBER_TEMPLATES */ template void vector::insert(iterator position, const_iterator first, const_iterator last) { if (first != last) { size_type n = 0; distance(first, last, n); if (size_type(end_of_storage - finish) >= n) { const size_type elems_after = finish - position; iterator old_finish = finish; if (elems_after > n) { uninitialized_copy(finish - n, finish, finish); finish += n; copy_backward(position, old_finish - n, old_finish); copy(first, last, position); } else { uninitialized_copy(first + elems_after, last, finish); finish += n - elems_after; uninitialized_copy(position, old_finish, finish); finish += elems_after; copy(first, first + elems_after, position); } } else { const size_type old_size = size(); const size_type len = old_size + max(old_size, n); iterator new_start = data_allocator::allocate(len); iterator new_finish = new_start; __STL_TRY { new_finish = uninitialized_copy(start, position, new_start); new_finish = uninitialized_copy(first, last, new_finish); new_finish = uninitialized_copy(position, finish, new_finish); } # ifdef __STL_USE_EXCEPTIONS catch(...) { destroy(new_start, new_finish); data_allocator::deallocate(new_start, len); throw; } # endif /* __STL_USE_EXCEPTIONS */ destroy(start, finish); deallocate(); start = new_start; finish = new_finish; end_of_storage = new_start + len; } } } #endif /* __STL_MEMBER_TEMPLATES */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_VECTOR_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/stream.h ================================================ /* Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 _COMPAT_STREAM_H #define _COMPAT_STREAM_H // Compatibility with old library. // DO NOT USE THESE FUNCTIONS IN NEW CODE! // They are obsolete, non-standard, and non-reentrant. #define _STREAM_COMPAT #include extern "C++" { extern char* form(const char*, ...); extern char* dec(long, int=0); extern char* dec(int, int=0); extern char* dec(unsigned long, int=0); extern char* dec(unsigned int, int=0); extern char* hex(long, int=0); extern char* hex(int, int=0); extern char* hex(unsigned long, int=0); extern char* hex(unsigned int, int=0); extern char* oct(long, int=0); extern char* oct(int, int=0); extern char* oct(unsigned long, int=0); extern char* oct(unsigned int, int=0); char* chr(char ch, int width = 0); char* str(const char* s, int width = 0); inline istream& WS(istream& str) { return ws(str); } } // extern "C++" #endif /* !_COMPAT_STREAM_H */ ================================================ FILE: tass-sgi-stl-2.91.57-source/streambuf.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 _STREAMBUF_H #define _STREAMBUF_H #ifdef __GNUG__ #pragma interface #endif /* #define _G_IO_THROW */ /* Not implemented: ios::failure */ #define _IO_NEW_STREAMS // new optimizated stream representation extern "C" { #include } //#include <_G_config.h> #ifdef _G_NEED_STDARG_H #include #endif #ifndef _IO_va_list #define _IO_va_list char * #endif #ifndef EOF #define EOF (-1) #endif #ifndef NULL #ifdef __GNUG__ #define NULL (__null) #else #define NULL (0) #endif #endif #ifndef _IO_wchar_t #if _G_IO_IO_FILE_VERSION == 0x20001 #define _IO_wchar_t _G_wchar_t #else #define _IO_wchar_t short #endif #endif extern "C++" { class istream; /* Work-around for a g++ name mangling bug. Fixed in 2.6. */ class ostream; class streambuf; // In case some header files defines these as macros. #undef open #undef close #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 typedef _IO_off64_t streamoff; typedef _IO_fpos64_t streampos; #else typedef _IO_off_t streamoff; typedef _IO_fpos_t streampos; #endif typedef _IO_ssize_t streamsize; typedef unsigned long __fmtflags; typedef unsigned char __iostate; struct _ios_fields { // The data members of an ios. streambuf *_strbuf; ostream* _tie; int _width; __fmtflags _flags; _IO_wchar_t _fill; __iostate _state; __iostate _exceptions; int _precision; void *_arrays; /* Support for ios::iword and ios::pword. */ }; #define _IOS_GOOD 0 #define _IOS_EOF 1 #define _IOS_FAIL 2 #define _IOS_BAD 4 #define _IO_INPUT 1 #define _IO_OUTPUT 2 #define _IO_ATEND 4 #define _IO_APPEND 8 #define _IO_TRUNC 16 #define _IO_NOCREATE 32 #define _IO_NOREPLACE 64 #define _IO_BIN 128 #ifdef _STREAM_COMPAT enum state_value { _good = _IOS_GOOD, _eof = _IOS_EOF, _fail = _IOS_FAIL, _bad = _IOS_BAD }; enum open_mode { input = _IO_INPUT, output = _IO_OUTPUT, atend = _IO_ATEND, append = _IO_APPEND }; #endif class ios : public _ios_fields { ios& operator=(ios&); /* Not allowed! */ ios (const ios&); /* Not allowed! */ public: typedef __fmtflags fmtflags; typedef int iostate; typedef int openmode; typedef int streamsize; enum io_state { goodbit = _IOS_GOOD, eofbit = _IOS_EOF, failbit = _IOS_FAIL, badbit = _IOS_BAD }; enum open_mode { in = _IO_INPUT, out = _IO_OUTPUT, ate = _IO_ATEND, app = _IO_APPEND, trunc = _IO_TRUNC, nocreate = _IO_NOCREATE, noreplace = _IO_NOREPLACE, bin = _IOS_BIN, // Deprecated - ANSI uses ios::binary. binary = _IOS_BIN }; enum seek_dir { beg, cur, end}; typedef enum seek_dir seekdir; // NOTE: If adding flags here, before to update ios::bitalloc(). enum { skipws=_IO_SKIPWS, left=_IO_LEFT, right=_IO_RIGHT, internal=_IO_INTERNAL, dec=_IO_DEC, oct=_IO_OCT, hex=_IO_HEX, showbase=_IO_SHOWBASE, showpoint=_IO_SHOWPOINT, uppercase=_IO_UPPERCASE, showpos=_IO_SHOWPOS, scientific=_IO_SCIENTIFIC, fixed=_IO_FIXED, unitbuf=_IO_UNITBUF, stdio=_IO_STDIO #ifndef _IO_NEW_STREAMS , dont_close=_IO_DONT_CLOSE // Don't delete streambuf on stream destruction #endif }; enum { // Masks. basefield=dec+oct+hex, floatfield = scientific+fixed, adjustfield = left+right+internal }; #ifdef _IO_THROW class failure : public xmsg { ios* _stream; public: failure(ios* stream) { _stream = stream; } failure(string cause, ios* stream) { _stream = stream; } ios* rdios() const { return _stream; } }; #endif ostream* tie() const { return _tie; } ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; } // Methods to change the format state. _IO_wchar_t fill() const { return _fill; } _IO_wchar_t fill(_IO_wchar_t newf) {_IO_wchar_t oldf = _fill; _fill = newf; return oldf;} fmtflags flags() const { return _flags; } fmtflags flags(fmtflags new_val) { fmtflags old_val = _flags; _flags = new_val; return old_val; } int precision() const { return _precision; } int precision(int newp) { unsigned short oldp = _precision; _precision = (unsigned short)newp; return oldp; } fmtflags setf(fmtflags val) { fmtflags oldbits = _flags; _flags |= val; return oldbits; } fmtflags setf(fmtflags val, fmtflags mask) { fmtflags oldbits = _flags; _flags = (_flags & ~mask) | (val & mask); return oldbits; } fmtflags unsetf(fmtflags mask) { fmtflags oldbits = _flags; _flags &= ~mask; return oldbits; } int width() const { return _width; } int width(int val) { int save = _width; _width = val; return save; } #ifdef _IO_THROW void _throw_failure() const { throw new ios::failure(this); } #else void _throw_failure() const { } #endif void clear(iostate state = 0) { _state = _strbuf ? state : state|badbit; if (_state & _exceptions) _throw_failure(); } void set(iostate flag) { _state |= flag; if (_state & _exceptions) _throw_failure(); } void setstate(iostate flag) { _state |= flag; // ANSI if (_state & _exceptions) _throw_failure(); } int good() const { return _state == 0; } int eof() const { return _state & ios::eofbit; } int fail() const { return _state & (ios::badbit|ios::failbit); } int bad() const { return _state & ios::badbit; } iostate rdstate() const { return _state; } operator void*() const { return fail() ? (void*)0 : (void*)(-1); } int operator!() const { return fail(); } iostate exceptions() const { return _exceptions; } void exceptions(iostate enable) { _exceptions = enable; if (_state & _exceptions) _throw_failure(); } streambuf* rdbuf() const { return _strbuf; } streambuf* rdbuf(streambuf *_s) { streambuf *_old = _strbuf; _strbuf = _s; clear (); return _old; } static int sync_with_stdio(int on); static void sync_with_stdio() { sync_with_stdio(1); } static fmtflags bitalloc(); static int xalloc(); void*& pword(int); void* pword(int) const; long& iword(int); long iword(int) const; #ifdef _STREAM_COMPAT void unset(state_value flag) { _state &= ~flag; } void close(); int is_open(); int readable(); int writable(); #endif // Used to initialize standard streams. Not needed in this implementation. class Init { public: Init () { } }; protected: inline ios(streambuf* sb = 0, ostream* tie_to = 0); inline virtual ~ios(); inline void init(streambuf* sb, ostream* tie = 0); }; #if __GNUG__==1 typedef int _seek_dir; #else typedef ios::seek_dir _seek_dir; #endif // Magic numbers and bits for the _flags field. // The magic numbers use the high-order bits of _flags; // the remaining bits are abailable for variable flags. // Note: The magic numbers must all be negative if stdio // emulation is desired. // A streammarker remembers a position in a buffer. // You are guaranteed to be able to seek back to it if it is saving(). class streammarker : private _IO_marker { friend class streambuf; void set_offset(int offset) { _pos = offset; } public: streammarker(streambuf *sb); ~streammarker(); int saving() { return 1; } int delta(streammarker&); int delta(); }; struct streambuf : public _IO_FILE { // protected?? friend class ios; friend class istream; friend class ostream; friend class streammarker; const void *&_vtable() { return *(const void**)((_IO_FILE*)this + 1); } protected: static streambuf* _list_all; /* List of open streambufs. */ _IO_FILE*& xchain() { return _chain; } void _un_link(); void _link_in(); char* gptr() const { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_ptr; } char* pptr() const { return _IO_write_ptr; } char* egptr() const { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_end : _IO_read_end; } char* epptr() const { return _IO_write_end; } char* pbase() const { return _IO_write_base; } char* eback() const { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_base;} char* base() const { return _IO_buf_base; } char* ebuf() const { return _IO_buf_end; } int blen() const { return _IO_buf_end - _IO_buf_base; } void xput_char(char c) { *_IO_write_ptr++ = c; } int xflags() { return _IO_file_flags; } int xflags(int f) {int fl = _IO_file_flags; _IO_file_flags = f; return fl;} void xsetflags(int f) { _IO_file_flags |= f; } void xsetflags(int f, int mask) { _IO_file_flags = (_IO_file_flags & ~mask) | (f & mask); } void gbump(int n) { _IO_file_flags & _IO_IN_BACKUP ? (_IO_save_base+=n):(_IO_read_ptr+=n);} void pbump(int n) { _IO_write_ptr += n; } void setb(char* b, char* eb, int a=0); void setp(char* p, char* ep) { _IO_write_base=_IO_write_ptr=p; _IO_write_end=ep; } void setg(char* eb, char* g, char *eg) { if (_IO_file_flags & _IO_IN_BACKUP) _IO_free_backup_area(this); _IO_read_base = eb; _IO_read_ptr = g; _IO_read_end = eg; } char *shortbuf() { return _shortbuf; } int in_backup() { return _flags & _IO_IN_BACKUP; } // The start of the main get area: FIXME: wrong for write-mode filebuf? char *Gbase() { return in_backup() ? _IO_save_base : _IO_read_base; } // The end of the main get area: char *eGptr() { return in_backup() ? _IO_save_end : _IO_read_end; } // The start of the backup area: char *Bbase() { return in_backup() ? _IO_read_base : _IO_save_base; } char *Bptr() { return _IO_backup_base; } // The end of the backup area: char *eBptr() { return in_backup() ? _IO_read_end : _IO_save_end; } char *Nbase() { return _IO_save_base; } char *eNptr() { return _IO_save_end; } int have_backup() { return _IO_save_base != NULL; } int have_markers() { return _markers != NULL; } void free_backup_area(); void unsave_markers(); // Make all streammarkers !saving(). int put_mode() { return _flags & _IO_CURRENTLY_PUTTING; } int switch_to_get_mode(); streambuf(int flags=0); public: static int flush_all(); static void flush_all_linebuffered(); // Flush all line buffered files. virtual ~streambuf(); virtual int overflow(int c = EOF); // Leave public for now virtual int underflow(); // Leave public for now virtual int uflow(); // Leave public for now virtual int pbackfail(int c); // virtual int showmany (); virtual streamsize xsputn(const char* s, streamsize n); virtual streamsize xsgetn(char* s, streamsize n); virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out); streampos pubseekoff(streamoff o, _seek_dir d, int mode=ios::in|ios::out) { return _IO_seekoff (this, o, d, mode); } streampos pubseekpos(streampos pos, int mode = ios::in|ios::out) { return _IO_seekpos (this, pos, mode); } streampos sseekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); streampos sseekpos(streampos pos, int mode = ios::in|ios::out); virtual streambuf* setbuf(char* p, int len); virtual int sync(); virtual int doallocate(); int seekmark(streammarker& mark, int delta = 0); int sputbackc(char c); int sungetc(); int unbuffered() { return _flags & _IO_UNBUFFERED ? 1 : 0; } int linebuffered() { return _flags & _IO_LINE_BUF ? 1 : 0; } void unbuffered(int i) { if (i) _flags |= _IO_UNBUFFERED; else _flags &= ~_IO_UNBUFFERED; } void linebuffered(int i) { if (i) _flags |= _IO_LINE_BUF; else _flags &= ~_IO_LINE_BUF; } int allocate() { // For AT&T compatibility if (base() || unbuffered()) return 0; else return doallocate(); } // Allocate a buffer if needed; use _shortbuf if appropriate. void allocbuf() { if (base() == NULL) doallocbuf(); } void doallocbuf(); int in_avail() { return _IO_read_end - _IO_read_ptr; } int out_waiting() { return _IO_write_ptr - _IO_write_base; } streamsize sputn(const char* s, streamsize n) { return xsputn(s, n); } streamsize padn(char pad, streamsize n) { return _IO_padn(this, pad, n); } streamsize sgetn(char* s, streamsize n) { return _IO_sgetn(this, s, n); } int ignore(int); int get_column(); int set_column(int); long sgetline(char* buf, _IO_size_t n, char delim, int putback_delim); int sputc(int c) { return _IO_putc(c, this); } int sbumpc() { return _IO_getc(this); } int sgetc() { return _IO_peekc(this); } int snextc() { if (_IO_read_ptr >= _IO_read_end && __underflow(this) == EOF) return EOF; else return _IO_read_ptr++, sgetc(); } void stossc() { if (_IO_read_ptr < _IO_read_end) _IO_read_ptr++; } int vscan(char const *fmt0, _IO_va_list ap, ios* stream = NULL); int scan(char const *fmt0 ...); int vform(char const *fmt0, _IO_va_list ap); int form(char const *fmt0 ...); #if 0 /* Work in progress */ int column(); // Current column number (of put pointer). -1 is unknown. void column(int c); // Set column number of put pointer to c. #endif virtual streamsize sys_read(char* buf, streamsize size); virtual streamsize sys_write(const char*, streamsize); virtual streampos sys_seek(streamoff, _seek_dir); virtual int sys_close(); virtual int sys_stat(void*); // Actually, a (struct stat*) #if _G_IO_IO_FILE_VERSION == 0x20001 virtual int showmanyc(); virtual void imbue(void *); #endif }; // A backupbuf is a streambuf with full backup and savepoints on reading. // All standard streambufs in the GNU iostream library are backupbufs. class filebuf : public streambuf { protected: void init(); public: static const int openprot; // Non-ANSI AT&T-ism: Default open protection. filebuf(); filebuf(int fd); filebuf(int fd, char* p, int len); #if !_IO_UNIFIED_JUMPTABLES static filebuf *__new(); #endif ~filebuf(); filebuf* attach(int fd); filebuf* open(const char *filename, const char *mode); filebuf* open(const char *filename, ios::openmode mode, int prot = 0664); virtual int underflow(); virtual int overflow(int c = EOF); int is_open() const { return _fileno >= 0; } int fd() const { return is_open() ? _fileno : EOF; } filebuf* close(); virtual int doallocate(); virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); virtual streambuf* setbuf(char* p, int len); streamsize xsputn(const char* s, streamsize n); streamsize xsgetn(char* s, streamsize n); virtual int sync(); protected: // See documentation in filebuf.C. // virtual int pbackfail(int c); int is_reading() { return eback() != egptr(); } char* cur_ptr() { return is_reading() ? gptr() : pptr(); } /* System's idea of pointer */ char* file_ptr() { return eGptr(); } // Low-level operations (Usually invoke system calls.) virtual streamsize sys_read(char* buf, streamsize size); virtual streampos sys_seek(streamoff, _seek_dir); virtual streamsize sys_write(const char*, streamsize); virtual int sys_stat(void*); // Actually, a (struct stat*) virtual int sys_close(); #if 0 virtual uflow; virtual showmany; #endif }; inline void ios::init(streambuf* sb, ostream* tie_to) { _state = sb ? ios::goodbit : ios::badbit; _exceptions=0; _strbuf=sb; _tie = tie_to; _width=0; _fill=' '; #ifdef _IO_NEW_STREAMS _flags=ios::skipws|ios::dec; #else _flags=ios::skipws|ios::dec|ios::dont_close; #endif _precision=6; _arrays = 0; } inline ios::ios(streambuf* sb, ostream* tie_to) { init(sb, tie_to); } inline ios::~ios() { #ifndef _IO_NEW_STREAMS if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf(); #endif if (_arrays) delete [] _arrays; } } // extern "C++" #endif /* _STREAMBUF_H */ ================================================ FILE: tass-sgi-stl-2.91.57-source/strfile.h ================================================ /* Copyright (C) 1993, 1997 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General 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 #ifdef TODO Merge into libio.h ? #endif typedef void *(*_IO_alloc_type) __P ((_IO_size_t)); typedef void (*_IO_free_type) __P ((void*)); struct _IO_str_fields { _IO_alloc_type _allocate_buffer; _IO_free_type _free_buffer; }; /* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type, but a 32 bit pointer type. In this case, we get 4 bytes of padding after the vtable pointer. Putting them in a structure together solves this problem. */ struct _IO_streambuf { struct _IO_FILE _f; const void *_vtable; }; typedef struct _IO_strfile_ { struct _IO_streambuf _sbf; struct _IO_str_fields _s; } _IO_strfile; /* dynamic: set when the array object is allocated (or reallocated) as necessary to hold a character sequence that can change in length. */ #define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0) /* frozen: set when the program has requested that the array object not be altered, reallocated, or freed. */ #define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF) ================================================ FILE: tass-sgi-stl-2.91.57-source/string ================================================ // Main header for the -*- C++ -*- string classes. #ifndef __STRING__ #define __STRING__ #include extern "C++" { typedef basic_string string; // typedef basic_string wstring; } // extern "C++" #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/strstream ================================================ // -*- C++ -*- forwarding header. // This file is part of the GNU ANSI C++ Library. #ifndef __STRSTREAM__ #define __STRSTREAM__ #include #endif ================================================ FILE: tass-sgi-stl-2.91.57-source/strstream.h ================================================ /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 1993 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Written by Per Bothner (bothner@cygnus.com). */ #ifndef __STRSTREAM_H #define __STRSTREAM_H #ifdef __GNUG__ #pragma interface #endif #include #include extern "C++" { class strstreambuf : public streambuf { struct _IO_str_fields _s; friend class istrstream; void init_dynamic(_IO_alloc_type alloc, _IO_free_type free, int initial_size = 0); void init_static(char *ptr, int size, char *pstart); void init_readonly(const char *ptr, int size); protected: virtual int overflow(int = EOF); virtual int underflow(); virtual int pbackfail(int c); public: virtual ~strstreambuf(); strstreambuf() { init_dynamic(0, 0); } strstreambuf(int initial_size) { init_dynamic(0, 0, initial_size); } strstreambuf(void *(*alloc)(_IO_size_t), void (*free)(void*)) { init_dynamic(alloc, free); } strstreambuf(char *ptr, int size, char *pstart = NULL) { init_static(ptr, size, pstart); } strstreambuf(unsigned char *ptr, int size, unsigned char *pstart = NULL) { init_static((char*)ptr, size, (char*)pstart); } strstreambuf(const char *ptr, int size) { init_readonly(ptr, size); } strstreambuf(const unsigned char *ptr, int size) { init_readonly((const char*)ptr, size); } strstreambuf(signed char *ptr, int size, signed char *pstart = NULL) { init_static((char*)ptr, size, (char*)pstart); } strstreambuf(const signed char *ptr, int size) { init_readonly((const char*)ptr, size); } // Note: frozen() is always true if !_IO_STR_DYNAMIC(this). int frozen() { return _flags & _IO_USER_BUF ? 1 : 0; } void freeze(int n=1) { if (_IO_STR_DYNAMIC(this)) { if (n) _flags |= _IO_USER_BUF; else _flags &= ~_IO_USER_BUF; } } _IO_ssize_t pcount(); char *str(); virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); }; class strstreambase : virtual public ios { protected: strstreambuf __my_sb; public: strstreambuf* rdbuf() { return &__my_sb; } protected: strstreambase() { init (&__my_sb); } strstreambase(char *cp, int n, int mode=ios::out); }; class istrstream : public strstreambase, public istream { public: istrstream(const char*, int=0); }; class ostrstream : public strstreambase, public ostream { public: ostrstream() { } ostrstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){} _IO_ssize_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); } char *str() { return ((strstreambuf*)_strbuf)->str(); } void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); } int frozen() { return ((strstreambuf*)_strbuf)->frozen(); } }; class strstream : public strstreambase, public iostream { public: strstream() { } strstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){} _IO_ssize_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); } char *str() { return ((strstreambuf*)_strbuf)->str(); } void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); } int frozen() { return ((strstreambuf*)_strbuf)->frozen(); } }; } // extern "C++" #endif /*!__STRSTREAM_H*/ ================================================ FILE: tass-sgi-stl-2.91.57-source/tempbuf.h ================================================ /* * * 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 __SGI_STL_TEMPBUF_H #define __SGI_STL_TEMPBUF_H #ifndef __SGI_STL_PAIR_H #include #endif #include #include #include #ifndef __TYPE_TRAITS_H #include #endif #ifndef __SGI_STL_INTERNAL_CONSTRUCT_H #include #endif #ifndef __SGI_STL_INTERNAL_TEMPBUF_H #include #endif #ifdef __STL_USE_NAMESPACES using __STD::get_temporary_buffer; using __STD::return_temporary_buffer; using __STD::temporary_buffer; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_TEMPBUF_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/tree.h ================================================ /* * * 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. * * */ #ifndef __SGI_STL_TREE_H #define __SGI_STL_TREE_H #ifndef __SGI_STL_INTERNAL_TREE_H #include #endif #include #include #ifdef __STL_USE_NAMESPACES using __STD::rb_tree; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_TREE_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/type_traits.h ================================================ /* * * 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 __TYPE_TRAITS_H #define __TYPE_TRAITS_H #ifndef __STL_CONFIG_H #include #endif /* This header file provides a framework for allowing compile time dispatch based on type attributes. This is useful when writing template code. For example, when making a copy of an array of an unknown type, it helps to know if the type has a trivial copy constructor or not, to help decide if a memcpy can be used. The class template __type_traits provides a series of typedefs each of which is either __true_type or __false_type. The argument to __type_traits can be any type. The typedefs within this template will attain their correct values by one of these means: 1. The general instantiation contain conservative values which work for all types. 2. Specializations may be declared to make distinctions between types. 3. Some compilers (such as the Silicon Graphics N32 and N64 compilers) will automatically provide the appropriate specializations for all types. EXAMPLE: //Copy an array of elements which have non-trivial copy constructors template void copy(T* source,T* destination,int n,__false_type); //Copy an array of elements which have trivial copy constructors. Use memcpy. template void copy(T* source,T* destination,int n,__true_type); //Copy an array of any type by using the most efficient copy mechanism template inline void copy(T* source,T* destination,int n) { copy(source,destination,n,typename __type_traits::has_trivial_copy_constructor()); } */ struct __true_type { }; struct __false_type { }; template struct __type_traits { typedef __true_type this_dummy_member_must_be_first; /* Do not remove this member. It informs a compiler which automatically specializes __type_traits that this __type_traits template is special. It just makes sure that things work if an implementation is using a template called __type_traits for something unrelated. */ /* The following restrictions should be observed for the sake of compilers which automatically produce type specific specializations of this class: - You may reorder the members below if you wish - You may remove any of the members below if you wish - You must not rename members without making the corresponding name change in the compiler - Members you add will be treated like regular members unless you add the appropriate support in the compiler. */ typedef __false_type has_trivial_default_constructor; typedef __false_type has_trivial_copy_constructor; typedef __false_type has_trivial_assignment_operator; typedef __false_type has_trivial_destructor; typedef __false_type is_POD_type; }; // Provide some specializations. This is harmless for compilers that // have built-in __types_traits support, and essential for compilers // that don't. __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ #endif /* __TYPE_TRAITS_H */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/utility ================================================ /* * * 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 __SGI_STL_UTILITY #define __SGI_STL_UTILITY #include #include #include #endif /* __SGI_STL_UTILITY */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/vector ================================================ /* * * 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 __SGI_STL_VECTOR #define __SGI_STL_VECTOR #include #include #include #include #include #include #endif /* __SGI_STL_VECTOR */ // Local Variables: // mode:C++ // End: ================================================ FILE: tass-sgi-stl-2.91.57-source/vector.h ================================================ /* * * 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 __SGI_STL_VECTOR_H #define __SGI_STL_VECTOR_H #include #include #include #ifdef __STL_USE_NAMESPACES using __STD::vector; #endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_VECTOR_H */ // Local Variables: // mode:C++ // End: