diff options
author | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-10-05 11:27:02 +0000 |
---|---|---|
committer | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-10-05 11:27:02 +0000 |
commit | 1d487acac02f71846ad17cadad3e4cb1cca9f799 (patch) | |
tree | bc187d782ab1e9dceb01b0464aef31982b570007 | |
parent | 9abe66a77ccab7e9ed4178b9840186fefacf36ff (diff) | |
download | gcc-1d487acac02f71846ad17cadad3e4cb1cca9f799.tar.gz |
2000-10-05 Benjamin Kosnik <bkoz@cygnus.com>
* include: New directory.
* include/backward: New directory.
* include/bits: New directory.
* include/ext: New directory.
* include/std: New directory.
* include/*/*: Populate.
* src/complex.cc: Adjust include of mathconf.
* mkc++config (BASE_H): Add include.
* src/Makefile.am: Support for topleve sources include directory.
(INCLUDES): Add LIBMATH_INCLUDE.
* src/Makefile.in: Regenerate.
* math/Makefile.am (INCLUDES): Append /include.
* math/Makefile.in: Regenerate.
* libio/Makefile.am (INCLUDES): Add glibcpp_includedir.
* libio/Makefile.in: Regenerate.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36723 138bc75d-0d04-0410-961f-82ee72b054a4
210 files changed, 51297 insertions, 0 deletions
diff --git a/libstdc++-v3/include/backward/algo.h b/libstdc++-v3/include/backward/algo.h new file mode 100644 index 00000000000..b46d3242309 --- /dev/null +++ b/libstdc++-v3/include/backward/algo.h @@ -0,0 +1,114 @@ +/* + * + * 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 _CPP_BACKWARD_ALGO_H +#define _CPP_BACKWARD_ALGO_H 1 + +#include "algobase.h" +#include "tempbuf.h" +#include <bits/stl_algo.h> +#include <bits/stl_numeric.h> + +#ifdef __STL_USE_NAMESPACES + +// Names from <stl_algo.h> +using __STD::for_each; +using __STD::find; +using __STD::find_if; +using __STD::adjacent_find; +using __STD::count; +using __STD::count_if; +using __STD::search; +using __STD::search_n; +using __STD::swap_ranges; +using __STD::transform; +using __STD::replace; +using __STD::replace_if; +using __STD::replace_copy; +using __STD::replace_copy_if; +using __STD::generate; +using __STD::generate_n; +using __STD::remove; +using __STD::remove_if; +using __STD::remove_copy; +using __STD::remove_copy_if; +using __STD::unique; +using __STD::unique_copy; +using __STD::reverse; +using __STD::reverse_copy; +using __STD::rotate; +using __STD::rotate_copy; +using __STD::random_shuffle; +using __STD::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 stl_numeric.h +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 /* _CPP_BACKWARD_ALGO_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/algobase.h b/libstdc++-v3/include/backward/algobase.h new file mode 100644 index 00000000000..b5c807a882f --- /dev/null +++ b/libstdc++-v3/include/backward/algobase.h @@ -0,0 +1,71 @@ +/* + * + * 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 _CPP_BACKWARD_ALGOBASE_H +#define _CPP_BACKWARD_ALGOBASE_H 1 + +#ifndef _CPP_BACKWARD_PAIR_H +#include "pair.h" +#endif +#ifndef _CPP_BACKWARD_ITERATOR_H +#include "iterator.h" +#endif +#ifndef _CPP_BITS_STL__ALGOBASE_H +#include <bits/stl_algobase.h> +#endif +#ifndef _CPP_BITS_STL_UNINITIALIZED_H +#include <bits/stl_uninitialized.h> +#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 /* _CPP_BACKWARD_ALGOBASE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/alloc.h b/libstdc++-v3/include/backward/alloc.h new file mode 100644 index 00000000000..3ec1304a8e7 --- /dev/null +++ b/libstdc++-v3/include/backward/alloc.h @@ -0,0 +1,48 @@ +/* + * 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 _CPP_BACKWARD_ALLOC_H +#define _CPP_BACKWARD_ALLOC_H 1 + +#ifndef _CPP_BITS_STL_CONFIG_H +#include <bits/stl_config.h> +#endif +#ifndef _CPP_BITS_STL_ALLOC_H +#include <bits/stl_alloc.h> +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::__malloc_alloc_template; +using __STD::malloc_alloc; +using __STD::simple_alloc; +using __STD::debug_alloc; +#ifndef __USE_MALLOC +using __STD::__default_alloc_template; +#endif +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 /* _CPP_BACKWARD_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/bvector.h b/libstdc++-v3/include/backward/bvector.h new file mode 100644 index 00000000000..ed922540485 --- /dev/null +++ b/libstdc++-v3/include/backward/bvector.h @@ -0,0 +1,51 @@ +/* + * + * 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 _CPP_BACKWARD_BVECTOR_H +#define _CPP_BACKWARD_BVECTOR_H 1 + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +#include "vector.h" +#else +#include "algobase.h" +#include "alloc.h" +#endif + +#include <bits/stl_bvector.h> + +#ifdef __STL_USE_NAMESPACES + +using __STD::bit_vector; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_BVECTOR_H */ + +// Local Variables: +// mode:C++ +// End: + + diff --git a/libstdc++-v3/include/backward/complex.h b/libstdc++-v3/include/backward/complex.h new file mode 100644 index 00000000000..97e0852068b --- /dev/null +++ b/libstdc++-v3/include/backward/complex.h @@ -0,0 +1,47 @@ + +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BACKWARD_COMPLEX_H +#define _CPP_BACKWARD_COMPLEX_H 1 + +#include <bits/stl_config.h> +#include <bits/std_complex.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::complex; +#endif /* __STL_USE_NAMESPACES */ + +typedef complex<float> float_complex; +typedef complex<double> double_complex; +typedef complex<long double> long_double_complex; + +#endif /* _CPP_BACKWARD_COMPLEX_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/defalloc.h b/libstdc++-v3/include/backward/defalloc.h new file mode 100644 index 00000000000..8edee690bc6 --- /dev/null +++ b/libstdc++-v3/include/backward/defalloc.h @@ -0,0 +1,87 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +// Inclusion of this file is DEPRECATED. This is the original HP +// default allocator. It is provided only for backward compatibility. +// This file WILL BE REMOVED in a future release. +// +// DO NOT USE THIS FILE unless you have an old container implementation +// that requires an allocator with the HP-style interface. +// +// Standard-conforming allocators have a very different interface. The +// standard default allocator is declared in the header <memory>. + +#ifndef _CPP_BACKWARD_DEFALLOC_H +#define _CPP_BACKWARD_DEFALLOC_H 1 + +#include "new.h" +#include <stddef.h> +#include <stdlib.h> +#include <limits.h> +#include "iostream.h" +#include "algobase.h" + + +template <class _Tp> +inline _Tp* allocate(ptrdiff_t __size, _Tp*) { + set_new_handler(0); + _Tp* __tmp = (_Tp*)(::operator new((size_t)(__size * sizeof(_Tp)))); + if (__tmp == 0) { + cerr << "out of memory" << endl; + exit(1); + } + return __tmp; +} + + +template <class _Tp> +inline void deallocate(_Tp* __buffer) { + ::operator delete(__buffer); +} + +template <class _Tp> +class allocator { +public: + typedef _Tp value_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + pointer allocate(size_type __n) { + return ::allocate((difference_type)__n, (pointer)0); + } + void deallocate(pointer __p) { ::deallocate(__p); } + pointer address(reference __x) { return (pointer)&__x; } + const_pointer const_address(const_reference __x) { + return (const_pointer)&__x; + } + size_type init_page_size() { + return max(size_type(1), size_type(4096/sizeof(_Tp))); + } + size_type max_size() const { + return max(size_type(1), size_type(UINT_MAX/sizeof(_Tp))); + } +}; + +class allocator<void> { +public: + typedef void* pointer; +}; + + + +#endif /* _CPP_BACKWARD_DEFALLOC_H */ diff --git a/libstdc++-v3/include/backward/deque.h b/libstdc++-v3/include/backward/deque.h new file mode 100644 index 00000000000..fc47056c5ee --- /dev/null +++ b/libstdc++-v3/include/backward/deque.h @@ -0,0 +1,42 @@ +/* + * + * 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 _CPP_BACKWARD_DEQUE_H +#define _CPP_BACKWARD_DEQUE_H 1 + +#include "algobase.h" +#include "alloc.h" +#include <bits/std_deque.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::deque; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_DEQUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/fstream.h b/libstdc++-v3/include/backward/fstream.h new file mode 100644 index 00000000000..a346faf994c --- /dev/null +++ b/libstdc++-v3/include/backward/fstream.h @@ -0,0 +1,50 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BACKWARD_FSTREAM_H +#define _CPP_BACKWARD_FSTREAM_H 1 + +#include <bits/std_fstream.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::ifstream; +using __STD::ofstream; +using __STD::fstream; + +#ifdef _GLIBCPP_USE_WCHAR_T +using __STD::wifstream; +using __STD::wofstream; +using __STD::wfstream; +#endif + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_FSTREAM_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/function.h b/libstdc++-v3/include/backward/function.h new file mode 100644 index 00000000000..7988ae99c2b --- /dev/null +++ b/libstdc++-v3/include/backward/function.h @@ -0,0 +1,118 @@ +/* + * + * 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 _CPP_BACKWARD_FUNCTION_H +#define _CPP_BACKWARD_FUNCTION_H 1 + +#ifndef _CPP_BITS_STL_CONFIG_H +#include <bits/stl_config.h> +#endif +#ifndef _CPP_BITS_STL_RELOPS +#include <bits/stl_relops.h> +#endif +#include <stddef.h> +#ifndef _CPP_BITS_STL_FUNCTION_H +#include <bits/stl_function.h> +#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 /* _CPP_BACKWARD_FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/hash_map.h b/libstdc++-v3/include/backward/hash_map.h new file mode 100644 index 00000000000..ebf0cb8f84b --- /dev/null +++ b/libstdc++-v3/include/backward/hash_map.h @@ -0,0 +1,49 @@ +/* + * 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 _CPP_BACKWARD_HASH_MAP_H +#define _CPP_BACKWARD_HASH_MAP_H 1 + +#ifndef _CPP_BITS_STL_HASHTABLE_H +#include <bits/stl_hashtable.h> +#endif + +#include "algobase.h" +#include <bits/stl_hash_map.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +using __STD::hash_map; +using __STD::hash_multimap; +#endif /* __STL_USE_NAMESPACES */ + + +#endif /* _CPP_BACKWARD_HASH_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/hash_set.h b/libstdc++-v3/include/backward/hash_set.h new file mode 100644 index 00000000000..140ce6048c6 --- /dev/null +++ b/libstdc++-v3/include/backward/hash_set.h @@ -0,0 +1,44 @@ +/* + * 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 _CPP_BACKWARD_HASH_SET_H +#define _CPP_BACKWARD_HASH_SET_H 1 + +#ifndef _CPP_BITS_STL_HASHTABLE_H +#include <bits/stl_hashtable.h> +#endif + +#include "algobase.h" +#include <bits/stl_hash_set.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +using __STD::hash_set; +using __STD::hash_multiset; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_HASH_SET_H */ diff --git a/libstdc++-v3/include/backward/hashtable.h b/libstdc++-v3/include/backward/hashtable.h new file mode 100644 index 00000000000..bd0f4f47433 --- /dev/null +++ b/libstdc++-v3/include/backward/hashtable.h @@ -0,0 +1,48 @@ +/* + * 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 _CPP_BACKWARD_HASHTABLE_H +#define _CPP_BACKWARD_HASHTABLE_H 1 + +#include <bits/stl_hashtable.h> +#include "algo.h" +#include "alloc.h" +#include "vector.h" + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_HASHTABLE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/heap.h b/libstdc++-v3/include/backward/heap.h new file mode 100644 index 00000000000..0256fc62e7e --- /dev/null +++ b/libstdc++-v3/include/backward/heap.h @@ -0,0 +1,46 @@ +/* + * + * 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 _CPP_BACKWARD_HEAP_H +#define _CPP_BACKWARD_HEAP_H 1 + +#include <bits/stl_config.h> +#include <bits/stl_heap.h> + +#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 /* _CPP_BACKWARD_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/iomanip.h b/libstdc++-v3/include/backward/iomanip.h new file mode 100644 index 00000000000..206a3880b66 --- /dev/null +++ b/libstdc++-v3/include/backward/iomanip.h @@ -0,0 +1,48 @@ + +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BACKWARD_IOMANIP_H +#define _CPP_BACKWARD_IOMANIP_H 1 + +#include <backward/iostream.h> +#include <bits/std_iomanip.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::resetiosflags; +using __STD::setiosflags; +using __STD::setbase; +using __STD::setfill; +using __STD::setprecision; +using __STD::setw; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_IOMANIP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/iostream.h b/libstdc++-v3/include/backward/iostream.h new file mode 100644 index 00000000000..2caee39adc4 --- /dev/null +++ b/libstdc++-v3/include/backward/iostream.h @@ -0,0 +1,60 @@ + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BACKWARD_IOSTREAM_H +#define _CPP_BACKWARD_IOSTREAM_H 1 + +#include <bits/std_iostream.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::iostream; +using __STD::ostream; +using __STD::istream; +using __STD::ios; +using __STD::streambuf; + +using __STD::cout; +using __STD::cin; +using __STD::cerr; +using __STD::clog; +#ifdef _GLIBCPP_USE_WCHAR_T +using __STD::wcout; +using __STD::wcin; +using __STD::wcerr; +using __STD::wclog; +#endif + +using __STD::endl; +using __STD::ends; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_IOSTREAM_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/istream.h b/libstdc++-v3/include/backward/istream.h new file mode 100644 index 00000000000..f45709267eb --- /dev/null +++ b/libstdc++-v3/include/backward/istream.h @@ -0,0 +1,37 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BACKWARD_ISTREAM_H +#define _CPP_BACKWARD_ISTREAM_H 1 + +#include <backward/iostream.h> + +#endif /* _CPP_BACKWARD_ISTREAM_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/iterator.h b/libstdc++-v3/include/backward/iterator.h new file mode 100644 index 00000000000..40185036b3b --- /dev/null +++ b/libstdc++-v3/include/backward/iterator.h @@ -0,0 +1,104 @@ +/* + * + * 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 _CPP_BACKWARD_ITERATOR_H +#define _CPP_BACKWARD_ITERATOR_H 1 + +#ifndef _CPP_BACKWARD_FUNCTION_H +#include "function.h" +#endif +#include <stddef.h> +#include "iostream.h" +#ifndef _CPP_BITS_STL_ITERATOR_H +#include <bits/stl_iterator.h> +#endif +#ifndef _CPP_BITS_TYPE_TRAITS_H +#include <bits/type_traits.h> +#endif +#ifndef _CPP_BITS_STL_CONSTRUCT_H +#include <bits/stl_construct.h> +#endif +#ifndef _CPP_BITS_STL_RAW_STORAGE_ITERATOR_H +#include <bits/stl_raw_storage_iter.h> +#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 /* _CPP_BACKWARD_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/list.h b/libstdc++-v3/include/backward/list.h new file mode 100644 index 00000000000..9a719ff9594 --- /dev/null +++ b/libstdc++-v3/include/backward/list.h @@ -0,0 +1,42 @@ +/* + * + * 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 _CPP_BACKWARD_LIST_H +#define _CPP_BACKWARD_LIST_H 1 + +#include <bits/stl_algobase.h> +#include "alloc.h" +#include <bits/std_list.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::list; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_LIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/map.h b/libstdc++-v3/include/backward/map.h new file mode 100644 index 00000000000..cf0fe2bc638 --- /dev/null +++ b/libstdc++-v3/include/backward/map.h @@ -0,0 +1,41 @@ +/* + * + * 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 _CPP_BACKWARD_MAP_H +#define _CPP_BACKWARD_MAP_H 1 + +#include "tree.h" +#include <bits/stl_map.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::map; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/multimap.h b/libstdc++-v3/include/backward/multimap.h new file mode 100644 index 00000000000..157e3331aa9 --- /dev/null +++ b/libstdc++-v3/include/backward/multimap.h @@ -0,0 +1,41 @@ +/* + * + * 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 _CPP_BACKWARD_MULTIMAP_H +#define _CPP_BACKWARD_MULTIMAP_H 1 + +#include "tree.h" +#include <bits/stl_multimap.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::multimap; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_MULTIMAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/multiset.h b/libstdc++-v3/include/backward/multiset.h new file mode 100644 index 00000000000..270a5da8ca3 --- /dev/null +++ b/libstdc++-v3/include/backward/multiset.h @@ -0,0 +1,41 @@ +/* + * + * 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 _CPP_BACKWARD_MULTISET_H +#define _CPP_BACKWARD_MULTISET_H 1 + +#include "tree.h" +#include <bits/stl_multiset.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::multiset; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_MULTISET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/new.h b/libstdc++-v3/include/backward/new.h new file mode 100644 index 00000000000..20e57dee8de --- /dev/null +++ b/libstdc++-v3/include/backward/new.h @@ -0,0 +1,46 @@ + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BACKWARD_NEW_H +#define _CPP_BACKWARD_NEW_H 1 + +#include <bits/std_new.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::bad_alloc; +using __STD::nothrow_t; +using __STD::nothrow; +using __STD::new_handler; +using __STD::set_new_handler; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_NEW_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/ostream.h b/libstdc++-v3/include/backward/ostream.h new file mode 100644 index 00000000000..740588a277b --- /dev/null +++ b/libstdc++-v3/include/backward/ostream.h @@ -0,0 +1,37 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BACKWARD_OSTREAM_H +#define _CPP_BACKWARD_OSTREAM_H 1 + +#include <backward/iostream.h> + +#endif /* _CPP_BACKWARD_OSTREAM_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/pair.h b/libstdc++-v3/include/backward/pair.h new file mode 100644 index 00000000000..275a205bb6e --- /dev/null +++ b/libstdc++-v3/include/backward/pair.h @@ -0,0 +1,51 @@ +/* + * + * 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 _CPP_BACKWARD_PAIR_H +#define _CPP_BACKWARD_PAIR_H 1 + +#ifndef _CPP_BITS_STL_CONFIG_H +#include <bits/stl_config.h> +#endif +#ifndef _CPP_BITS_STL_RELOPS_H +#include <bits/stl_relops.h> +#endif +#ifndef _CPP_BITS_STL_PAIR_H +#include <bits/stl_pair.h> +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::pair; +using __STD::make_pair; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/rope.h b/libstdc++-v3/include/backward/rope.h new file mode 100644 index 00000000000..7d32f87497e --- /dev/null +++ b/libstdc++-v3/include/backward/rope.h @@ -0,0 +1,34 @@ +/* + * 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 _CPP_BACKWARD_ROPE_H +#define _CPP_BACKWARD_ROPE_H 1 + +#include "hashtable.h" +#include <bits/stl_rope.h> + +#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 /* _CPP_BACKWARD_ROPE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/set.h b/libstdc++-v3/include/backward/set.h new file mode 100644 index 00000000000..e05890e046e --- /dev/null +++ b/libstdc++-v3/include/backward/set.h @@ -0,0 +1,41 @@ +/* + * + * 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 _CPP_BACKWARD_SET_H +#define _CPP_BACKWARD_SET_H 1 + +#include "tree.h" +#include <bits/stl_set.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::set; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/slist.h b/libstdc++-v3/include/backward/slist.h new file mode 100644 index 00000000000..8c63282d1ca --- /dev/null +++ b/libstdc++-v3/include/backward/slist.h @@ -0,0 +1,28 @@ +/* + * 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 _CPP_BACKWARD_SLIST_H +#define _CPP_BACKWARD_SLIST_H 1 + +#include <ext/slist> + +#ifdef __STL_USE_NAMESPACES +using __STD::slist; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/stack.h b/libstdc++-v3/include/backward/stack.h new file mode 100644 index 00000000000..4140f409970 --- /dev/null +++ b/libstdc++-v3/include/backward/stack.h @@ -0,0 +1,46 @@ +/* + * + * 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 _CPP_BACKWARD_STACK_H +#define _CPP_BACKWARD_STACK_H 1 + +#include "vector.h" +#include "deque.h" +#include "heap.h" +#include <bits/stl_stack.h> +#include <bits/stl_queue.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::stack; +using __STD::queue; +using __STD::priority_queue; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_STACK_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/stream.h b/libstdc++-v3/include/backward/stream.h new file mode 100644 index 00000000000..f829b0dd577 --- /dev/null +++ b/libstdc++-v3/include/backward/stream.h @@ -0,0 +1,37 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BACKWARD_STREAM_H +#define _CPP_BACKWARD_STREAM_H 1 + +#include <backward/iostream.h> + +#endif /* _CPP_BACKWARD_STREAM_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/strstream.h b/libstdc++-v3/include/backward/strstream.h new file mode 100644 index 00000000000..f693fcd54de --- /dev/null +++ b/libstdc++-v3/include/backward/strstream.h @@ -0,0 +1,44 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BACKWARD_STRSTREAM_H +#define _CPP_BACKWARD_STRSTREAM_H 1 + +#include <bits/std_strstream.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::strstreambuf; +using __STD::istrstream; +using __STD::ostrstream; +using __STD::strstream; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_STRSTREAM_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/tempbuf.h b/libstdc++-v3/include/backward/tempbuf.h new file mode 100644 index 00000000000..82e5c8e811b --- /dev/null +++ b/libstdc++-v3/include/backward/tempbuf.h @@ -0,0 +1,62 @@ +/* + * + * 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 _CPP_BACKWARD_TEMPBUF_H +#define _CPP_BACKWARD_TEMPBUF_H 1 + +#ifndef _CPP_BACKWARD_PAIR_H +#include "pair.h" +#endif +#include <iterator.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#ifndef _CPP_BITS_TYPE_TRAITS_H +#include <bits/type_traits.h> +#endif +#ifndef _CPP_BITS_STL_CONSTRUCT_H +#include <bits/stl_construct.h> +#endif +#ifndef _CPP_BITS_STL_UNINITIALIZED_H +#include <bits/stl_uninitialized.h> +#endif +#ifndef _CPP_BITS_STL_TEMPBUF_H +#include <bits/stl_tempbuf.h> +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::get_temporary_buffer; +using __STD::return_temporary_buffer; +using __STD::_Temporary_buffer; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_TEMPBUF_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/tree.h b/libstdc++-v3/include/backward/tree.h new file mode 100644 index 00000000000..64e89ad36fe --- /dev/null +++ b/libstdc++-v3/include/backward/tree.h @@ -0,0 +1,46 @@ +/* + * + * 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 _CPP_BACKWARD_TREE_H +#define _CPP_BACKWARD_TREE_H 1 + +#ifndef _CPP_BITS_STL_TREE_H +#include <bits/stl_tree.h> +#endif +#include "algobase.h" +#include "alloc.h" + +#ifdef __STL_USE_NAMESPACES +using __STD::rb_tree; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_TREE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/backward/vector.h b/libstdc++-v3/include/backward/vector.h new file mode 100644 index 00000000000..8a7e8f94040 --- /dev/null +++ b/libstdc++-v3/include/backward/vector.h @@ -0,0 +1,42 @@ +/* + * + * 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 _CPP_BACKWARD_VECTOR_H +#define _CPP_BACKWARD_VECTOR_H 1 + +#include "algobase.h" +#include "alloc.h" +#include <bits/stl_vector.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::vector; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* _CPP_BACKWARD_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/basic_file.h b/libstdc++-v3/include/bits/basic_file.h new file mode 100644 index 00000000000..3c8430b3264 --- /dev/null +++ b/libstdc++-v3/include/bits/basic_file.h @@ -0,0 +1,340 @@ +// Wrapper of C-language FILE struct -*- C++ -*- + +// Copyright (C) 1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8 File-based streams +// + +#ifndef _CPP_BASIC_FILE +#define _CPP_BASIC_FILE 1 + +#include <bits/c++config.h> +#include <bits/std_ios.h> + +namespace std { + + // Ulrich is going to make some detailed comment here, explaining + // all this unpleasantness, providing detailed performance analysis + // as to why we have to do all this lame vtable hacking instead of a + // sane, function-based approach. This verbage will provide a clear + // and detailed description of the whole object-layout, + // vtable-swapping, sordid history of this hack. + template<typename _CharT> + struct __basic_file_base: public __c_file_type + { + virtual + ~__basic_file_base() { }; + + virtual int + overflow(int __c = EOF) = 0; + + virtual int + underflow() = 0; + + virtual int + uflow() = 0; + + virtual int + pbackfail(int __c) = 0; + + virtual streamsize + xsputn(const _CharT* __s, streamsize __n) = 0; + + virtual streamsize + xsgetn(_CharT* __s, streamsize __n) = 0; + + virtual streamoff + seekoff(streamoff __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out) = 0; + + virtual streamoff + seekpos(streamoff __pos, + ios_base::openmode __mode = ios_base::in | ios_base::out) = 0; + + virtual streambuf* + setbuf(_CharT* __b, int __len) = 0; + + virtual int + sync() = 0; + + virtual int + doallocate() = 0; + + virtual streamsize + sys_read(_CharT* __s, streamsize __n) = 0; + + virtual streamsize + sys_write(const _CharT* __s, streamsize __n) = 0; + + virtual streamoff + sys_seek(streamoff __off, ios_base::seekdir __way) = 0; + + virtual int + sys_close() = 0; + + virtual int + sys_stat(void* __v) = 0; + + virtual int + showmanyc() = 0; + + virtual void + imbue(void* __v) = 0; + }; + + // Some of these member functions are based on libio/filebuf.cc. + // Also note that the order and number of virtual functions has to precisely + // match the order and number in the _IO_jump_t struct defined in libioP.h. + template<typename _CharT> +#if _GLIBCPP_BASIC_FILE_INHERITANCE + class __basic_file: public __basic_file_base<_CharT> +#else + class __basic_file +#endif + { +#if _GLIBCPP_BASIC_FILE_ENCAPSULATION + int _M_fileno; + __c_file_type* _M_cfile; +#endif + __c_wfile_type _M_wfile; + + public: + __basic_file(__c_lock* __lock = 0); + + void + _M_open_mode(ios_base::openmode __mode, int& __p_mode, int& __rw_mode); + + // Eqivalent to the normal fopen function. + __basic_file* + open(const char* __name, ios_base::openmode __mode, int __prot = 0664); + + // Used for opening the standard streams, cin, cout, cerr, clog, + // and their wide-stream equivalents. Instead of calling open, it + // just sets __c_file_type->_fileno and the respective _flags bits, and + // returns. + __basic_file* + sys_open(int __fd, ios_base::openmode __mode); + + __basic_file* + close(); + + bool + is_open(); + + // Needed by ios_base::sync_with_stdio. + int get_fileno(void); + + // NB: Must match FILE specific jump table starting here--this + // means all virtual functions starting with the dtor must match, + // slot by slot. For glibc-based dystems, this means the _IO_FILE + // as the FILE struct and _IO_jump_t as the jump table. + virtual + ~__basic_file(); // Takes the place of __finish. + + virtual int + overflow(int __c = EOF); + + virtual int + underflow(); + + virtual int + uflow(); + + virtual int + pbackfail(int __c); + + // A complex "write" function that sets all of __c_file_type's + // ponters and associated data members correctly and manages it's + // relation to the external byte sequence. + virtual streamsize + xsputn(const _CharT* __s, streamsize __n); + + // A complex "read" function that sets all of __c_file_type's + // ponters and associated data members correctly and manages it's + // relation to the external byte sequence. + virtual streamsize + xsgetn(_CharT* __s, streamsize __n); + + // A complex "seekoff" function that sets all of __c_file_type's + // ponters and associated data members correctly and manages it's + // relation to the external byte sequence. + virtual streamoff + seekoff(streamoff __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + // A complex "seekpos" function that sets all of __c_file_type's + // pointers and associated data members correctly and manages it's + // relation to the external byte sequence. + virtual streamoff + seekpos(streamoff __pos, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + virtual streambuf* + setbuf(_CharT* __b, int __len); + + virtual int + sync(); + + virtual int + doallocate(); + + // A simple read function for the external byte sequence, that + // does no mucking around with or setting of the pointers or flags + // in __c_file_type. + virtual streamsize + sys_read(_CharT* __s, streamsize __n); + + // A simple write function for the external byte sequence, that + // does no mucking around with or setting of the pointers or flags + // in __c_file_type. + virtual streamsize + sys_write(const _CharT* __s, streamsize __n); + + // A simple seek function for the external byte sequence, that + // does no mucking around with or setting of the pointers or flags + // in __c_file_type. + virtual streamoff + sys_seek(streamoff __off, ios_base::seekdir __way); + + virtual int + sys_close(); + + virtual int + sys_stat(void* __v); + + virtual int + showmanyc(); + + virtual void + imbue(void* __v); + }; + + // __basic_file<char> specializations + template<> + __basic_file<char>::__basic_file(__c_lock* __lock); + + template<> + int + __basic_file<char>::overflow(int __c); + + template<> + int + __basic_file<char>::underflow(); + + template<> + int + __basic_file<char>::uflow(); + + template<> + int + __basic_file<char>::pbackfail(int __c); + + template<> + streamsize + __basic_file<char>::xsputn(const char* __s, streamsize __n); + + template<> + streamoff + __basic_file<char>::seekoff(streamoff __off, ios_base::seekdir __way, + ios_base::openmode __mode); + + template<> + streamoff + __basic_file<char>::seekpos(streamoff __pos, ios_base::openmode __mode); + + template<> + streambuf* + __basic_file<char>::setbuf(char* __b, int __len); + + template<> + int + __basic_file<char>::sync(); + + template<> + int + __basic_file<char>::doallocate(); + + // __basic_file<wchar_t> specializations +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + __basic_file<wchar_t>::__basic_file(__c_lock* __lock); + + template<> + int + __basic_file<wchar_t>::overflow(int __c); + + template<> + int + __basic_file<wchar_t>::underflow(); + + template<> + int + __basic_file<wchar_t>::uflow(); + + template<> + int + __basic_file<wchar_t>::pbackfail(int __c); + + template<> + streamsize + __basic_file<wchar_t>::xsputn(const wchar_t* __s, streamsize __n); + + template<> + streamoff + __basic_file<wchar_t>::seekoff(streamoff __off, ios_base::seekdir __way, + ios_base::openmode __mode); + + template<> + streamoff + __basic_file<wchar_t>::seekpos(streamoff __pos, ios_base::openmode __mode); + + template<> + streambuf* + __basic_file<wchar_t>::setbuf(wchar_t* __b, int __len); + + template<> + int + __basic_file<wchar_t>::sync(); + + template<> + int + __basic_file<wchar_t>::doallocate(); +#endif + +} // namespace std + +#endif /* _CPP_BASIC_FILE */ + + + + + + + + diff --git a/libstdc++-v3/include/bits/basic_ios.h b/libstdc++-v3/include/bits/basic_ios.h new file mode 100644 index 00000000000..7cac68b74c2 --- /dev/null +++ b/libstdc++-v3/include/bits/basic_ios.h @@ -0,0 +1,216 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BITS_BASICIOS_H +#define _CPP_BITS_BASICIOS_H 1 + +#include <bits/sbuf_iter.h> + +namespace std { + + // 27.4.5 Template class basic_ios + template<typename _CharT, typename _Traits> + class basic_ios : public ios_base + { + public: + + // Types: + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + // Non-standard Types: + typedef ctype<_CharT> __ctype_type; + // From ostream + typedef ostreambuf_iterator<_CharT> __ostreambuf_iter; + typedef num_put<_CharT, __ostreambuf_iter> __numput_type; + typedef istreambuf_iterator<_CharT> __istreambuf_iter; + typedef num_get<_CharT, __istreambuf_iter> __numget_type; + + // Data members: + private: + basic_ostream<_CharT, _Traits>* _M_tie; + char_type _M_fill; + iostate _M_exception; + + protected: + basic_streambuf<_CharT, _Traits>* _M_streambuf; + iostate _M_streambuf_state; + + // Cached use_facet<ctype>, which is based on the current locale info. + const __ctype_type* _M_ios_fctype; + // From ostream. + const __numput_type* _M_fnumput; + // From istream. + const __numget_type* _M_fnumget; + + public: + + inline const __ctype_type* + _M_get_fctype_ios(void) + { return _M_ios_fctype; } + + inline const __numget_type* + _M_get_fnumget(void) + { return _M_fnumget; } + + inline const __numput_type* + _M_get_fnumput(void) + { return _M_fnumput; } + + operator void*() const + { return this->fail() ? 0 : const_cast<basic_ios*>(this); } + + inline bool + operator!() const + { return this->fail(); } + + inline iostate + rdstate() const + { return _M_streambuf_state; } + + inline void + clear(iostate __state = goodbit) + { + if (this->rdbuf()) + _M_streambuf_state = __state; + else + _M_streambuf_state = __state | badbit; + if ((this->rdstate() & this->exceptions())) + throw failure("basic_ios::clear(iostate) caused exception"); + } + + inline void + setstate(iostate __state) + { this->clear(this->rdstate() | __state); } + + inline bool + good() const + { return this->rdstate() == 0; } + + inline bool + eof() const + { return (this->rdstate() & eofbit) != 0; } + + inline bool + fail() const + { return (this->rdstate() & (badbit | failbit)) != 0; } + + inline bool + bad() const + { return (this->rdstate() & badbit) != 0; } + + inline iostate + exceptions() const + { return _M_exception; } + + inline void + exceptions(iostate __except) + { + _M_exception = __except; + this->clear(_M_streambuf_state); + } + + // Constructor/destructor: + explicit + basic_ios(basic_streambuf<_CharT, _Traits>* __sb) : ios_base() + { this->init(__sb); } + + virtual + ~basic_ios() { } + + // Members: + inline basic_ostream<_CharT, _Traits>* + tie() const + { return _M_tie; } + + inline basic_ostream<_CharT, _Traits>* + tie(basic_ostream<_CharT, _Traits>* __tiestr) + { + basic_ostream<_CharT, _Traits>* __old = _M_tie; + _M_tie = __tiestr; + return __old; + } + + inline basic_streambuf<_CharT, _Traits>* + rdbuf() const + { return _M_streambuf; } + + basic_streambuf<_CharT, _Traits>* + rdbuf(basic_streambuf<_CharT, _Traits>* __sb); + + basic_ios& + copyfmt(const basic_ios& __rhs); + + inline char_type + fill() const + { return _M_fill; } + + inline char_type + fill(char_type __ch) + { + char_type __old = _M_fill; + _M_fill = __ch; + return __old; + } + + // Locales: + locale + imbue(const locale& __loc); + + char + narrow(char_type __c, char __dfault) const; + + char_type + widen(char __c) const; + + protected: + // 27.4.5.1 basic_ios constructors + basic_ios() : ios_base() + { } + + void + init(basic_streambuf<_CharT, _Traits>* __sb); + }; + +} // namespace std + +#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT +# define export +//#include <bits/basic_ios.tcc> +#endif + +#endif /* _CPP_BITS_BASICIOS_H */ + + + + + diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc new file mode 100644 index 00000000000..54d5efd19bc --- /dev/null +++ b/libstdc++-v3/include/bits/basic_ios.tcc @@ -0,0 +1,142 @@ +// basic_ios locale and locale-related member functions -*- C++ -*- + +// Copyright (C) 1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_BITS_BASICIOS_TCC +#define _CPP_BITS_BASICIOS_TCC 1 + +namespace std { + + template<typename _CharT, typename _Traits> + basic_streambuf<_CharT, _Traits>* + basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb) + { + basic_streambuf<_CharT, _Traits>* __old = _M_streambuf; + _M_streambuf = __sb; + this->clear(); + return __old; + } + + template<typename _CharT, typename _Traits> + basic_ios<_CharT, _Traits>& + basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) + { + // Per 27.1.1.1, do not call imbue, yet must trash all caches + // associated with imbue() + + // Alloc any new word array first, so if it fails we have "rollback". + _Words* __words = (__rhs._M_word_limit <= _S_local_words) ? + _M_word_array : new _Words[__rhs._M_word_limit]; + + // XXX This is the only reason _Callback_list was defined + // inline. The suspicion is that this increased compilation + // times dramatically for functions that use this member + // function (inserters_extractors, ios_manip_fmtflags). FIX ME, + // clean this stuff up. Callbacks are broken right now, anyway. + + // Bump refs before doing callbacks, for safety. + _Callback_list* __cb = __rhs._M_callbacks; + if (__cb) + __cb->_M_add_reference(); + _M_call_callbacks(erase_event); + if (_M_words != _M_word_array) + delete [] _M_words; + _M_dispose_callbacks(); + + _M_callbacks = __cb; // NB: Don't want any added during above. + for (int __i = 0; __i < __rhs._M_word_limit; ++__i) + __words[__i] = __rhs._M_words[__i]; + if (_M_words != _M_word_array) + delete [] _M_words; + _M_words = __words; + _M_word_limit = __rhs._M_word_limit; + + this->flags(__rhs.flags()); + this->width(__rhs.width()); + this->precision(__rhs.precision()); + this->tie(__rhs.tie()); + this->fill(__rhs.fill()); + // The next is required to be the last assignment. + this->exceptions(__rhs.exceptions()); + + _M_call_callbacks(copyfmt_event); + return *this; + } + + template<typename _CharT, typename _Traits> + char + basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const + { return _M_ios_fctype->narrow(__c, __dfault); } + + template<typename _CharT, typename _Traits> + _CharT + basic_ios<_CharT, _Traits>::widen(char __c) const + { return _M_ios_fctype->widen(__c); } + + // Locales: + template<typename _CharT, typename _Traits> + locale + basic_ios<_CharT, _Traits>::imbue(const locale& __loc) + { + locale __old(this->getloc()); + ios_base::imbue(__loc); + _M_ios_fctype = &use_facet<__ctype_type>(__loc); + _M_fnumput = &use_facet<__numput_type>(__loc); + _M_fnumget = &use_facet<__numget_type>(__loc); + if (this->rdbuf() != 0) + this->rdbuf()->pubimbue(__loc); + return __old; + } + + template<typename _CharT, typename _Traits> + void + basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb) + { + // NB: This may be called more than once on the same object. + ios_base::_M_init(); + locale __loc = this->getloc(); + _M_ios_fctype = &use_facet<__ctype_type>(__loc); + // Should be filled in by ostream and istream, respectively. + _M_fnumput = &use_facet<__numput_type>(__loc); + _M_fnumget = &use_facet<__numget_type>(__loc); + _M_tie = 0; + _M_fill = this->widen(' '); + _M_exception = goodbit; + _M_streambuf = __sb; + iostate __state = __sb ? goodbit : badbit; + _M_streambuf_state = __state; + } + +} // namespace std + +#endif /* _CPP_BITS_BASICIOS_TCC */ + + + + + diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h new file mode 100644 index 00000000000..60795f7b72e --- /dev/null +++ b/libstdc++-v3/include/bits/basic_string.h @@ -0,0 +1,1038 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +#ifndef _CPP_BITS_STRING_H +#define _CPP_BITS_STRING_H 1 + +#include <bits/exception_support.h> +#include <bits/atomicity.h> + +namespace std { + + // Documentation? What's that? + // Nathan Myers <ncm@cantrip.org>. + // + // A string looks like this: + // + // [_Rep] + // _M_length + // [basic_string<char_type>] _M_capacity + // _M_dataplus _M_state + // _M_p ----------------> unnamed array of char_type + + // Where the _M_p points to the first character in the string, and + // you cast it to a pointer-to-_Rep and subtract 1 to get a + // pointer to the header. + + // This approach has the enormous advantage that a string object + // requires only one allocation. All the ugliness is confined + // within a single pair of inline functions, which each compile to + // a single "add" instruction: _Rep::_M_data(), and + // string::_M_rep(); and the allocation function which gets a + // block of raw bytes and with room enough and constructs a _Rep + // object at the front. + + // The reason you want _M_data pointing to the character array and + // not the _Rep is so that the debugger can see the string + // contents. (Probably we should add a non-inline member to get + // the _Rep for the debugger to use, so users can check the actual + // string length.) + + // Note that the _Rep object is a POD so that you can have a + // static "empty string" _Rep object already "constructed" before + // static constructors have run. The reference-count encoding is + // chosen so that a 0 indicates one reference, so you never try to + // destroy the empty-string _Rep object. + + // All but the last paragraph is considered pretty conventional + // for a C++ string implementation. + + // 21.3 Template class basic_string + template<typename _CharT, typename _Traits, typename _Alloc> + class basic_string + { + // Types: + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + typedef typename _Alloc::size_type size_type; + typedef typename _Alloc::difference_type difference_type; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef __normal_iterator<pointer, basic_string> iterator; + typedef __normal_iterator<const_pointer, basic_string> const_iterator; + typedef reverse_iterator<const_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; + + private: + // _Rep: string representation + // Invariants: + // 1. String really contains _M_length + 1 characters; last is set + // to 0 only on call to c_str(). We avoid instantiating + // _CharT() where the interface does not require it. + // 2. _M_capacity >= _M_length + // Allocated memory is always _M_capacity + (1 * sizeof(_CharT)). + // 3. _M_references has three states: + // -1: leaked, one reference, no ref-copies allowed, non-const. + // 0: one reference, non-const. + // n>0: n + 1 references, operations require a lock, const. + // 4. All fields==0 is an empty string, given the extra storage + // beyond-the-end for a null terminator; thus, the shared + // empty string representation needs no constructor. + + struct _Rep + { + // Types: + typedef typename _Alloc::rebind<char>::other _Raw_bytes_alloc; + + // (Public) Data members: + + // The maximum number of individual char_type elements of an + // individual string is determined by _S_max_size. This is the + // value that will be returned by max_size(). (Whereas npos + // is the maximum number of bytes the allocator can allocate.) + // If one was to divvy up the theoretical largest size string, + // with a terminating character and m _CharT elements, it'd + // look like this: + // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) + // Solving for m: + // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 + // In addition, this implementation quarters this ammount. + static size_type _S_max_size; + static _CharT _S_terminal; + + size_type _M_length; + size_type _M_capacity; + _Atomic_word _M_references; + + bool + _M_is_leaked() const + { return _M_references < 0; } + + bool + _M_is_shared() const + { return _M_references > 0; } + + void + _M_set_leaked() + { _M_references = -1; } + + void + _M_set_sharable() + { _M_references = 0; } + + _CharT* + _M_refdata() throw() + { return reinterpret_cast<_CharT*> (this + 1); } + + _CharT& + operator[](size_t __s) throw() + { return _M_refdata() [__s]; } + + _CharT* + _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) + { return (!_M_is_leaked() && __alloc1 == __alloc2) ? + _M_refcopy() : _M_clone(__alloc1); } + + // Create & Destroy + static _Rep* + _S_create(size_t, const _Alloc&); + + void + _M_dispose(const _Alloc& __a) + { + if (__exchange_and_add(&_M_references, -1) <= 0) + _M_destroy(__a); + } // XXX MT + + void + _M_destroy(const _Alloc&) throw(); + + _CharT* + _M_refcopy() throw() + { + __atomic_add(&_M_references, 1); + return _M_refdata(); + } // XXX MT + + _CharT* + _M_clone(const _Alloc&, size_type __res = 0); + +#if _GLIBCPP_ALLOC_CONTROL + // These function pointers allow you to modify the allocation + // policy used by the string classes. By default they expand by + // powers of two, but this may be excessive for space-critical + // applications. + + // Returns true if ALLOCATED is too much larger than LENGTH + static bool (*_S_excess_slop) (size_t __length, size_t __allocated); + + inline static bool + __default_excess(size_t, size_t); +#else + inline static bool + _S_excess_slop(size_t, size_t); +#endif + }; + + // Use empty-base optimization: http://www.cantrip.org/emptyopt.html + struct _Alloc_hider : _Alloc + { + _Alloc_hider(_CharT* __dat, const _Alloc& __a) + : _Alloc(__a), _M_p(__dat) { } + + _CharT* _M_p; // The actual data. + }; + + public: + // Data Members (public): + // NB: This is an unsigned type, and thus represents the maximum + // size that the allocator can hold. + static const size_type npos = static_cast<size_type>(-1); + + private: + // Data Members (private): + mutable _Alloc_hider _M_dataplus; + + // The following storage is init'd to 0 by the linker, resulting + // (carefully) in an empty string with one reference. + static size_type _S_empty_rep_storage[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)]; + + _CharT* + _M_data() const + { return _M_dataplus._M_p; } + + _CharT* + _M_data(_CharT* __p) + { return (_M_dataplus._M_p = __p); } + + _Rep* + _M_rep() const + { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } + + // For the internal use we have functions similar to `begin'/`end' + // but they do not call _M_leak. + iterator + _M_ibegin() const { return iterator(_M_data()); } + + iterator + _M_iend() const { return iterator(_M_data() + this->size()); } + + void + _M_leak() // for use in begin() & non-const op[] + { + if (!_M_rep()->_M_is_leaked()) + _M_leak_hard(); + } + + iterator + _M_check(size_type __pos) const + { + __OUTOFRANGE(__pos > this->size()); + return _M_ibegin() + __pos; + } + + // NB: _M_fold doesn't check for a bad __pos1 value. + iterator + _M_fold(size_type __pos, size_type __off) const + { + bool __testoff = __off < this->size() - __pos; + size_type __newoff = __testoff ? __off : this->size() - __pos; + return (_M_ibegin() + __pos + __newoff); + } + + // _S_copy_chars is a separate template to permit specialization + // to optimize for the common case of pointers as iterators. + template<class _Iterator> + static void + _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + { + for (; __k1 != __k2; ++__k1, ++__p) + traits_type::assign(*__p, *__k1); //these types are off + } + + static void + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) + { traits_type::copy(__p, __k1, __k2 - __k1); } + + static void + _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + { traits_type::copy(__p, __k1, __k2 - __k1); } + + void + _M_mutate(size_type __pos, size_type __len1, size_type __len2); + + void + _M_leak_hard(); + + static _Rep& + _S_empty_rep() + { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); } + + public: + // Construct/copy/destroy: + // NB: We overload ctors in some cases instead of using default + // arguments, per 17.4.4.4 para. 2 item 2. + + inline + basic_string(); + + explicit + basic_string(const _Alloc& __a); + + // NB: per LWG issue 42, semantics different from IS: + basic_string(const basic_string& __str); + basic_string(const basic_string& __str, size_type __pos, + size_type __n = npos); + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a); + + basic_string(const _CharT* __s, size_type __n, + const _Alloc& __a = _Alloc()); + basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()); + basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()); + + template<class _InputIterator> + basic_string(_InputIterator __begin, _InputIterator __end, + const _Alloc& __a = _Alloc()); + + ~basic_string() + { _M_rep()->_M_dispose(this->get_allocator()); } + + basic_string& + operator=(const basic_string& __str) { return this->assign(__str); } + + basic_string& + operator=(const _CharT* __s) { return this->assign(__s); } + + basic_string& + operator=(_CharT __c) { return this->assign(1, __c); } + + // Iterators: + iterator + begin() + { + _M_leak(); + return iterator(_M_data()); + } + + const_iterator + begin() const + { return const_iterator(_M_data()); } + + iterator + end() + { + _M_leak(); + return iterator(_M_data() + this->size()); + } + + const_iterator + end() const + { return const_iterator(_M_data() + this->size()); } + + reverse_iterator + rbegin() + { return reverse_iterator(this->end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->end()); } + + reverse_iterator + rend() + { return reverse_iterator(this->begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->begin()); } + + public: + // Capacity: + size_type + size() const { return _M_rep()->_M_length; } + + size_type + length() const { return _M_rep()->_M_length; } + + size_type + max_size() const { return _Rep::_S_max_size; } + + void + resize(size_type __n, _CharT __c); + + void + resize(size_type __n) { this->resize(__n, _CharT()); } + + size_type + capacity() const { return _M_rep()->_M_capacity; } + + void + reserve(size_type __res_arg = 0); + + void + clear() { _M_mutate(0, this->size(), 0); } + + bool + empty() const { return this->size() == 0; } + + // Element access: + const_reference + operator[] (size_type __pos) const + { return _M_data()[__pos]; } + + reference + operator[](size_type __pos) + { + _M_leak(); + return _M_data()[__pos]; + } + + const_reference + at(size_type __n) const + { + __OUTOFRANGE(__n >= this->size()); + return _M_data()[__n]; + } + + reference + at(size_type __n) + { + __OUTOFRANGE(__n >= size()); + _M_leak(); + return _M_data()[__n]; + } + + // Modifiers: + basic_string& + operator+=(const basic_string& __str) { return this->append(__str); } + + basic_string& + operator+=(const _CharT* __s) { return this->append(__s); } + + basic_string& + operator+=(_CharT __c) { return this->append(size_type(1), __c); } + + basic_string& + append(const basic_string& __str); + + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n); + + basic_string& + append(const _CharT* __s, size_type __n); + + basic_string& + append(const _CharT* __s) + { return this->append(__s, traits_type::length(__s)); } + + basic_string& + append(size_type __n, _CharT __c); + + template<class _InputIterator> + basic_string& + append(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_iend(), _M_iend(), __first, __last); } + + void + push_back(_CharT __c) + { this->replace(_M_iend(), _M_iend(), 1, __c); } + + basic_string& + assign(const basic_string& __str); + + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { + return this->assign(__str._M_check(__pos), __str._M_fold(__pos, __n)); + } + + basic_string& + assign(const _CharT* __s, size_type __n) + { return this->assign(__s, __s + __n); } + + basic_string& + assign(const _CharT* __s) + { return this->assign(__s, __s + traits_type::length(__s)); } + + basic_string& + assign(size_type __n, _CharT __c) + { return this->replace(_M_ibegin(), _M_iend(), __n, __c); } + + template<class _InputIterator> + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } + + void + insert(iterator __p, size_type __n, _CharT __c) + { this->replace(__p, __p, __n, __c); } + + template<class _InputIterator> + void insert(iterator __p, _InputIterator __beg, _InputIterator __end) + { this->replace(__p, __p, __beg, __end); } + + basic_string& + insert(size_type __pos1, const basic_string& __str) + { + iterator __p = _M_check(__pos1); + this->replace(__p, __p, __str._M_ibegin(), __str._M_iend()); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { + iterator __p = _M_check(__pos1); + this->replace(__p, __p, __str._M_check(__pos2), + __str._M_fold(__pos2, __n)); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { + iterator __p = _M_check(__pos); + this->replace(__p, __p, __s, __s + __n); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s) + { return this->insert(__pos, __s, traits_type::length(__s)); } + + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { + this->insert(_M_check(__pos), __n, __c); + return *this; + } + + iterator + insert(iterator __p, _CharT __c = _CharT()) + { + size_type __pos = __p - _M_ibegin(); + this->insert(_M_check(__pos), size_type(1), __c); + _M_rep()->_M_set_leaked(); + return this->_M_ibegin() + __pos; + } + + basic_string& + erase(size_type __pos = 0, size_type __n = npos) + { + return this->replace(_M_check(__pos), _M_fold(__pos, __n), + _M_data(), _M_data()); + } + + iterator + erase(iterator __position) + { + size_type __i = __position - _M_ibegin(); + this->replace(__position, __position + 1, _M_data(), _M_data()); + _M_rep()->_M_set_leaked(); + return _M_ibegin() + __i; + } + + iterator + erase(iterator __first, iterator __last) + { + size_type __i = __first - _M_ibegin(); + this->replace(__first, __last, _M_data(), _M_data()); + _M_rep()->_M_set_leaked(); + return _M_ibegin() + __i; + } + + basic_string& + replace(size_type __pos, size_type __n, const basic_string& __str) + { + return this->replace(_M_check(__pos), _M_fold(__pos, __n), + __str.begin(), __str.end()); + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2); + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + return this->replace(_M_check(__pos), _M_fold(__pos, __n1), + __s, __s + __n2); + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + return this->replace(_M_check(__pos), _M_fold(__pos, __n1), + __s, __s + traits_type::length(__s)); + } + + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { + return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); + } + + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { return this->replace(__i1, __i2, __str.begin(), __str.end()); } + + basic_string& + replace(iterator __i1, iterator __i2, + const _CharT* __s, size_type __n) + { return this->replace(__i1, __i2, __s, __s + __n); } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { return this->replace(__i1, __i2, __s, + __s + traits_type::length(__s)); } + + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c); + + template<class _InputIterator> + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { return _M_replace(__i1, __i2, __k1, __k2, + typename iterator_traits<_InputIterator>::iterator_category()); } + + private: + template<class _InputIterator> + basic_string& + _M_replace(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, input_iterator_tag); + + template<class _FwdIterator> + basic_string& + _M_replace(iterator __i1, iterator __i2, _FwdIterator __k1, + _FwdIterator __k2, forward_iterator_tag); + + // _S_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIter is an integral type + template<class _InIter> + static _CharT* + _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a, + __false_type) + { + typedef typename iterator_traits<_InIter>::iterator_category _Tag; + return _S_construct(__beg, __end, __a, _Tag()); + } + + template<class _InIter> + static _CharT* + _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a, + __true_type) + { + return _S_construct(static_cast<size_type>(__beg), + static_cast<value_type>(__end), __a); + } + + template<class _InIter> + static _CharT* + _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a) + { + typedef typename _Is_integer<_InIter>::_Integral _Integral; + return _S_construct_aux(__beg, __end, __a, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template<class _InIter> + static _CharT* + _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, + input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template<class _FwdIter> + static _CharT* + _S_construct(_FwdIter __end, _FwdIter __beg, const _Alloc& __a, + forward_iterator_tag); + + static _CharT* + _S_construct(size_type __req, _CharT __c, const _Alloc& __a); + + public: + + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + + void + swap(basic_string<_CharT, _Traits, _Alloc>& __s); + + // String operations: + const _CharT* + c_str() const + { + // MT: This assumes concurrent writes are OK. + size_type __n = this->size(); + traits_type::assign(_M_data()[__n], _Rep::_S_terminal); + return _M_data(); + } + + const _CharT* + data() const { return _M_data(); } + + allocator_type + get_allocator() const { return _M_dataplus; } + + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; + + size_type + find(const basic_string& __str, size_type __pos = 0) const + { return this->find(__str.data(), __pos, __str.size()); } + + size_type + find(const _CharT* __s, size_type __pos = 0) const + { return this->find(__s, __pos, traits_type::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 this->rfind(__str.data(), __pos, __str.size()); } + + 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 this->rfind(__s, __pos, traits_type::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 this->find_first_of(__str.data(), __pos, __str.size()); } + + 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 this->find_first_of(__s, __pos, traits_type::length(__s)); } + + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return this->find(__c, __pos); } + + size_type + find_last_of(const basic_string& __str, size_type __pos = npos) const + { return this->find_last_of(__str.data(), __pos, __str.size()); } + + 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 this->find_last_of(__s, __pos, traits_type::length(__s)); } + + size_type + find_last_of(_CharT __c, size_type __pos = npos) const + { return this->rfind(__c, __pos); } + + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + { return this->find_first_not_of(__str.data(), __pos, __str.size()); } + + 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 this->find_first_not_of(__s, __pos, traits_type::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 this->find_last_not_of(__str.data(), __pos, __str.size()); } + + 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 this->find_last_not_of(__s, __pos, traits_type::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 + { + __OUTOFRANGE(__pos > this->size()); + return basic_string(*this, __pos, __n); + } + + int + compare(const basic_string& __str) const + { + size_type __size = this->size(); + size_type __osize = __str.size(); + size_type __len = min(__size, __osize); + + int __r = traits_type::compare(_M_data(), __str.data(), __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + int + compare(size_type __pos, size_type __n, const basic_string& __str) const; + + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const; + + int + compare(const _CharT* __s) const; + + int + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2 = npos) const; + + private: + static const _CharT* + _S_find(const _CharT* __beg, const _CharT* __end, _CharT __c); + }; + + + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_string<_CharT, _Traits, _Alloc>:: + basic_string() + : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { } + + // operator+ + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc> + operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str(__lhs); + __str.append(__size_type(1), __rhs); + return __str; + } + + // operator == + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) == 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) == 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) == 0; } + + // operator != + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) != 0; } + + // operator < + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) < 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) < 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) > 0; } + + // operator > + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) > 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) > 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) < 0; } + + // operator <= + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) <= 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) <= 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) >= 0; } + + // operator >= + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) >= 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) >= 0; } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) <= 0; } + + + template<typename _CharT, typename _Traits, typename _Alloc> + inline void + swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, + basic_string<_CharT, _Traits, _Alloc>& __rhs) + { __lhs.swap(__rhs); } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str); + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT, _Traits, _Alloc>& __str); + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_istream<_CharT,_Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim); + + template<typename _CharT, typename _Traits, typename _Alloc> + inline basic_istream<_CharT,_Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str); + +} // namespace std + +#endif /* _CPP_BITS_STRING_H */ diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config new file mode 100644 index 00000000000..07667353a04 --- /dev/null +++ b/libstdc++-v3/include/bits/c++config @@ -0,0 +1,72 @@ +// Predefined symbols and macros -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_CPPCONFIG +#define _CPP_CPPCONFIG 1 + +// The current version of the C++ library in compressed ISO date format. +#define __GLIBCPP__ 20000911 + +// By enabling this, all GNU extensions are enabled. +#define _GNU_SOURCE 1 + +// By enabling this, all ISO C99, ISO C9X functionality is enabled. +#define _ISOC99_SOURCE 1 + +// This flag controls the error handling in string, and perhaps other +// bits as time goes on: check out bits/basic_string.h for more +// info. It also helps alleviate the circular dependency between +// string and exception. +# define _GLIBCPP_USE_EXCEPTIONS 1 + +// This is necessary until Egcs supports separate template +// compilation. +#define _GLIBCPP_NO_TEMPLATE_EXPORT 1 + +// This is a hack around not having either pre-compiled headers or +// export compilation. If defined, the io, string, and valarray +// headers will include all the necessary bits. If not defined, the +// implementation optimizes the headers for the most commonly-used +// types. For the io library, this means that larger, out-of-line +// member functions are only declared, and definitions are not parsed +// by the compiler, but instead instantiated into the library binary. +//#define _GLIBCPP_FULLY_COMPLIANT_HEADERS 1 + +// To enable older, ARM-style iostreams and other anachronisms use this. +//#define _GLIBCPP_DEPRICATED 1 + +// Use corrected code from the committee library group's issues list. +# define _GLIBCPP_RESOLVE_LIB_DEFECTS 1 + + + + + + + diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h new file mode 100644 index 00000000000..baab72293c3 --- /dev/null +++ b/libstdc++-v3/include/bits/char_traits.h @@ -0,0 +1,307 @@ +// Character Traits for use by standard string and iostream -*- C++ -*- + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +#ifndef _CPP_BITS_CHAR_TRAITS_H +#define _CPP_BITS_CHAR_TRAITS_H 1 + +#include <bits/std_cwchar.h> // For mbstate_t. +#include <bits/std_cstring.h> // For memmove, memset, memchr +#include <bits/fpos.h> // For streamoff, streamsize + +namespace std { + + // Same as iosfwd +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // Can't have self-recursive types for streampos. + // 21.1.3.1 char_traits sets size_type to streampos + // 27.4.1 + // And here, where streampos is typedefed to fpos<traits::state_type> + typedef fpos<mbstate_t> streampos; +# ifdef _GLIBCPP_USE_WCHAR_T + typedef fpos<mbstate_t> wstreampos; +# endif +#endif + + // 21.1.2 Basis for explicit _Traits specialization + // NB: That for any given actual character type this definition is + // probably wrong. + + template<class _CharT> + struct char_traits + { + typedef _CharT char_type; + // Unsigned as wint_t in unsigned. + typedef unsigned long int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (!eq(__s1[__i], __s2[__i])) + return lt(__s1[__i], __s2[__i]) ? -1 : 1; + return 0; + } + + static size_t + length(const char_type* __s) + { + const char_type* __p = __s; + while (*__p) ++__p; + return (__p - __s); + } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { + for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) + if (*__p == __a) return __p; + return 0; + } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { + for (char_type* __p = __s; __p < __s + __n; ++__p) + assign(*__p, __a); + return __s; + } + + static char_type + to_char_type(const int_type& __c) + { return char_type(__c); } + + static int_type + to_int_type(const char_type& __c) { return int_type(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static state_type + _S_get_state(const pos_type& __pos) { return __pos.state(); } + + static int_type + eof() { return static_cast<int_type>(-1); } + + static int_type + _S_eos() { return char_type(); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? int_type(0) : __c; } + }; + + // 21.1.4 char_traits specializations + template<> + struct char_traits<char> + { + typedef char char_type; + typedef unsigned int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return memcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return strlen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return static_cast<const char_type*>(memchr(__s, __a, __n)); } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast<char_type*>(memmove(__s1, __s2, __n)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return static_cast<char_type*>(memset(__s, __a, __n)); } + + static char_type + to_char_type(const int_type& __c) + { return static_cast<char_type>(__c); } + + // To keep both the byte 0xff and the eof symbol 0xffffffff + // from ending up as 0xffffffff. + static int_type + to_int_type(const char_type& __c) + { return static_cast<int_type>(static_cast<unsigned char>(__c)); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static state_type + _S_get_state(const pos_type& __pos) { return __pos.state(); } + + static int_type + eof() { return static_cast<int_type>(EOF); } + + static int_type + _S_eos() { return char_type(); } + + static int_type + not_eof(const int_type& __c) + { return (__c == eof()) ? 0 : __c; } + }; + + +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + struct char_traits<wchar_t> + { + typedef wchar_t char_type; + typedef wint_t int_type; + typedef wstreamoff off_type; + typedef wstreampos pos_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return wcslen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return wmemchr(__s, __a, __n); } + + static char_type* + move(char_type* __s1, const char_type* __s2, int_type __n) + { return wmemmove(__s1, __s2, __n); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcpy(__s1, __s2, __n); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return wmemset(__s, __a, __n); } + + static char_type + to_char_type(const int_type& __c) { return char_type(__c); } + + static int_type + to_int_type(const char_type& __c) { return int_type(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static state_type + _S_get_state(const pos_type& __pos) { return __pos.state(); } + + static int_type + eof() { return static_cast<int_type>(WEOF); } + + static int_type + _S_eos() { return char_type(); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? 0 : __c; } + }; +#endif //_GLIBCPP_USE_WCHAR_T + + template<typename _CharT, typename _Traits> + struct _Char_traits_match + { + _CharT _M_c; + _Char_traits_match(_CharT const& __c) : _M_c(__c) { } + + bool + operator()(_CharT const& __a) { return _Traits::eq(_M_c,__a); } + }; + +} // namespace std + + +#endif /* _CPP_BITS_CHAR_TRAITS_H */ + diff --git a/libstdc++-v3/include/bits/codecvt.h b/libstdc++-v3/include/bits/codecvt.h new file mode 100644 index 00000000000..1306434a18c --- /dev/null +++ b/libstdc++-v3/include/bits/codecvt.h @@ -0,0 +1,662 @@ +// Locale support (codecvt) -*- C++ -*- + +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.1.5 Template class codecvt +// + +// Warning: this file is not meant for user inclusion. Use <locale>. + +// Written by Benjamin Kosnik <bkoz@cygnus.com> + +#ifndef _CPP_BITS_CODECVT_H +#define _CPP_BITS_CODECVT_H 1 + +#ifdef _GLIBCPP_USE_WCHAR_T +#include <iconv.h> // For iconv, iconv_t +#include <langinfo.h> +#endif + +namespace std +{ + // XXX __enc_traits may need to move up the locale header hierarchy, + // depending on if ctype ends up using it. +#ifdef _GLIBCPP_USE_WCHAR_T + // Extensions to use icov for dealing with character encodings, + // including conversions and comparisons between various character + // sets. This object encapsulates data that may need to be shared between + // char_traits, codecvt and ctype. + class __enc_traits + { + public: + // Types: + // NB: A conversion descriptor subsumes and enhances the + // functionality of a simple state type such as mbstate_t. + typedef iconv_t __desc_type; + + protected: + // Data Members: + // Max size of charset encoding name + static const int _S_max_size = 32; + // Name of internal character set encoding. + char _M_intc_enc[_S_max_size]; + // Name of external character set encoding. + char _M_extc_enc[_S_max_size]; + + // Conversion descriptor between external encoding to internal encoding. + __desc_type _M_in_desc; + // Conversion descriptor between internal encoding to external encoding. + __desc_type _M_out_desc; + + public: + __enc_traits() : _M_in_desc(0), _M_out_desc(0) + { + // __intc_end = whatever we are using internally, which is + // UCS4 (linux) + // UCS2 == UNICODE (microsoft, java, aix, whatever...) + // XXX Currently don't know how to get this data from target system... + strcpy(_M_intc_enc, "UCS4"); + + // __extc_end = external codeset in current locale + strcpy(_M_extc_enc, nl_langinfo(CODESET)); + } + + __enc_traits(const char* __int, const char* __ext) + : _M_in_desc(0), _M_out_desc(0) + { + strncpy(_M_intc_enc, __int, _S_max_size); + strncpy(_M_extc_enc, __ext, _S_max_size); + } + + // 21.1.2 traits typedefs + // p4 + // typedef STATE_T state_type + // requires: state_type shall meet the requirements of + // CopyConstructible types (20.1.3) + __enc_traits(const __enc_traits& __obj) + { + strncpy(_M_intc_enc, __obj._M_intc_enc, _S_max_size); + strncpy(_M_extc_enc, __obj._M_extc_enc, _S_max_size); + } + + ~__enc_traits() + { + iconv_close(_M_in_desc); + iconv_close(_M_out_desc); + } + + // Initializes + void + _M_init() + { + _M_in_desc = iconv_open(_M_intc_enc, _M_extc_enc); + _M_out_desc = iconv_open(_M_extc_enc, _M_intc_enc); + if (_M_out_desc == iconv_t(-1) || _M_in_desc == iconv_t(-1)) + { + // XXX Extended error checking. + } + } + + bool + _M_good() + { + return _M_out_desc && _M_in_desc + && _M_out_desc != iconv_t(-1) && _M_in_desc != iconv_t(-1); + } + + const __desc_type* + _M_get_in_descriptor() + { return &_M_in_desc; } + + const __desc_type* + _M_get_out_descriptor() + { return &_M_out_desc; } + + const char* + _M_get_internal_enc() + { return _M_intc_enc; } + + const char* + _M_get_external_enc() + { return _M_extc_enc; } + }; +#endif //_GLIBCPP_USE_WCHAR_T + + + // 22.2.1.5 Template class codecvt + class codecvt_base + { + public: + enum result + { + ok, + partial, + error, + noconv + }; + }; + + // Template class __codecvt_abstract_base + // NB: An abstract base class that fills in the public inlines, so + // that the specializations don't have to re-copy the public + // interface. + template<typename _InternT, typename _ExternT, typename _StateT> + class __codecvt_abstract_base + : public locale::facet, public codecvt_base + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + + // 22.2.1.5.1 codecvt members + result + out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { + return this->do_out(__state, __from, __from_end, __from_next, + __to, __to_end, __to_next); + } + + result + unshift(state_type& __state, extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { return this->do_unshift(__state, __to,__to_end,__to_next); } + + result + in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const + { + return this->do_in(__state, __from, __from_end, __from_next, + __to, __to_end, __to_next); + } + + int + encoding() const throw() + { return this->do_encoding(); } + + bool + always_noconv() const throw() + { return this->do_always_noconv(); } + + int + length(const state_type& __state, const extern_type* __from, + const extern_type* __end, size_t __max) const + { return this->do_length(__state, __from, __end, __max); } + + int + max_length() const throw() + { return this->do_max_length(); } + + protected: + explicit + __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } + + virtual + ~__codecvt_abstract_base() { } + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const = 0; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const = 0; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const = 0; + + virtual int + do_encoding() const throw() = 0; + + virtual bool + do_always_noconv() const throw() = 0; + + virtual int + do_length(const state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const = 0; + + virtual int + do_max_length() const throw() = 0; + }; + + // 22.2.1.5 Template class codecvt + // NB: Generic, mostly useless implementation. + template<typename _InternT, typename _ExternT, typename _StateT> + class codecvt + : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + + // Data Members: + static locale::id id; + + explicit + codecvt(size_t __refs = 0) + : __codecvt_abstract_base<_InternT,_ExternT,_StateT> (__refs) { } + + protected: + virtual + ~codecvt() { } + }; + + template<typename _InternT, typename _ExternT, typename _StateT> + locale::id codecvt<_InternT, _ExternT, _StateT>::id; + + // partial specialization + // This specialization takes advantage of iconv to provide code + // conversions between a large number of character encodings. + template<typename _InternT, typename _ExternT> + class codecvt<_InternT, _ExternT, __enc_traits> + : public __codecvt_abstract_base<_InternT, _ExternT, __enc_traits> + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef __enc_traits state_type; + typedef __enc_traits::__desc_type __desc_type; + typedef __enc_traits __enc_type; + + // Data Members: + static locale::id id; + + explicit + codecvt(size_t __refs = 0) + : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs) + { } + + explicit + codecvt(__enc_type* __enc, size_t __refs = 0) + : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs) + { } + + protected: + virtual + ~codecvt() { } + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(const state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + + template<typename _InternT, typename _ExternT> + locale::id + codecvt<_InternT, _ExternT, __enc_traits>::id; + + template<typename _InternT, typename _ExternT> + codecvt_base::result + codecvt<_InternT, _ExternT, __enc_traits>:: + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { + result __ret = error; + if (__state._M_good()) + { + typedef state_type::__desc_type __desc_type; + const __desc_type* __desc = __state._M_get_out_descriptor(); + const size_t __fmultiple = sizeof(intern_type) / sizeof(char); + size_t __flen = __fmultiple * (__from_end - __from); + const size_t __tmultiple = sizeof(extern_type) / sizeof(char); + size_t __tlen = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cfrom = reinterpret_cast<char*>(const_cast<intern_type*>(__from)); + char* __cto = reinterpret_cast<char*>(__to); + size_t __conv = iconv(*__desc, &__cfrom, &__flen, &__cto, &__tlen); + + if (__conv != size_t(-1)) + { + __from_next = reinterpret_cast<const intern_type*>(__cfrom); + __to_next = reinterpret_cast<extern_type*>(__cto); + __ret = ok; + } + else + { + if (__flen < __from_end - __from) + { + __from_next = reinterpret_cast<const intern_type*>(__cfrom); + __to_next = reinterpret_cast<extern_type*>(__cto); + __ret = partial; + } + else + __ret = error; + } + } + return __ret; + } + + template<typename _InternT, typename _ExternT> + codecvt_base::result + codecvt<_InternT, _ExternT, __enc_traits>:: + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const + { + result __ret = error; + if (__state._M_good()) + { + typedef state_type::__desc_type __desc_type; + const __desc_type* __desc = __state._M_get_in_descriptor(); + const size_t __tmultiple = sizeof(intern_type) / sizeof(char); + size_t __tlen = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast<char*>(__to); + size_t __conv = iconv(*__desc, NULL, NULL, &__cto, &__tlen); + + if (__conv != size_t(-1)) + { + __to_next = reinterpret_cast<extern_type*>(__cto); + if (__tlen == __tmultiple * (__to_end - __to)) + __ret = noconv; + else if (__tlen == 0) + __ret = ok; + else + __ret = partial; + } + else + __ret = error; + } + return __ret; + } + + template<typename _InternT, typename _ExternT> + codecvt_base::result + codecvt<_InternT, _ExternT, __enc_traits>:: + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const + { + result __ret = error; + if (__state._M_good()) + { + typedef state_type::__desc_type __desc_type; + const __desc_type* __desc = __state._M_get_in_descriptor(); + const size_t __fmultiple = sizeof(extern_type) / sizeof(char); + size_t __flen = __fmultiple * (__from_end - __from); + const size_t __tmultiple = sizeof(intern_type) / sizeof(char); + size_t __tlen = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cfrom = reinterpret_cast<char*>(const_cast<extern_type*>(__from)); + char* __cto = reinterpret_cast<char*>(__to); + size_t __conv = iconv(*__desc, &__cfrom, &__flen, &__cto, &__tlen); + + if (__conv != size_t(-1)) + { + __from_next = reinterpret_cast<const extern_type*>(__cfrom); + __to_next = reinterpret_cast<intern_type*>(__cto); + __ret = ok; + } + else + { + if (__flen < __from_end - __from) + { + __from_next = reinterpret_cast<const extern_type*>(__cfrom); + __to_next = reinterpret_cast<intern_type*>(__cto); + __ret = partial; + } + else + __ret = error; + } + } + return __ret; + } + + template<typename _InternT, typename _ExternT> + int + codecvt<_InternT, _ExternT, __enc_traits>:: + do_encoding() const throw() + { return 0; } + + template<typename _InternT, typename _ExternT> + bool + codecvt<_InternT, _ExternT, __enc_traits>:: + do_always_noconv() const throw() + { return false; } + + template<typename _InternT, typename _ExternT> + int + codecvt<_InternT, _ExternT, __enc_traits>:: + do_length(const state_type& __state, const extern_type* __from, + const extern_type* __end, size_t __max) const + { return min(__max, static_cast<size_t>(__end - __from)); } + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +// 74. Garbled text for codecvt::do_max_length + template<typename _InternT, typename _ExternT> + int + codecvt<_InternT, _ExternT, __enc_traits>:: + do_max_length() const throw() + { return 1; } +#endif + + // codecvt<char, char, mbstate_t> required specialization + template<> + class codecvt<char, char, mbstate_t> + : public __codecvt_abstract_base<char, char, mbstate_t> + { + public: + // Types: + typedef char intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + // Data Members: + static locale::id id; + + explicit + codecvt(size_t __refs = 0); + + protected: + virtual + ~codecvt(); + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(const state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + +#ifdef _GLIBCPP_USE_WCHAR_T + // codecvt<wchar_t, char, mbstate_t> required specialization + template<> + class codecvt<wchar_t, char, mbstate_t> + : public __codecvt_abstract_base<wchar_t, char, mbstate_t> + { + public: + // Types: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + // Data Members: + static locale::id id; + + explicit + codecvt(size_t __refs = 0); + + protected: + virtual + ~codecvt(); + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, + const extern_type* __from, const extern_type* __from_end, + const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual + int do_encoding() const throw(); + + virtual + bool do_always_noconv() const throw(); + + virtual + int do_length(const state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; +#endif //_GLIBCPP_USE_WCHAR_T + + // 22.2.1.6 Template class codecvt_byname + template<typename _InternT, typename _ExternT, typename _StateT> + class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> + { + public: + explicit + codecvt_byname(const char*, size_t __refs = 0) + : codecvt<_InternT,_ExternT,_StateT> (__refs) { } + protected: + virtual + ~codecvt_byname() { } + }; + + template<> + class codecvt_byname<char, char, mbstate_t> + : public codecvt<char, char, mbstate_t> + { + public: + explicit + codecvt_byname(const char*, size_t __refs = 0); + + protected: + virtual + ~codecvt_byname(); + }; + +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + class codecvt_byname<wchar_t, char, mbstate_t> + : public codecvt<wchar_t, char, mbstate_t> + { + public: + explicit + codecvt_byname(const char*, size_t __refs = 0); + + protected: + virtual + ~codecvt_byname(); + }; +#endif + +} // namespace std + +#endif // _CPP_BITS_CODECVT_H + +// Local Variables: +// mode:c++ +// End: + diff --git a/libstdc++-v3/include/bits/concept_checks.h b/libstdc++-v3/include/bits/concept_checks.h new file mode 100644 index 00000000000..4a0e2d55703 --- /dev/null +++ b/libstdc++-v3/include/bits/concept_checks.h @@ -0,0 +1,811 @@ +/* + * 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 <class _Tp> +struct _Mutable_trait { + typedef _Tp _Type; +}; +template <class _Tp> +struct _Mutable_trait<const _Tp> { + typedef _Tp _Type; +}; + + +/* helper function for avoiding compiler warnings about unused variables */ +template <class _Type> +void __sink_unused_warning(_Type) { } + +template <class _TypeX, class _TypeY> +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 <class _Type> struct __check_equal { }; + +template <class _TypeX, class _TypeY> +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 <class _Func, class _Ret> +struct _STL_GENERATOR_ERROR { + static _Ret __generator_requirement_violation(_Func& __f) { + return __f(); + } +}; + +template <class _Func> +struct _STL_GENERATOR_ERROR<_Func, void> { + static void __generator_requirement_violation(_Func& __f) { + __f(); + } +}; + + +template <class _Func, class _Ret, class _Arg> +struct _STL_UNARY_FUNCTION_ERROR { + static _Ret + __unary_function_requirement_violation(_Func& __f, + const _Arg& __arg) { + return __f(__arg); + } +}; + +template <class _Func, class _Arg> +struct _STL_UNARY_FUNCTION_ERROR<_Func, void, _Arg> { + static void + __unary_function_requirement_violation(_Func& __f, + const _Arg& __arg) { + __f(__arg); + } +}; + +template <class _Func, class _Ret, class _First, class _Second> +struct _STL_BINARY_FUNCTION_ERROR { + static _Ret + __binary_function_requirement_violation(_Func& __f, + const _First& __first, + const _Second& __second) { + return __f(__first, __second); + } +}; + +template <class _Func, class _First, class _Second> +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 <class _Ret, class _First, class _Second> \ +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 <class _Type> + static _Type + __default_constructor_requirement_violation(_Type) { + return _Type(); + } + template <class _Type> + static _Type + __assignment_operator_requirement_violation(_Type __a) { + __a = __a; + return __a; + } + template <class _Type> + static _Type + __copy_constructor_requirement_violation(_Type __a) { + _Type __c(__a); + return __c; + } + template <class _Type> + static _Type + __const_parameter_required_for_copy_constructor(_Type /* __a */, + const _Type& __b) { + _Type __c(__b); + return __c; + } + template <class _Type> + static _Type + __const_parameter_required_for_assignment_operator(_Type __a, + const _Type& __b) { + __a = __b; + return __a; + } + template <class _Type> + static _Type + __less_than_comparable_requirement_violation(_Type __a, _Type __b) { + if (__a < __b) return __a; + return __b; + } + template <class _Type> + static _Type + __equality_comparable_requirement_violation(_Type __a, _Type __b) { + if (__a == __b || __a != __b) return __a; + return __b; + } + template <class _Iterator> + static void + __dereference_operator_requirement_violation(_Iterator __i) { + __sink_unused_warning(*__i); + } + template <class _Iterator> + static void + __dereference_operator_and_assignment_requirement_violation(_Iterator __i) { + *__i = *__i; + } + template <class _Iterator> + static void + __preincrement_operator_requirement_violation(_Iterator __i) { + ++__i; + } + template <class _Iterator> + static void + __postincrement_operator_requirement_violation(_Iterator __i) { + __i++; + } + template <class _Iterator> + static void + __predecrement_operator_requirement_violation(_Iterator __i) { + --__i; + } + template <class _Iterator> + static void + __postdecrement_operator_requirement_violation(_Iterator __i) { + __i--; + } + template <class _Iterator, class _Type> + static void + __postincrement_operator_and_assignment_requirement_violation(_Iterator __i, + _Type __t) { + *__i++ = __t; + } + template <class _Iterator, class _Distance> + static _Iterator + __iterator_addition_assignment_requirement_violation(_Iterator __i, + _Distance __n) { + __i += __n; + return __i; + } + template <class _Iterator, class _Distance> + static _Iterator + __iterator_addition_requirement_violation(_Iterator __i, _Distance __n) { + __i = __i + __n; + __i = __n + __i; + return __i; + } + template <class _Iterator, class _Distance> + static _Iterator + __iterator_subtraction_assignment_requirement_violation(_Iterator __i, + _Distance __n) { + __i -= __n; + return __i; + } + template <class _Iterator, class _Distance> + static _Iterator + __iterator_subtraction_requirement_violation(_Iterator __i, _Distance __n) { + __i = __i - __n; + return __i; + } + template <class _Iterator, class _Distance> + static _Distance + __difference_operator_requirement_violation(_Iterator __i, _Iterator __j, + _Distance __n) { + __n = __i - __j; + return __n; + } + template <class _Exp, class _Type, class _Distance> + static _Type + __element_access_operator_requirement_violation(_Exp __x, _Type*, + _Distance __n) { + return __x[__n]; + } + template <class _Exp, class _Type, class _Distance> + 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 <class _Iterator> struct iterator_traits; +__STL_END_NAMESPACE + +template <class _Iter> +struct __value_type_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::value_type value_type; +}; + +template <class _Iter> +struct __difference_type_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::difference_type + difference_type; +}; + +template <class _Iter> +struct __reference_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::reference reference; +}; + +template <class _Iter> +struct __pointer_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::pointer pointer; +}; + +template <class _Iter> +struct __iterator_category_type_definition_requirement_violation { + typedef typename __STD::iterator_traits<_Iter>::iterator_category + iterator_category; +}; + +/* Assignable Requirements */ + + +template <class _Type> +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 <class _Type> +struct _DefaultConstructible_concept_specification { + static void _DefaultConstructible_requirement_violation(_Type __a) { + _STL_ERROR::__default_constructor_requirement_violation(__a); + } +}; + +/* EqualityComparable Requirements */ + +template <class _Type> +struct _EqualityComparable_concept_specification { + static void _EqualityComparable_requirement_violation(_Type __a) { + _STL_ERROR::__equality_comparable_requirement_violation(__a, __a); + } +}; + +/* LessThanComparable Requirements */ +template <class _Type> +struct _LessThanComparable_concept_specification { + static void _LessThanComparable_requirement_violation(_Type __a) { + _STL_ERROR::__less_than_comparable_requirement_violation(__a, __a); + } +}; + +/* TrivialIterator Requirements */ + +template <class _TrivialIterator> +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 <class _TrivialIterator> +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 <class _InputIterator> +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 <class _OutputIterator> +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 <class _ForwardIterator> +struct _ForwardIterator_concept_specification { +static void +_ForwardIterator_requirement_violation(_ForwardIterator __i) { + // Refinement of InputIterator + _InputIterator_concept_specification<_ForwardIterator>:: + _InputIterator_requirement_violation(__i); +} +}; + +template <class _ForwardIterator> +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 <class _BidirectionalIterator> +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 <class _BidirectionalIterator> +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 <class _RandAccIter> +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<value_type>::_Type* __dummy_ptr = 0; + _STL_ERROR::__element_access_operator_requirement_violation(__i, + __dummy_ptr, + _MutDist()); +} +}; + +template <class _RandAccIter> +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<value_type>::_Type* __tmp_ptr = 0; + // Valid Expressions + _STL_ERROR::__element_assignment_operator_requirement_violation(__i, + __tmp_ptr, _Dist()); +} +}; + +#define __STL_TYPEDEF_REQUIREMENT(__REQUIREMENT) \ +template <class Type> \ +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 <class _Alloc> +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: diff --git a/libstdc++-v3/include/bits/container_concepts.h b/libstdc++-v3/include/bits/container_concepts.h new file mode 100644 index 00000000000..99aec1c4b62 --- /dev/null +++ b/libstdc++-v3/include/bits/container_concepts.h @@ -0,0 +1,244 @@ +/* + * 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 <bits/concept_checks.h> + +#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 <class _Container> + static void + __begin_iterator_accessor_requirement_violation(_Container __c) { + __c.begin(); + } + template <class _Container> + static void + __const_begin_iterator_accessor_requirement_violation(const _Container& __c) { + __c.begin(); + } + template <class _Container> + static void + __end_iterator_accessor_requirement_violation(_Container __c) { + __c.end(); + } + template <class _Container> + static void + __const_end_iterator_accessor_requirement_violation(const _Container& __c) { + __c.end(); + } + + template <class _Container> + static void + __rbegin_iterator_accessor_requirement_violation(_Container __c) { + __c.rbegin(); + } + template <class _Container> + static void + __const_rbegin_iterator_accessor_requirement_violation(const _Container& __c) { + __c.rbegin(); + } + template <class _Container> + static void + __rend_iterator_accessor_requirement_violation(_Container __c) { + __c.rend(); + } + template <class _Container> + static void + __const_rend_iterator_accessor_requirement_violation(const _Container& __c) { + __c.rend(); + } + template <class _Container> + static void + __size_function_must_be_const(const _Container& __c) { + __c.size(); + } + template <class _Container> + static void + __size_function_requirement_violation(_Container& __c) { + __c.size(); + __size_function_must_be_const(__c); + } + template <class _Container> + static void + __max_size_function_must_be_const(const _Container& __c) { + __c.max_size(); + } + template <class _Container> + static void + __max_size_function_requirement_violation(_Container& __c) { + __c.max_size(); + __max_size_function_must_be_const(__c); + } + template <class _Container> + static void + __empty_function_must_be_const(const _Container& __c) { + __c.empty(); + } + template <class _Container> + static void + __empty_function_requirement_violation(_Container& __c) { + __c.empty(); + __empty_function_must_be_const(__c); + } + template <class _Container> + static void + __swap_function_requirement_violation(_Container& __c) { + __c.swap(__c); + } + +}; + + +__STL_TYPEDEF_REQUIREMENT(iterator); +__STL_TYPEDEF_REQUIREMENT(const_iterator); + +/* Containers */ + +template <class _Container> +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<const_iter>::_InputIterator_requirement_violation(const_iter()); + _InputIterator_concept_specification<iter>::_InputIterator_requirement_violation(iter()); +} +}; + +template <class _ForwardContainer> +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<const_iter>::_ForwardIterator_requirement_violation(const_iter()); + _Mutable_ForwardIterator_concept_specification<iter>::_Mutable_ForwardIterator_requirement_violation(iter()); +} +}; + + +__STL_TYPEDEF_REQUIREMENT(reverse_iterator); +__STL_TYPEDEF_REQUIREMENT(const_reverse_iterator); + +template <class _ReversibleContainer> +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<const_iter>::_BidirectionalIterator_requirement_violation(const_iter()); + _Mutable_BidirectionalIterator_concept_specification<iter>::_Mutable_BidirectionalIterator_requirement_violation(iter()); +} +}; + +template <class _ReversibleContainer> +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; + + _BidirectionalIterator_concept_specification<const_iter>::_BidirectionalIterator_requirement_violation(const_iter()); +} +}; + + +template <class _RandomAccessContainer> +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<const_iter>::_RandomAccessIterator_requirement_violation(const_iter()); + _Mutable_RandomAccessIterator_concept_specification<iter>::_Mutable_RandomAccessIterator_requirement_violation(iter()); +} +}; + +#endif /* if __STL_USE_CONCEPT_CHECKS */ + +#endif /* __STL_CONTAINER_CONCEPTS_H */ diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h new file mode 100644 index 00000000000..2b62ee8926e --- /dev/null +++ b/libstdc++-v3/include/bits/cpp_type_traits.h @@ -0,0 +1,301 @@ +// The -*- C++ -*- type traits classes for internal use in libstdc++ + +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> + +#ifndef _CPP_BITS_CPP_TYPE_TRAITS_H +#define _CPP_BITS_CPP_TYPE_TRAITS_H 1 + +// +// This file provides some compile-time information about various types. +// These informations were designed, on purpose, to be constant-expressions +// and not types as found in <stl/bits/type_traits.h>. In particular, they +// can be used in control structures and the optimizer hopefully will do +// the obvious thing. +// +// Why integral expressions, and not functions nor types? +// Firstly, these compile-time information entities are used as +// template-arguments so function return values won't work. We +// need compile-time entities. We're left with types and constant +// integral expressions. +// Secondly, from the point of view of ease of use type-based compile-time +// information is -not- *that* convenient. On has to write lots of +// overloaded functions and to hope that the compiler will select the right +// one. As a net effect, the overall structure isn't very clear at first +// glance. +// Thirdly, partial ordering and overload resolution (of template functions) +// is very costly in terms of compiler-resource. It is a Good Thing to +// keep these resource consumption as least as possible. +// +// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. +// + +namespace std { + + template<typename _Tp> + struct __is_void + { + enum + { + _M_type = 0 + }; + }; + + template<> + struct __is_void<void> + { + enum + { + _M_type = 1 + }; + }; + + // + // Integer types + // + template<typename _Tp> + struct __is_integer + { + enum + { + _M_type = 0 + }; + }; + + // Thirteen specializations (yes there are eleven standard integer + // types; 'long long' and 'unsigned long long' are supported as + // extensions) + template<> + struct __is_integer<bool> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer<char> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer<signed char> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer<unsigned char> + { + enum + { + _M_type = 1 + }; + }; + +# ifdef _GLIBCPP_USE_WCHAR_T + template<> + struct __is_integer<wchar_t> + { + enum + { + _M_type = 1 + }; + }; +# endif + + template<> + struct __is_integer<short> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer<unsigned short> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer<int> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer<unsigned int> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer<long> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer<unsigned long> + { + enum + { + _M_type = 1 + }; + }; + +# ifdef _GLIBCPP_USE_LONG_LONG + template<> + struct __is_integer<long long> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer<unsigned long long> + { + enum + { + _M_type = 1 + }; + }; +# endif + + // + // Floating point types + // + template<typename _Tp> + struct __is_floating + { + enum + { + _M_type = 0 + }; + }; + + // three specializations (float, double and 'long double') + template<> + struct __is_floating<float> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_floating<double> + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_floating<long double> + { + enum + { + _M_type = 1 + }; + }; + + // + // An arithmetic type is an integer type or a floating point type + // + template<typename _Tp> + struct __is_arithmetic + { + enum + { + _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type + }; + }; + + // + // A fundamental type is `void' or and arithmetic type + // + template<typename _Tp> + struct __is_fundamental + { + enum + { + _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type + }; + }; + + // + // For the immediate use, the following is a good approximation + // + template<typename _Tp> + struct __is_pod + { + enum + { + _M_type = __is_fundamental<_Tp>::_M_type + }; + }; + +} // namespace std + + +#endif //_CPP_BITS_CPP_TYPE_TRAITS_H + + + + + + + diff --git a/libstdc++-v3/include/bits/exception_support.h b/libstdc++-v3/include/bits/exception_support.h new file mode 100644 index 00000000000..e4d033c9ada --- /dev/null +++ b/libstdc++-v3/include/bits/exception_support.h @@ -0,0 +1,79 @@ +// Methods and support infrastructure for exceptions -*- C++ -*- + +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 15 Exception handling +// + +// This file declares functions whose only purpose is to throw an +// exception. They help break a circularity between <string> and +// <stdexcept>. See src/stdexcept.cc, where these functions are +// defined. + +// XXX: These functions serve a similar purpose to those in +// stl/bits/stl_range_errors.h . Eventually the two approaches should +// be merged. + +#ifndef _CPP_EXCEPTION_SUPPORT_H +#define _CPP_EXCEPTION_SUPPORT_H 1 + +namespace std { + +#if _GLIBCPP_USE_EXCEPTIONS + // Internal functions for string implementation. + extern void __out_of_range(const char *__str); + extern void __length_error(const char *__str); + +# 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 <bits/std_cassert.h> +# define __OUTOFRANGE(__cond) assert(!(__cond)) +# define __LENGTHERROR(__cond) assert(!(__cond)) +#endif + +} // namespace std + +#endif /* _CPP_EXCEPTION_SUPPORT_H */ + + + + + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/fpos.h b/libstdc++-v3/include/bits/fpos.h new file mode 100644 index 00000000000..27792b04a84 --- /dev/null +++ b/libstdc++-v3/include/bits/fpos.h @@ -0,0 +1,121 @@ +// File position object and stream types + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27 Input/output library +// + +#ifndef _CPP_BITS_FPOS_H +#define _CPP_BITS_FPOS_H 1 + +// Need this here as well as in std_ios because fpos is used in +// char_traits, and char_traits is used by string, which may or may +// not have included the std_ios file. +#include <bits/c++io.h> + +namespace std { + + // 27.4.1 Types + + // 27.4.3 Template class fpos + template<typename _StateT> + class fpos + { + public: + + // Types: + typedef _StateT __state_type; + + __state_type + state() const { return _M_st; } + + void + state(__state_type __st) { _M_st = __st; } + + // NB: The standard defines only the implicit copy ctor and the + // previous two members. The rest is a "conforming extension". + fpos(): _M_st(__state_type()), _M_pos(streamoff()) { } + + fpos(streamoff __pos, __state_type __st) + : _M_st(__st), _M_pos(__pos) { } + + fpos(streamoff __pos) + : _M_st(), _M_pos(__pos) { } + + operator streamoff() const { return _M_pos; } + + fpos& + operator+=(streamoff __off) { _M_pos += __off; return *this; } + + fpos& + operator-=(streamoff __off) { _M_pos -= __off; return *this; } + + bool + operator==(const fpos& __pos2) const { return _M_pos == __pos2._M_pos; } + + bool + operator!=(const fpos& __pos2) const { return _M_pos != __pos2._M_pos; } + + streamoff + _M_position() const { return _M_pos; } + + void + _M_position(streamoff __pos) { _M_pos = __pos; } + + private: + __state_type _M_st; + streamoff _M_pos; + }; + + template<typename _State> + inline fpos<_State> + operator+(const fpos<_State>& __pos, streamoff __off) + { + fpos<_State> t(__pos); + return t += __off; + } + + template<typename _State> + inline fpos<_State> + operator-(const fpos<_State>& __pos, streamoff __off) + { + fpos<_State> t(__pos); + return t -= __off; + } + + template<typename _State> + inline streamoff + operator-(const fpos<_State>& __pos1, const fpos<_State>& __pos2) + { return __pos1._M_position() - __pos2._M_position(); } + +} // namespace std + +#endif /* _CPP_BITS_FPOS_H */ + + diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc new file mode 100644 index 00000000000..d3a57501097 --- /dev/null +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -0,0 +1,586 @@ +// File based streams -*- C++ -*- + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8 File-based streams +// + +#ifndef _CPP_BITS_FSTREAM_TCC +#define _CPP_BITS_FSTREAM_TCC 1 + +namespace std +{ + template<typename _CharT, typename _Traits> + void + basic_filebuf<_CharT, _Traits>:: + _M_filebuf_init() + { + _M_buf_unified = true; // Tie input to output for basic_filebuf. + _M_buf_size = _M_buf_size_opt; + try { + _M_file = new __file_type(&_M_lock); + } + catch(...) { + delete _M_file; + throw; + } + } + + template<typename _CharT, typename _Traits> + void + basic_filebuf<_CharT, _Traits>:: + _M_allocate_buffers() + { + // Allocate internal buffer. + try { + _M_buf = new char_type[_M_buf_size]; + } + catch(...) { + delete [] _M_buf; + throw; + } + + // Allocate pback buffer. + try { + _M_pback = new char_type[_M_pback_size]; + } + catch(...) { + delete [] _M_pback; + throw; + } + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>:: + basic_filebuf() + : __streambuf_type(), _M_file(NULL), _M_state_cur(), _M_state_beg(), + _M_last_overflowed(false) + { _M_fcvt = &use_facet<__codecvt_type>(this->getloc()); } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>:: + basic_filebuf(int __fd, const char* /*__name*/, ios_base::openmode __mode) + : __streambuf_type(), _M_state_cur(), _M_state_beg(), + _M_last_overflowed(false) + { + _M_fcvt = &use_facet<__codecvt_type>(this->getloc()); + _M_filebuf_init(); + _M_file->sys_open(__fd, __mode); + if (this->is_open() && _M_buf_size) + { + _M_allocate_buffers(); + _M_mode = __mode; + + // XXX So that istream::getc() will only need to get 1 char, + // as opposed to BUF_SIZE. + if (__fd == 0) + _M_buf_size = 1; + + this->_M_set_indeterminate(); + } + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::__filebuf_type* + basic_filebuf<_CharT, _Traits>:: + open(const char* __s, ios_base::openmode __mode) + { + __filebuf_type *__ret = NULL; + if (!this->is_open()) + { + _M_filebuf_init(); + _M_file->open(__s, __mode); + if (this->is_open() && _M_buf_size) + { + _M_allocate_buffers(); + _M_mode = __mode; + + // For time being, set both (in/out) sets of pointers. + _M_set_indeterminate(); + if (__mode & ios_base::ate + && this->seekoff(0, ios_base::end, __mode) < 0) + this->close(); + __ret = this; + } + } + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::__filebuf_type* + basic_filebuf<_CharT, _Traits>:: + close() + { + __filebuf_type *__ret = NULL; + if (this->is_open()) + { + bool __testput = _M_out_cur && _M_out_beg < _M_out_end; + if (__testput) + _M_really_overflow(traits_type::eof()); + + // NB: Do this here so that re-opened filebufs will be cool... + _M_pback_destroy(); + +#if 0 + // XXX not done + if (_M_last_overflowed) + { + _M_output_unshift(); + _M_really_overflow(traits_type::eof()); + } +#endif + + _M_mode = ios_base::openmode(0); + if (_M_buf_size) + delete [] _M_buf; + _M_buf = NULL; + delete [] _M_pback; + _M_pback = NULL; + this->setg(NULL, NULL, NULL); + this->setp(NULL, NULL); + __ret = this; + } + + // Can actually allocate this file as part of an open and never + // have it be opened..... + if (_M_file) + { + delete _M_file; + _M_file = NULL; + } + _M_last_overflowed = false; + return __ret; + } + + template<typename _CharT, typename _Traits> + streamsize + basic_filebuf<_CharT, _Traits>:: + showmanyc() + { + streamsize __ret = -1; + bool __testin = _M_mode & ios_base::in; + + if (__testin) + { + bool __testeof = false; + if (_M_in_cur >= _M_in_end) + __testeof = this->underflow() == traits_type::eof(); + if (!__testeof) + __ret = _M_in_end - _M_in_cur; + } + _M_last_overflowed = false; + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + underflow() + { + int_type __ret = traits_type::eof(); + bool __testin = _M_mode & ios_base::in; + + if (__testin) + { + // Check for pback madness, and if so swich back to the + // normal buffers and jet outta here before expensive + // fileops happen... + if (_M_pback_init) + { + _M_pback_destroy(); + if (_M_in_cur < _M_in_end) + return traits_type::to_int_type(*_M_in_cur); + } + + bool __testget = _M_in_cur && _M_in_beg < _M_in_cur; + bool __testinit = _M_is_indeterminate(); + bool __testout = _M_mode & ios_base::out; + + // Sync internal and external buffers. + // NB: __testget -> __testput as _M_buf_unified here. + if (__testget) + { + if (__testout) + _M_really_overflow(); + else + _M_file->seekoff(_M_in_cur - _M_in_beg, + ios_base::cur, ios_base::in); + } + + if (__testinit || __testget) + { +#if 1 + streamsize __size = _M_file->xsgetn(_M_in_beg, _M_buf_size); + if (0 < __size) + { + _M_set_determinate(__size); + streamoff __p = _M_file->seekoff(0 - __size, ios_base::cur, + ios_base::in); + if (__p == -1) + { + // XXX Something is wrong, do error checking. + } + else + { + if (__testout) + _M_out_cur = _M_in_cur; + __ret = traits_type::to_int_type(*_M_in_cur); + } + } +#else + // 2000-08-04 bkoz disable + // Part one: (Re)fill external buf (_M_file->_IO_*) from + // external byte sequence (whatever physical byte sink or + // FILE actually is.) + char_type __conv_buf[_M_buf_size]; + streamsize __size = _M_file->xsgetn(__conv_buf, _M_buf_size); + + // Part two: (Re)fill internal buf contents from external buf. + if (0 < __size) + { + _M_set_determinate(__size); + + char* __conv_cur = __conv_buf; + _M_state_beg = _M_state_cur; + __res_type __r = _M_fcvt->in(_M_state_cur, + __conv_buf, + __conv_buf + __size, + const_cast<const char*&>(__conv_cur), + _M_in_beg, _M_in_end, _M_in_cur); + + if (__r == codecvt_base::partial) + { + // XXX Retry with larger _M_buf size. + } + + // Set pointers to internal and external buffers + // correctly. . . + if (__r != codecvt_base::error) + { + if (__testout) + _M_out_cur = _M_in_cur; + __ret = traits_type::to_int_type(*_M_in_cur); + } + + // Part three: Sync the current internal buffer + // position with the (now overshot) external buffer + // position. + streamoff __p = _M_file->seekoff(0 - __size, ios_base::cur, + ios_base::in); + if (__p == -1) + { + // XXX Something is wrong, do error checking. + } + } +#endif + } + } + _M_last_overflowed = false; + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + pbackfail(int_type __i) + { + int_type __ret = traits_type::eof(); + bool __testin = _M_mode & ios_base::in; + + if (__testin) + { + bool __testpb = _M_in_beg < _M_in_cur; + char_type __c = traits_type::to_char_type(__i); + bool __testeof = traits_type::eq_int_type(__i, __ret); + + if (__testpb) + { + bool __testout = _M_mode & ios_base::out; + bool __testeq = traits_type::eq(__c, this->gptr()[-1]); + + // Try to put back __c into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && __testeq) + { + --_M_in_cur; + if (__testout) + --_M_out_cur; + __ret = __i; + } + else if (__testeof) + { + --_M_in_cur; + if (__testout) + --_M_out_cur; + __ret = traits_type::not_eof(__i); + } + else if (!__testeof) + { + --_M_in_cur; + if (__testout) + --_M_out_cur; + _M_pback_create(); + *_M_in_cur = __c; + __ret = __i; + } + } + else + { + // At the beginning of the buffer, need to make a + // putback position available. + this->seekoff(-1, ios_base::cur); + this->underflow(); + if (!__testeof) + { + if (!traits_type::eq(__c, *_M_in_cur)) + { + _M_pback_create(); + *_M_in_cur = __c; + } + __ret = __i; + } + else + __ret = traits_type::not_eof(__i); + } + } + _M_last_overflowed = false; + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + overflow(int_type __c) + { + int_type __ret = traits_type::eof(); + bool __testpos = _M_out_cur && _M_out_cur >= _M_buf + _M_buf_size; + bool __testout = _M_mode & ios_base::out; + + if (__testout) + { + if (!__testpos) + { + *_M_out_cur = traits_type::to_char_type(__c); + _M_out_cur_move(1); + __ret = traits_type::not_eof(__c); + } + else + __ret = this->_M_really_overflow(__c); + } + + _M_last_overflowed = false; // Set in _M_really_overflow, below. + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + _M_really_overflow(int_type __c) + { + int_type __ret = traits_type::eof(); + bool __testput = _M_out_cur && _M_out_beg < _M_out_end; + + if (__testput) + { + bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); +#if 1 + int __plen = _M_out_end - _M_out_beg; + streamsize __len = _M_file->xsputn(_M_out_beg, __plen); + if (!__testeof) + { + char_type __pending = traits_type::to_char_type(__c); + __len += _M_file->xsputn(&__pending, 1); + ++__plen; + } + traits_type::to_char_type(__c); + // NB: Need this so that external byte sequence reflects + // internal buffer. + _M_file->sync(); + if (__len == __plen) + { + _M_set_indeterminate(); + __ret = traits_type::not_eof(__c); + } +#else + // Part one: Allocate temporary conversion buffer on + // stack. Convert internal buffer plus __c (ie, + // "pending sequence") to temporary conversion buffer. + int __plen = _M_out_end - _M_out_beg; + char_type __pbuf[__plen + 1]; + traits_type::copy(__pbuf, this->pbase(), __plen); + if (!__testeof) + { + __pbuf[__plen] = traits_type::to_char_type(__c); + ++__plen; + } + + char_type* __pend; + char __conv_buf[__plen]; + char* __conv_end; + _M_state_beg = _M_state_cur; + + __res_type __r = _M_fcvt->out(_M_state_cur, + __pbuf, __pbuf + __plen, + const_cast<const char_type*&>(__pend), + __conv_buf, __conv_buf + __plen, + __conv_end); + + // Part two: (Re)spill converted "pending sequence" + // contents (now in temporary conversion buffer) to + // external buffer (_M_file->_IO_*) using + // _M_file->sys_write(), and do error (minimal) checking. + if (__r != codecvt_base::error) + { + streamsize __len = _M_file->xsputn(__conv_buf, __plen); + // NB: Need this so that external byte sequence reflects + // internal buffer. + _M_file->sync(); + if (__len == __plen) + { + _M_set_indeterminate(); + __ret = traits_type::not_eof(__c); + } + } +#endif + } + _M_last_overflowed = true; + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) + { + pos_type __ret = pos_type(off_type(-1)); + bool __testopen = this->is_open(); + bool __testin = __mode & ios_base::in && _M_mode & ios_base::in; + bool __testout = __mode & ios_base::out && _M_mode & ios_base::out; + int __width = _M_fcvt->encoding(); + if (__width < 0) + __width = 0; + bool __testfail = __off != 0 && __width <= 0; + + if (__testopen && !__testfail && (__testin || __testout)) + { + // Ditch any pback buffers to avoid confusion. + _M_pback_destroy(); + + if (__way != ios_base::cur || __off != 0) + { + off_type __computed_off = __width * __off; + + bool __testget = _M_in_cur && _M_in_beg < _M_in_end; + bool __testput = _M_out_cur && _M_out_beg < _M_out_end; + // Sync the internal and external streams. + // out + if (__testput || _M_last_overflowed) + { + // Part one: update the output sequence. + this->sync(); + // Part two: output unshift sequence. + _M_output_unshift(); + } + //in + // NB: underflow() rewinds the external buffer. + else if (__testget && __way == ios_base::cur) + __computed_off += _M_in_cur - _M_in_beg; + + __ret = _M_file->seekoff(__computed_off, __way, __mode); + _M_set_indeterminate(); + } + // NB: Need to do this in case _M_file in indeterminate + // state, ie _M_file->_offset == -1 + else + { + __ret = _M_file->seekoff(__off, ios_base::cur, __mode); + __ret += max(_M_out_cur, _M_in_cur) - _M_buf; + } + } + _M_last_overflowed = false; + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + seekpos(pos_type __pos, ios_base::openmode __mode) + { + pos_type __ret; + off_type __off = __pos; + + __ret = this->seekoff(__off, ios_base::beg, __mode); + + _M_last_overflowed = false; + return __ret; + } + + template<typename _CharT, typename _Traits> + void + basic_filebuf<_CharT, _Traits>:: + _M_output_unshift() + { } + + template<typename _CharT, typename _Traits> + void + basic_filebuf<_CharT, _Traits>:: + imbue(const locale& __loc) + { + bool __testbeg = gptr() == eback() && pptr() == pbase(); + bool __teststate = _M_fcvt->encoding() == -1; + + _M_buf_locale_init = true; + if (__testbeg && !__teststate && _M_buf_locale != __loc) + { + // XXX Will need to save these older values. + _M_buf_locale = __loc; + _M_fcvt = &use_facet<__codecvt_type>(_M_buf_locale); + // XXX Necessary? + _M_buf_fctype = &use_facet<__ctype_type>(_M_buf_locale); + } + // NB this may require the reconversion of previously + // converted chars. This in turn may cause the reconstruction + // of the original file. YIKES!! + // XXX The part in the above comment is not done. + _M_last_overflowed = false; + } + +} // namespace std + +#endif // _CPP_BITS_FSTREAM_TCC + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/generic_shadow.h b/libstdc++-v3/include/bits/generic_shadow.h new file mode 100644 index 00000000000..b2a554f89ee --- /dev/null +++ b/libstdc++-v3/include/bits/generic_shadow.h @@ -0,0 +1,59 @@ +// generic C header shadow file -*- C++ -*- + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 is included by all the standard C <foo.h> headers +// after defining _SHADOW_NAME. + +#ifdef _IN_C_LEGACY_ /* sub-included by a C header */ + + // Get out of the "swamp." + } // Close extern "C" + } // Close namespace _C_legacy:: + +# undef _IN_C_LEGACY_ +# include _SHADOW_NAME + + // Dive back into the "swamp." + namespace _C_legacy { + extern "C" { +# define _IN_C_LEGACY_ + +#else /* not _IN_C_LEGACY_: directly included by user program */ + +# include _SHADOW_NAME + + // Expose global C names, including non-standard ones, but shadow + // some names and types with the std:: C++ version. + + using namespace ::_C_legacy::_C_shadow; + +#endif /* _IN_C_LEGACY_ */ + + + diff --git a/libstdc++-v3/include/bits/gslice.h b/libstdc++-v3/include/bits/gslice.h new file mode 100644 index 00000000000..737254c9da7 --- /dev/null +++ b/libstdc++-v3/include/bits/gslice.h @@ -0,0 +1,117 @@ +// The template and inlines for the -*- C++ -*- gslice class. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _CPP_BITS_GSLICE_H +#define _CPP_BITS_GSLICE_H + +namespace std { + + class gslice + { + public: + gslice (); + gslice (size_t, const valarray<size_t>&, const valarray<size_t>&); + // XXX: the IS says the copy-ctor and copy-assignment operators are + // synthetized by the compiler but they are just unsuitable + // for a ref-counted semantic + gslice(const gslice&); + ~gslice(); + + // XXX: See the note above. + gslice& operator= (const gslice&); + + size_t start () const; + valarray<size_t> size () const; + valarray<size_t> stride () const; + + private: + struct _Indexer { + size_t _M_count; + size_t _M_start; + valarray<size_t> _M_size; + valarray<size_t> _M_stride; + valarray<size_t> _M_index; + _Indexer(size_t, const valarray<size_t>&, + const valarray<size_t>&); + void _M_increment_use() { ++_M_count; } + size_t _M_decrement_use() { return --_M_count; } + }; + + _Indexer* _M_index; + + template<typename _Tp> friend class valarray; + }; + + inline size_t + gslice::start () const + { return _M_index ? _M_index->_M_start : 0; } + + inline valarray<size_t> + gslice::size () const + { return _M_index ? _M_index->_M_size : valarray<size_t>(); } + + inline valarray<size_t> + gslice::stride () const + { return _M_index ? _M_index->_M_stride : valarray<size_t>(); } + + inline gslice::gslice () : _M_index(0) {} + + inline + gslice::gslice(size_t __o, const valarray<size_t>& __l, + const valarray<size_t>& __s) + : _M_index(new gslice::_Indexer(__o, __l, __s)) {} + + inline + gslice::gslice(const gslice& __g) : _M_index(__g._M_index) + { if (_M_index) _M_index->_M_increment_use(); } + + inline + gslice::~gslice() + { if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; } + + inline gslice& + gslice::operator= (const gslice& __g) + { + if (__g._M_index) __g._M_index->_M_increment_use(); + if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; + _M_index = __g._M_index; + return *this; + } + + +} // std:: + + +#endif /* _CPP_BITS_GSLICE_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/gslice_array.h b/libstdc++-v3/include/bits/gslice_array.h new file mode 100644 index 00000000000..23a1f6d438b --- /dev/null +++ b/libstdc++-v3/include/bits/gslice_array.h @@ -0,0 +1,169 @@ +// The template and inlines for the -*- C++ -*- gslice_array class. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _CPP_BITS_GSLICE_ARRAY +#define _CPP_BITS_GSLICE_ARRAY 1 + +namespace std { + + template<typename _Tp> class gslice_array + { + public: + typedef _Tp value_type; + + void operator= (const valarray<_Tp>&) const; + void operator*= (const valarray<_Tp>&) const; + void operator/= (const valarray<_Tp>&) const; + void operator%= (const valarray<_Tp>&) const; + void operator+= (const valarray<_Tp>&) const; + void operator-= (const valarray<_Tp>&) const; + void operator^= (const valarray<_Tp>&) const; + void operator&= (const valarray<_Tp>&) const; + void operator|= (const valarray<_Tp>&) const; + void operator<<=(const valarray<_Tp>&) const; + void operator>>=(const valarray<_Tp>&) const; + void operator=(const _Tp&); + + template<class _Dom> + void operator= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator*= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator/= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator%= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator+= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator-= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator^= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator&= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator|= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator<<= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator>>= (const _Expr<_Dom,_Tp>&) const; + + private: + _Array<_Tp> _M_array; + const valarray<size_t>& _M_index; + + friend class valarray<_Tp>; + + gslice_array (_Array<_Tp>, const valarray<size_t>&); + + // this constructor needs to be implemented. + gslice_array (const gslice_array&); + + // not implemented + gslice_array(); + gslice_array& operator= (const gslice_array&); + }; + + template<typename _Tp> + inline + gslice_array<_Tp>::gslice_array (_Array<_Tp> __a, + const valarray<size_t>& __i) + : _M_array (__a), _M_index (__i) {} + + + template<typename _Tp> + inline + gslice_array<_Tp>::gslice_array (const gslice_array<_Tp>& __a) + : _M_array (__a._M_array), _M_index (__a._M_index) {} + + + template<typename _Tp> + inline void + gslice_array<_Tp>::operator= (const _Tp& __t) + { + __valarray_fill (_M_array, _Array<size_t>(_M_index), + _M_index.size(), __t); + } + + template<typename _Tp> + inline void + gslice_array<_Tp>::operator= (const valarray<_Tp>& __v) const + { + __valarray_copy (_Array<_Tp> (__v), __v.size (), + _M_array, _Array<size_t>(_M_index)); + } + + template<typename _Tp> + template<class E> + inline void + gslice_array<_Tp>::operator= (const _Expr<E, _Tp>& __e) const + { + __valarray_copy (__e, _M_index.size(), _M_array, + _Array<size_t>(_M_index)); + } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template<typename _Tp> \ +inline void \ +gslice_array<_Tp>::operator op##= (const valarray<_Tp>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _Array<size_t>(_M_index), \ + _Array<_Tp> (__v), __v.size ()); \ +} \ + \ +template<typename _Tp> template<class E> \ +inline void \ +gslice_array<_Tp>::operator op##= (const _Expr<E, _Tp>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _Array<size_t>(_M_index), __e, \ + _M_index.size()); \ +} + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _CPP_BITS_GSLICE_ARRAY */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/indirect_array.h b/libstdc++-v3/include/bits/indirect_array.h new file mode 100644 index 00000000000..1ad3b911f6b --- /dev/null +++ b/libstdc++-v3/include/bits/indirect_array.h @@ -0,0 +1,160 @@ +// The template and inlines for the -*- C++ -*- indirect_array class. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _CPP_BITS_INDIRECT_ARRAY_H +#define _CPP_BITS_INDIRECT_ARRAY_H + +namespace std { + + template <class _Tp> class indirect_array + { + public: + typedef _Tp value_type; + + void operator= (const valarray<_Tp>&) const; + void operator*= (const valarray<_Tp>&) const; + void operator/= (const valarray<_Tp>&) const; + void operator%= (const valarray<_Tp>&) const; + void operator+= (const valarray<_Tp>&) const; + void operator-= (const valarray<_Tp>&) const; + void operator^= (const valarray<_Tp>&) const; + void operator&= (const valarray<_Tp>&) const; + void operator|= (const valarray<_Tp>&) const; + void operator<<= (const valarray<_Tp>&) const; + void operator>>= (const valarray<_Tp>&) const; + void operator= (const _Tp&); + // ~indirect_array(); + + template<class _Dom> + void operator= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator*= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator/= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator%= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator+= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator-= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator^= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator&= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator|= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator<<= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator>>= (const _Expr<_Dom, _Tp>&) const; + + private: + indirect_array (const indirect_array&); + indirect_array (_Array<_Tp>, size_t, _Array<size_t>); + + friend class valarray<_Tp>; + friend class gslice_array<_Tp>; + + const size_t _M_sz; + const _Array<size_t> _M_index; + const _Array<_Tp> _M_array; + + // not implemented + indirect_array (); + indirect_array& operator= (const indirect_array&); + }; + + template<typename _Tp> + inline indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a) + : _M_sz (__a._M_sz), _M_index (__a._M_index), + _M_array (__a._M_array) {} + + template<typename _Tp> + inline + indirect_array<_Tp>::indirect_array (_Array<_Tp> __a, size_t __s, + _Array<size_t> __i) + : _M_sz (__s), _M_index (__i), _M_array (__a) {} + + // template<typename _Tp> + // inline indirect_array<_Tp>::~indirect_array() {} + + template<typename _Tp> + inline void + indirect_array<_Tp>::operator= (const _Tp& __t) + { __valarray_fill(_M_array, _M_index, _M_sz, __t); } + + template<typename _Tp> + inline void + indirect_array<_Tp>::operator= (const valarray<_Tp>& __v) const + { __valarray_copy (_Array<_Tp> (__v), _M_sz, _M_array, _M_index); } + + template<typename _Tp> + template<class _Dom> + inline void + indirect_array<_Tp>::operator= (const _Expr<_Dom,_Tp>& __e) const + { __valarray_copy (__e, _M_sz, _M_array, _M_index); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template<typename _Tp> \ +inline void \ +indirect_array<_Tp>::operator op##= (const valarray<_Tp>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _M_index, _Array<_Tp> (__v), _M_sz); \ +} \ + \ +template<typename _Tp> template<class _Dom> \ +inline void \ +indirect_array<_Tp>::operator op##= (const _Expr<_Dom,_Tp>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _M_index, __e, _M_sz); \ +} + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _CPP_BITS_INDIRECT_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h new file mode 100644 index 00000000000..59462145522 --- /dev/null +++ b/libstdc++-v3/include/bits/ios_base.h @@ -0,0 +1,576 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8 File-based streams +// + +#ifndef _CPP_BITS_IOSBASE_H +#define _CPP_BITS_IOSBASE_H 1 + +namespace std { + + // The following definitions of bitmask types are enums, not ints, + // as permitted (but not required) in the standard, in order to provide + // better type safety in iostream calls. A side effect is that + // expressions involving them are no longer compile-time constants. + enum _Ios_Fmtflags { _S_ios_fmtflags_end = 1<<16 }; + + inline _Ios_Fmtflags + operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast<int>(__a) & static_cast<int>(__b)); } + + inline _Ios_Fmtflags + operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast<int>(__a) | static_cast<int>(__b)); } + + inline _Ios_Fmtflags + operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast<int>(__a) ^ static_cast<int>(__b)); } + + inline _Ios_Fmtflags + operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a | __b; } + + inline _Ios_Fmtflags + operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a & __b; } + + inline _Ios_Fmtflags + operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a ^ __b; } + + inline _Ios_Fmtflags + operator~(_Ios_Fmtflags __a) + { return _Ios_Fmtflags(~static_cast<int>(__a)); } + + + enum _Ios_Openmode { _S_ios_openmode_end = 1<<16 }; + + inline _Ios_Openmode + operator&(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast<int>(__a) & static_cast<int>(__b)); } + + inline _Ios_Openmode + operator|(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast<int>(__a) | static_cast<int>(__b)); } + + inline _Ios_Openmode + operator^(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast<int>(__a) ^ static_cast<int>(__b)); } + + inline _Ios_Openmode + operator|=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a | __b; } + + inline _Ios_Openmode + operator&=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a & __b; } + + inline _Ios_Openmode + operator^=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a ^ __b; } + + inline _Ios_Openmode + operator~(_Ios_Openmode __a) + { return _Ios_Openmode(~static_cast<int>(__a)); } + + + enum _Ios_Iostate { _S_ios_iostate_end = 1<<16 }; + + inline _Ios_Iostate + operator&(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast<int>(__a) & static_cast<int>(__b)); } + + inline _Ios_Iostate + operator|(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast<int>(__a) | static_cast<int>(__b)); } + + inline _Ios_Iostate + operator^(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast<int>(__a) ^ static_cast<int>(__b)); } + + inline _Ios_Iostate + operator|=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a | __b; } + + inline _Ios_Iostate + operator&=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a & __b; } + + inline _Ios_Iostate + operator^=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a ^ __b; } + + inline _Ios_Iostate + operator~(_Ios_Iostate __a) + { return _Ios_Iostate(~static_cast<int>(__a)); } + + enum _Ios_Seekdir { _S_ios_Seekdir_end = 1<<16 }; + + // 27.4.2 Class ios_base + class ios_base + { + public: + + // 27.4.2.1.1 Class ios_base::failure + class failure : public exception + { + public: +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // Can't do exception(_msg) as defined in 27.4.2.1.1 + explicit + failure(const string& __str); + + virtual + ~failure() { }; + + virtual const + char* what() const throw() { return _M_name; } + + private: + enum { _M_bufsize = 256 }; + char _M_name[_M_bufsize]; +#endif + }; + + // 27.4.2.1.2 Type ios_base::fmtflags + typedef _Ios_Fmtflags fmtflags; + // 27.4.2.1.2 Type fmtflags + static const fmtflags boolalpha = fmtflags(__ios_flags::_S_boolalpha); + static const fmtflags dec = fmtflags(__ios_flags::_S_dec); + static const fmtflags fixed = fmtflags(__ios_flags::_S_fixed); + static const fmtflags hex = fmtflags(__ios_flags::_S_hex); + static const fmtflags internal = fmtflags(__ios_flags::_S_internal); + static const fmtflags left = fmtflags(__ios_flags::_S_left); + static const fmtflags oct = fmtflags(__ios_flags::_S_oct); + static const fmtflags right = fmtflags(__ios_flags::_S_right); + static const fmtflags scientific = fmtflags(__ios_flags::_S_scientific); + static const fmtflags showbase = fmtflags(__ios_flags::_S_showbase); + static const fmtflags showpoint = fmtflags(__ios_flags::_S_showpoint); + static const fmtflags showpos = fmtflags(__ios_flags::_S_showpos); + static const fmtflags skipws = fmtflags(__ios_flags::_S_skipws); + static const fmtflags unitbuf = fmtflags(__ios_flags::_S_unitbuf); + static const fmtflags uppercase = fmtflags(__ios_flags::_S_uppercase); + static const fmtflags adjustfield = fmtflags(__ios_flags::_S_adjustfield); + static const fmtflags basefield = fmtflags(__ios_flags::_S_basefield); + static const fmtflags floatfield = fmtflags(__ios_flags::_S_floatfield); + + // 27.4.2.1.3 Type ios_base::iostate + typedef _Ios_Iostate iostate; + static const iostate badbit = iostate(__ios_flags::_S_badbit); + static const iostate eofbit = iostate(__ios_flags::_S_eofbit); + static const iostate failbit = iostate(__ios_flags::_S_failbit); + static const iostate goodbit = iostate(0); + + // 27.4.2.1.4 Type openmode + typedef _Ios_Openmode openmode; + static const openmode app = openmode(__ios_flags::_S_app); + static const openmode ate = openmode(__ios_flags::_S_ate); + static const openmode binary = openmode(__ios_flags::_S_bin); + static const openmode in = openmode(__ios_flags::_S_in); + static const openmode out = openmode(__ios_flags::_S_out); + static const openmode trunc = openmode(__ios_flags::_S_trunc); + + // 27.4.2.1.5 Type seekdir + typedef _Ios_Seekdir seekdir; + static const seekdir beg = seekdir(0); + static const seekdir cur = seekdir(SEEK_CUR); + static const seekdir end = seekdir(SEEK_END); + +#ifdef _GLIBCPP_DEPRICATED + typedef int io_state; + typedef int open_mode; + typedef int seek_dir; +#endif + + // Callbacks; + enum event + { + erase_event, + imbue_event, + copyfmt_event + }; + + typedef void (*event_callback) (event, ios_base&, int); + + void + register_callback(event_callback __fn, int __index); + + protected: + // Data Members + streamsize _M_precision; + streamsize _M_width; + fmtflags _M_flags; + + // 27.4.2.6 Members for callbacks + // 27.4.2.6 ios_base callbacks + + struct _Callback_list + { + // Data Members + _Callback_list* _M_next; + ios_base::event_callback _M_fn; + int _M_index; + int _M_refcount; // 0 means one reference. + + _Callback_list(ios_base::event_callback __fn, int __index, + _Callback_list* __cb) + : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { } + + void + _M_add_reference() { ++_M_refcount; } // XXX MT + + int + _M_remove_reference() { return _M_refcount--; } // 0 => OK to delete + }; + + _Callback_list* _M_callbacks; + + void + _M_call_callbacks(event __ev) throw(); + + void + _M_dispose_callbacks(void); + + // 27.4.2.5 Members for iword/pword storage + struct _Words + { + void* _M_pword; + long _M_iword; + }; + + static const int _S_local_words = 8; + _Words _M_word_array[_S_local_words]; // Guaranteed storage + _Words _M_dummy; // Only for failed iword/pword calls. + _Words* _M_words; + int _M_word_limit; + + _Words& + _M_grow_words(int __index); + + // Members for locale and locale caching. + locale _M_ios_locale; + + void + _M_init(); + + public: + // 27.4.2.1.6 Class ios_base::Init + // Used to initialize standard streams. In theory, g++ could use + // -finit-priority to order this stuff correctly without going + // through these machinations. + + class Init + { + friend class ios_base; + public: + Init(); + ~Init(); + private: + static int _S_ios_base_init; + filebuf* _M_cout; + filebuf* _M_cin; + filebuf* _M_cerr; +#ifdef _GLIBCPP_USE_WCHAR_T + wfilebuf* _M_wcout; + wfilebuf* _M_wcin; + wfilebuf* _M_wcerr; +#endif + }; + + // Fmtflags state: + inline fmtflags + flags() const { return _M_flags; } + + inline fmtflags + flags(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags = __fmtfl; + return __old; + } + + inline fmtflags + setf(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags |= __fmtfl; + return __old; + } + + inline fmtflags + setf(fmtflags __fmtfl, fmtflags __mask) + { + fmtflags __old = _M_flags; + _M_flags &= ~__mask; + _M_flags |= (__fmtfl & __mask); + return __old; + } + + inline void + unsetf(fmtflags __mask) { _M_flags &= ~__mask; } + + inline streamsize + precision() const { return _M_precision; } + + inline streamsize + precision(streamsize __prec) + { + streamsize __old = _M_precision; + _M_precision = __prec; + return __old; + } + + inline streamsize + width() const { return _M_width; } + + inline streamsize + width(streamsize __wide) + { + streamsize __old = _M_width; + _M_width = __wide; + return __old; + } + + static bool + sync_with_stdio(bool __sync = true); + + // Locales: + locale + imbue(const locale& __loc); + + inline locale + getloc() const { return _M_ios_locale; } + + // Storage: + static int + xalloc() throw(); + + inline long& + iword(int __ix) + { + _Words& __word = (__ix < _M_word_limit) + ? _M_words[__ix] : _M_grow_words(__ix); + return __word._M_iword; + } + + inline void*& + pword(int __ix) + { + _Words& __word = (__ix < _M_word_limit) + ? _M_words[__ix] : _M_grow_words(__ix); + return __word._M_pword; + } + + // Destructor + ~ios_base(); + + protected: + ios_base(); + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + private: + ios_base(const ios_base&); + + ios_base& + operator=(const ios_base&); +#endif + }; + + // 27.4.5.1 fmtflags manipulators: + inline ios_base& + boolalpha(ios_base& __base) + { + __base.setf(ios_base::boolalpha); + return __base; + } + + inline ios_base& + noboolalpha(ios_base& __base) + { + __base.unsetf(ios_base::boolalpha); + return __base; + } + + inline ios_base& + showbase(ios_base& __base) + { + __base.setf(ios_base::showbase); + return __base; + } + + inline ios_base& + noshowbase(ios_base& __base) + { + __base.unsetf(ios_base::showbase); + return __base; + } + + inline ios_base& + showpoint(ios_base& __base) + { + __base.setf(ios_base::showpoint); + return __base; + } + + inline ios_base& + noshowpoint(ios_base& __base) + { + __base.unsetf(ios_base::showpoint); + return __base; + } + + inline ios_base& + showpos(ios_base& __base) + { + __base.setf(ios_base::showpos); + return __base; + } + + inline ios_base& + noshowpos(ios_base& __base) + { + __base.unsetf(ios_base::showpos); + return __base; + } + + inline ios_base& + skipws(ios_base& __base) + { + __base.setf(ios_base::skipws); + return __base; + } + + inline ios_base& + noskipws(ios_base& __base) + { + __base.unsetf(ios_base::skipws); + return __base; + } + + inline ios_base& + uppercase(ios_base& __base) + { + __base.setf(ios_base::uppercase); + return __base; + } + + inline ios_base& + nouppercase(ios_base& __base) + { + __base.unsetf(ios_base::uppercase); + return __base; + } + + inline ios_base& + unitbuf(ios_base& __base) + { + __base.setf(ios_base::unitbuf); + return __base; + } + + inline ios_base& + nounitbuf(ios_base& __base) + { + __base.unsetf(ios_base::unitbuf); + return __base; + } + + // 27.4.5.2 adjustfield anipulators: + inline ios_base& + internal(ios_base& __base) + { + __base.setf(ios_base::internal, ios_base::adjustfield); + return __base; + } + + inline ios_base& + left(ios_base& __base) + { + __base.setf(ios_base::left, ios_base::adjustfield); + return __base; + } + + inline ios_base& + right(ios_base& __base) + { + __base.setf(ios_base::right, ios_base::adjustfield); + return __base; + } + + // 27.4.5.3 basefield anipulators: + inline ios_base& + dec(ios_base& __base) + { + __base.setf(ios_base::dec, ios_base::basefield); + return __base; + } + + inline ios_base& + hex(ios_base& __base) + { + __base.setf(ios_base::hex, ios_base::basefield); + return __base; + } + + inline ios_base& + oct(ios_base& __base) + { + __base.setf(ios_base::oct, ios_base::basefield); + return __base; + } + + // 27.4.5.4 floatfield anipulators: + inline ios_base& + fixed(ios_base& __base) + { + __base.setf(ios_base::fixed, ios_base::floatfield); + return __base; + } + + inline ios_base& + scientific(ios_base& __base) + { + __base.setf(ios_base::scientific, ios_base::floatfield); + return __base; + } + +} // namespace std + +#endif /* _CPP_BITS_IOSBASE_H */ + + + + + + + + + diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc new file mode 100644 index 00000000000..8ad2de04862 --- /dev/null +++ b/libstdc++-v3/include/bits/istream.tcc @@ -0,0 +1,1216 @@ +// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.2 Output streams +// + +#include <bits/std_locale.h> + +namespace std { + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>::sentry:: + sentry(basic_istream<_CharT, _Traits>& __in, bool __noskipws) + { + if (__in.good()) + { + if (__in.tie()) + __in.tie()->flush(); + if (!__noskipws && (__in.flags() & ios_base::skipws)) + { + const __int_type __eof = traits_type::eof(); + __int_type __c = __int_type(0); + __streambuf_type* __sb = __in.rdbuf(); + const __ctype_type* __ctype = __in._M_get_fctype_ios(); + bool __testsp = true; + bool __testeof = false; + + while (!__testeof && __testsp) + { + __c = __sb->sbumpc(); + __testeof = __c == __eof; + __testsp = __ctype->is(ctype_base::space, __c); + } + + if (!__testeof && !__testsp) + __sb->sputbackc(__c); +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +//195. Should basic_istream::sentry's constructor ever set eofbit? + else + __in.setstate(ios_base::eofbit); +#endif + } + } + _M_ok = __in.good(); + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__istream_type& (*__pf)(__istream_type&)) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + __pf(*this); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__ios_type& (*__pf)(__ios_type&)) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + __pf(*this); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(ios_base& (*__pf)(ios_base&)) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + __pf(*this); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(bool& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(short& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned short& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(int& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned int& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + +#ifdef _GLIBCPP_USE_LONG_LONG + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(long long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned long long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } +#endif + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(float& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(double& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(long double& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(void*& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + try { + iostate __err = iostate(ios_base::goodbit); + _M_fnumget->get(*this, 0, *this, __err, __n); + this->setstate(__err); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__streambuf_type* __sbout) + { + streamsize __xtrct = 0; + __streambuf_type* __sbin = this->rdbuf(); + sentry __cerb(*this, false); + if (__sbout && __cerb) + __xtrct = _S_copy_streambufs(*this, __sbin, __sbout); + if (!__sbout || !__xtrct) + this->setstate(ios_base::failbit); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + get(void) + { + const int_type __eof = traits_type::eof(); + int_type __c = __eof; + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + try { + __c = this->rdbuf()->sbumpc(); + // 27.6.1.1 paragraph 3 + if (__c != __eof) + _M_gcount = 1; + else + this->setstate(ios_base::eofbit | ios_base::failbit); + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return __c; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type& __c) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + try { + const int_type __eof = traits_type::eof(); + int_type __bufval = this->rdbuf()->sbumpc(); + // 27.6.1.1 paragraph 3 + if (__bufval != __eof) + { + _M_gcount = 1; + __c = traits_type::to_char_type(__bufval); + } + else + this->setstate(ios_base::eofbit | ios_base::failbit); + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 1) + { + try { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sbumpc(); + bool __testdelim = __c == __idelim; + bool __testeof = __c == __eof; + + while (_M_gcount < __n - 1 && !__testeof && !__testdelim) + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->sbumpc(); + __testeof = __c == __eof; + __testdelim = __c == __idelim; + } + if (__testdelim || _M_gcount == __n - 1) + __sb->sputbackc(__c); + if (__testeof) + this->setstate(ios_base::eofbit); + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + *__s = char_type(NULL); + if (!_M_gcount) + this->setstate(ios_base::failbit); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(__streambuf_type& __sb, char_type __delim) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + int_type __c; + __streambuf_type* __this_sb = this->rdbuf(); + try { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __c = __this_sb->sbumpc(); + bool __testdelim = __c == __idelim; + bool __testeof = __c == __eof; + bool __testput = true; + streamsize __n = __this_sb->in_avail(); + + while (_M_gcount <= __n && !__testeof && !__testdelim + && (__testput = __sb.sputc(traits_type::to_char_type(__c)) + != __eof)) + { + ++_M_gcount; + __c = __this_sb->sbumpc(); + __testeof = __c == __eof; + __testdelim = __c == __idelim; + } + if (__testdelim || !__testput) + __this_sb->sputbackc(traits_type::to_char_type(__c)); + if (__testeof) + this->setstate(ios_base::eofbit); + } + catch(exception& __fail){ + // Exception may result from sputc->overflow. + __this_sb->sputbackc(traits_type::to_char_type(__c)); + } + } + if (!_M_gcount) + this->setstate(ios_base::failbit); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + getline(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + try { + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sbumpc(); + ++_M_gcount; + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + bool __testdelim = __c == __idelim; + bool __testeof = __c == __eof; + + while (_M_gcount < __n && !__testeof && !__testdelim) + { + *__s++ = traits_type::to_char_type(__c); + __c = __sb->sbumpc(); + ++_M_gcount; + __testeof = __c == __eof; + __testdelim = __c == __idelim; + } + + if (__testeof) + { + --_M_gcount; + this->setstate(ios_base::eofbit); + } + else if (!__testdelim) + { + --_M_gcount; + __sb->sputbackc(traits_type::to_char_type(__c)); + this->setstate(ios_base::failbit); + } + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + *__s = char_type(NULL); + if (!_M_gcount) + this->setstate(ios_base::failbit); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + ignore(streamsize __n, int_type __delim) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + try { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sbumpc(); + bool __testdelim = __c == __idelim; + bool __testeof = __c == __eof; + + __n = min(__n, numeric_limits<streamsize>::max()); + while (_M_gcount < __n - 1 && !__testeof && !__testdelim) + { + ++_M_gcount; + __c = __sb->sbumpc(); + __testeof = __c == __eof; + __testdelim = __c == __idelim; + } + if ((_M_gcount == __n - 1 && !__testeof) || __testdelim) + ++_M_gcount; + if (__testeof) + this->setstate(ios_base::eofbit); + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + peek(void) + { + int_type __c = traits_type::eof(); + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + try { + __c = this->rdbuf()->sgetc(); + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return __c; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + read(char_type* __s, streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + if (__n > 0) + { + try { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sbumpc(); + bool __testeof = __c == __eof; + + while (_M_gcount < __n - 1 && !__testeof) + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->sbumpc(); + __testeof = __c == __eof; + } + if (__testeof) + this->setstate(ios_base::eofbit | ios_base::failbit); + else + { + // _M_gcount == __n - 1 + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + } + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + } + else + this->setstate(ios_base::failbit); + return *this; + } + + template<typename _CharT, typename _Traits> + streamsize + basic_istream<_CharT, _Traits>:: + readsome(char_type* __s, streamsize __n) + { + const int_type __eof = traits_type::eof(); + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + if (__n > 0) + { + try { + streamsize __num = this->rdbuf()->in_avail(); + if (__num != static_cast<streamsize>(__eof)) + { + __num = min(__num, __n); + _M_gcount = this->rdbuf()->sgetn(__s, __num); + } + else + this->setstate(ios_base::eofbit); + } + + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + } + else + this->setstate(ios_base::failbit); + return _M_gcount; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + putback(char_type __c) + { + sentry __cerb(*this, true); + if (__cerb) + { + try { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb || __sb->sputbackc(__c) == __eof) + this->setstate(ios_base::badbit); + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + else + this->setstate(ios_base::failbit); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + unget(void) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + try { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb || __eof == __sb->sungetc()) + this->setstate(ios_base::badbit); + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + else + this->setstate(ios_base::failbit); + return *this; + } + + template<typename _CharT, typename _Traits> + int + basic_istream<_CharT, _Traits>:: + sync(void) + { + int __ret = traits_type::eof(); + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + try { + __streambuf_type* __sb = this->rdbuf(); + if (!__sb || __ret == __sb->pubsync()) + this->setstate(ios_base::badbit); + else + __ret = 0; + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return __ret; + } + + template<typename _CharT, typename _Traits> + typename basic_istream<_CharT, _Traits>::pos_type + basic_istream<_CharT, _Traits>:: + tellg(void) + { + pos_type __ret = pos_type(-1); + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + try { + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in); + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return __ret; + } + + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(pos_type __pos) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + try { +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +// 136. seekp, seekg setting wrong streams? + this->rdbuf()->pubseekpos(__pos, ios_base::in); +#endif + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(off_type __off, ios_base::seekdir __dir) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + try { +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +// 136. seekp, seekg setting wrong streams? + this->rdbuf()->pubseekoff(__off, __dir, ios_base::in); +#endif + } + catch(exception& __fail){ + // 27.6.1.3 paragraph 1 + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + // 27.6.1.2.3 Character extraction templates + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try { + __in.get(__c); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + __in.setstate(ios_base::badbit); + if ((__in.exceptions() & ios_base::badbit) != 0) + throw; + } + } + else + __in.setstate(ios_base::failbit); + return __in; + } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename _Traits::int_type int_type; + typedef _CharT char_type; + typedef ctype<_CharT> __ctype_type; + int_type __extracted = 0; + + __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try { + // Figure out how many characters to extract. + int_type __num = static_cast<int_type>(__in.width()); + if (__num <= 0) + __num = basic_string<_CharT, _Traits>::npos; + + __streambuf_type* __sb = __in.rdbuf(); + const __ctype_type* __ctype = __in._M_get_fctype_ios(); + int_type __c = __sb->sbumpc(); + const int_type __eof = _Traits::eof(); + bool __testsp = __ctype->is(ctype_base::space, __c); + bool __testeof = __c == __eof; + + while (__extracted < __num - 1 && !__testeof && !__testsp) + { + *__s++ = __c; + ++__extracted; + __c = __sb->sbumpc(); + __testeof = __c == __eof; + __testsp = __ctype->is(ctype_base::space, __c); + } + + if (!__testeof) + __sb->sputbackc(__c); + else + __in.setstate(ios_base::eofbit); + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +//68. Extractors for char* should store null at end + *__s = char_type(); +#endif + __in.width(0); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + __in.setstate(ios_base::badbit); + if ((__in.exceptions() & ios_base::badbit) != 0) + throw; + } + } + if (!__extracted) + __in.setstate(ios_base::failbit); + return __in; + } + + // 27.6.1.4 Standard basic_istream manipulators + template<typename _CharT, typename _Traits> + basic_istream<_CharT,_Traits>& + ws(basic_istream<_CharT,_Traits>& __in) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::char_type __char_type; + + __streambuf_type* __sb = __in.rdbuf(); + const __ctype_type* __ctype = __in._M_get_fctype_ios(); + const __int_type __eof = _Traits::eof(); + __int_type __c; + bool __testeof; + bool __testsp; + + do + { + __c = __sb->sbumpc(); + __testeof = __c == __eof; + __testsp = __ctype->is(ctype_base::space, __c); + } + while (!__testeof && __testsp); + + if (!__testeof && !__testsp) + __sb->sputbackc(__c); + else + __in.setstate(ios_base::eofbit); + + return __in; + } + + // 21.3.7.8 basic_string::getline and operators + template<typename _CharT, typename _Traits, typename _Alloc> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __int_type __extracted = 0; + + __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + __str.erase(); + streamsize __w = __in.width(); + __size_type __n; + __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size(); + + __streambuf_type* __sb = __in.rdbuf(); + const __ctype_type* __ctype = __in._M_get_fctype_ios(); + __int_type __c = __sb->sbumpc(); + const __int_type __eof = _Traits::eof(); + bool __testsp = __ctype->is(ctype_base::space, __c); + bool __testeof = __c == __eof; + + while (__extracted <= __n && !__testeof && !__testsp) + { + __str += _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->sbumpc(); + __testeof = __c == __eof; + __testsp = __ctype->is(ctype_base::space, __c); + } + if (!__testeof) + __sb->sputbackc(__c); + else + __in.setstate(ios_base::eofbit); + __in.width(0); + } +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +// 2000-02-01 Number to be determined + if (!__extracted) + __in.setstate (ios_base::failbit); +#endif + return __in; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + bool __testdelim = false; + __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + __str.erase(); + __size_type __n = __str.max_size(); + + __int_type __idelim = _Traits::to_int_type(__delim); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sbumpc(); + const __int_type __eof = _Traits::eof(); + __testdelim = __c == __idelim; + bool __testeof = __c == __eof; + + while (__extracted <= __n && !__testeof && !__testdelim) + { + __str += _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->sbumpc(); + __testeof = __c == __eof; + __testdelim = __c == __idelim; + } + if (__testeof) + __in.setstate(ios_base::eofbit); + } + if (!__extracted && !__testdelim) + __in.setstate(ios_base::failbit); + return __in; + } + + template<class _CharT, class _Traits, class _Alloc> + inline basic_istream<_CharT,_Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT,_Traits,_Alloc>& __str) + { return getline(__in, __str, __in.widen('\n')); } + +} // namespace std + +// Local Variables: +// mode:C++ +// End: + + + + + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/limits_generic.h b/libstdc++-v3/include/bits/limits_generic.h new file mode 100644 index 00000000000..45fcccb12dc --- /dev/null +++ b/libstdc++-v3/include/bits/limits_generic.h @@ -0,0 +1,786 @@ +// The template and inlines for the -*- C++ -*- numeric_limits classes. + +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Note: this is not a conforming implementation. +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> + +// +// ISO 14882:1998 +// 18.2.1 +// + +#ifndef _CPP_NUMERIC_LIMITS +#define _CPP_NUMERIC_LIMITS 1 + +#include <bits/c++config.h> +#include <bits/std_cfloat.h> +#include <bits/std_climits.h> +#if defined( _GLIBCPP_USE_WCHAR_T) +#include <bits/std_cwchar.h> +#endif + +namespace std { + + 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 + }; + + template<typename _T> struct numeric_limits { + static const bool is_specialized = false; + + static _T min() throw() { return static_cast<_T>(0); } + static _T max() throw() { return static_cast<_T>(0); } + + static const int digits = 0; + static const int digits10 = 0; + static const bool is_signed = false; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = 0; + + static _T epsilon() throw() { return static_cast<_T>(0); } + static _T round_error() throw() { return static_cast<_T>(0); } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static _T infinity() throw() { return static_cast<_T>(0); } + static _T quiet_NaN() throw() { return static_cast<_T>(0); } + static _T signaling_NaN() throw() { return static_cast<_T>(0); } + static _T denorm_min() throw() { return static_cast<_T>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = false; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<typename _T> _T __limits_infinity(); + template<typename _T> _T __limits_quiet_NaN(); + template<typename _T> _T __limits_signaling_NaN(); + template<typename _T> _T __limits_denorm_min(); + + template<> struct numeric_limits<bool> { + static const bool is_specialized = true; + + static bool min() throw() + { return false; } + static bool max() throw() + { return true; } + + static const int digits = 8; + static const int digits10 = 2; + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static bool epsilon() throw() + { return 0; } + static bool round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static bool infinity() throw() + { return static_cast<bool>(0); } + static bool quiet_NaN() throw() + { return static_cast<bool>(0); } + static bool signaling_NaN() throw() + { return static_cast<bool>(0); } + static bool denorm_min() throw() + { return static_cast<bool>(0); } + + static const bool is_iec559 = true; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<char> { + static const bool is_specialized = true; + + static char min() throw() + { return CHAR_MIN; } + static char max() throw() + { return CHAR_MAX; } + + static const int digits = 7; + static const int digits10 = 2; + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static char epsilon() throw() + { return 0; } + static char round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static char infinity() throw() + { return static_cast<char>(0); } + static char quiet_NaN() throw() + { return static_cast<char>(0); } + static char signaling_NaN() throw() + { return static_cast<char>(0); } + static char denorm_min() throw() + { return static_cast<char>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<signed char> { + static const bool is_specialized = true; + + static signed char min() throw() + { return SCHAR_MIN; } + static signed char max() throw() + { return SCHAR_MAX; } + + static const int digits = 7; + static const int digits10 = 2; + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static signed char epsilon() throw() + { return 0; } + static signed char round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static signed char infinity() throw() + { return static_cast<signed char>(0); } + static signed char quiet_NaN() throw() + { return static_cast<signed char>(0); } + static signed char signaling_NaN() throw() + { return static_cast<signed char>(0); } + static signed char denorm_min() throw() + { return static_cast<signed char>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<unsigned char> { + static const bool is_specialized = true; + + static unsigned char min() throw() + { return 0; } + static unsigned char max() throw() + { return UCHAR_MAX; } + + static const int digits = 8; + static const int digits10 = 2; + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned char epsilon() throw() + { return 0; } + static unsigned char round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned char infinity() throw() + { return static_cast<unsigned char>(0); } + static unsigned char quiet_NaN() throw() + { return static_cast<unsigned char>(0); } + static unsigned char signaling_NaN() throw() + { return static_cast<unsigned char>(0); } + static unsigned char denorm_min() throw() + { return static_cast<unsigned char>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = true; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + +#if defined( _GLIBCPP_USE_WCHAR_T) + template<> struct numeric_limits<wchar_t> { + static const bool is_specialized = true; + + static wchar_t min() throw() + { return WCHAR_MIN; } + static wchar_t max() throw() + { return WCHAR_MAX; } + + static const int digits = 31; + static const int digits10 = 9; + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static wchar_t epsilon() throw() + { return 0; } + static wchar_t round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static wchar_t infinity() throw() + { return static_cast<wchar_t>(0); } + static wchar_t quiet_NaN() throw() + { return static_cast<wchar_t>(0); } + static wchar_t signaling_NaN() throw() + { return static_cast<wchar_t>(0); } + static wchar_t denorm_min() throw() + { return static_cast<wchar_t>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; +#endif + + template<> struct numeric_limits<short> { + static const bool is_specialized = true; + + static short min() throw() + { return SHRT_MIN; } + static short max() throw() + { return SHRT_MAX; } + + static const int digits = 15; + static const int digits10 = 4; + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static short epsilon() throw() + { return 0; } + static short round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static short infinity() throw() + { return static_cast<short>(0); } + static short quiet_NaN() throw() + { return static_cast<short>(0); } + static short signaling_NaN() throw() + { return static_cast<short>(0); } + static short denorm_min() throw() + { return static_cast<short>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<unsigned short> { + static const bool is_specialized = true; + + static unsigned short min() throw() + { return 0; } + static unsigned short max() throw() + { return USHRT_MAX; } + + static const int digits = 16; + static const int digits10 = 4; + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned short epsilon() throw() + { return 0; } + static unsigned short round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned short infinity() throw() + { return static_cast<unsigned short>(0); } + static unsigned short quiet_NaN() throw() + { return static_cast<unsigned short>(0); } + static unsigned short signaling_NaN() throw() + { return static_cast<unsigned short>(0); } + static unsigned short denorm_min() throw() + { return static_cast<unsigned short>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = true; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<int> { + static const bool is_specialized = true; + + static int min() throw() + { return INT_MIN; } + static int max() throw() + { return INT_MAX; } + + static const int digits = 31; + static const int digits10 = 9; + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static int epsilon() throw() + { return 0; } + static int round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static int infinity() throw() + { return static_cast<int>(0); } + static int quiet_NaN() throw() + { return static_cast<int>(0); } + static int signaling_NaN() throw() + { return static_cast<int>(0); } + static int denorm_min() throw() + { return static_cast<int>(0); } + + static const bool is_iec559 = true; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<unsigned int> { + static const bool is_specialized = true; + + static unsigned int min() throw() + { return 0; } + static unsigned int max() throw() + { return UINT_MAX; } + + static const int digits = 32; + static const int digits10 = 9; + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned int epsilon() throw() + { return 0; } + static unsigned int round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned int infinity() throw() + { return static_cast<unsigned int>(0); } + static unsigned int quiet_NaN() throw() + { return static_cast<unsigned int>(0); } + static unsigned int signaling_NaN() throw() + { return static_cast<unsigned int>(0); } + static unsigned int denorm_min() throw() + { return static_cast<unsigned int>(0); } + + static const bool is_iec559 = true; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = true; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<long> { + static const bool is_specialized = true; + + static long min() throw() + { return LONG_MIN; } + static long max() throw() + { return LONG_MAX; } + + static const int digits = 31; + static const int digits10 = 9; + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static long epsilon() throw() + { return 0; } + static long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static long infinity() throw() + { return static_cast<long>(0); } + static long quiet_NaN() throw() + { return static_cast<long>(0); } + static long signaling_NaN() throw() + { return static_cast<long>(0); } + static long denorm_min() throw() + { return static_cast<long>(0); } + + static const bool is_iec559 = true; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<unsigned long> { + static const bool is_specialized = true; + + static unsigned long min() throw() + { return 0; } + static unsigned long max() throw() + { return ULONG_MAX; } + + static const int digits = 32; + static const int digits10 = 9; + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned long epsilon() throw() + { return 0; } + static unsigned long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned long infinity() throw() + { return static_cast<unsigned long>(0); } + static unsigned long quiet_NaN() throw() + { return static_cast<unsigned long>(0); } + static unsigned long signaling_NaN() throw() + { return static_cast<unsigned long>(0); } + static unsigned long denorm_min() throw() + { return static_cast<unsigned long>(0); } + + static const bool is_iec559 = true; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = true; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<float> { + static const bool is_specialized = true; + + static float min() throw() + { return FLT_MIN; } + static float max() throw() + { return FLT_MAX; } + + static const int digits = FLT_MANT_DIG; + static const int digits10 = FLT_DIG; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = FLT_RADIX; + static float epsilon() throw() + { return FLT_EPSILON; } + static float round_error() throw() + { return FLT_ROUNDS; } + + static const int min_exponent = FLT_MIN_EXP; + static const int min_exponent10 = FLT_MIN_10_EXP; + static const int max_exponent = FLT_MAX_EXP; + static const int max_exponent10 = FLT_MAX_10_EXP; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static float infinity() throw() + { return static_cast<float>(0); } + static float quiet_NaN() throw() + { return static_cast<float>(0); } + static float signaling_NaN() throw() + { return static_cast<float>(0); } + static float denorm_min() throw() + { return static_cast<float>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<double> { + static const bool is_specialized = true; + + static double min() throw() + { return DBL_MIN; } + static double max() throw() + { return DBL_MAX; } + + static const int digits = DBL_MANT_DIG; + static const int digits10 = DBL_DIG; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = 2; + static double epsilon() throw() + { return DBL_EPSILON; } + static double round_error() throw() + { return 1.0; } + + static const int min_exponent = DBL_MIN_EXP; + static const int min_exponent10 = DBL_MIN_10_EXP; + static const int max_exponent = DBL_MAX_EXP; + static const int max_exponent10 = DBL_MAX_10_EXP; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static double infinity() throw() + { return static_cast<double>(0); } + static double quiet_NaN() throw() + { return static_cast<double>(0); } + static double signaling_NaN() throw() + { return static_cast<double>(0); } + static double denorm_min() throw() + { return static_cast<double>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> struct numeric_limits<long double> { + static const bool is_specialized = true; + + static double min() throw() + { return LDBL_MIN; } + static double max() throw() + { return LDBL_MAX; } + + static const int digits = LDBL_MANT_DIG; + static const int digits10 = LDBL_DIG; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = 2; + static double epsilon() throw() + { return LDBL_EPSILON; } + static double round_error() throw() + { return 1.0L; } + + static const int min_exponent = LDBL_MIN_EXP; + static const int min_exponent10 = LDBL_MIN_10_EXP; + static const int max_exponent = LDBL_MAX_EXP; + static const int max_exponent10 = LDBL_MAX_10_EXP; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static double infinity() throw() + { return static_cast<double>(0); } + static double quiet_NaN() throw() + { return static_cast<double>(0); } + static double signaling_NaN() throw() + { return static_cast<double>(0); } + static double denorm_min() throw() + { return static_cast<double>(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = false; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + +} // namespace std + +#endif // _CPP_NUMERIC_LIMITS diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h new file mode 100644 index 00000000000..732eafce4ca --- /dev/null +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -0,0 +1,1733 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997-2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +// Warning: this file is not meant for user inclusion. Use <locale>. + +#ifndef _CPP_BITS_LOCFACETS_H +#define _CPP_BITS_LOCFACETS_H 1 + +#include <bits/std_ctime.h> // For struct tm +#include <bits/std_typeinfo.h> // For bad_cast, which shouldn't be here. +#include <bits/std_ios.h> // For ios_base +#include <bits/std_cwctype.h> // For wctype_t + +namespace std +{ + // XXX This function is to be specialized for the "required" facets to + // be constructed lazily. The specializations must be declared after + // the definitions of the facets themselves; but they shouldn't be + // inline. Corresponding new's in locale::classic() should then be + // eliminated. Note that ctype<> should not get this treatment; + // see the use_facet<> specializations below. + // + struct _Bad_use_facet : public bad_cast + { + _Bad_use_facet() throw() {} + + _Bad_use_facet(_Bad_use_facet const& __b) throw() + : bad_cast(__b) { } + + _Bad_use_facet& + operator=(_Bad_use_facet const& __b) throw() + { + static_cast<bad_cast*>(this)->operator=(__b); + return *this; + } + + virtual char const* + what() const throw(); + + virtual + ~_Bad_use_facet() throw(); + }; + + template<typename _Facet> + const _Facet& + _Use_facet_failure_handler(const locale&) + { throw _Bad_use_facet(); } + + // 22.2.1 The ctype category + // Include host-specific ctype enums for ctype_base. + #include <bits/ctype_base.h> + + // 22.2.1.1 Template class ctype + // _Ctype_nois is the common base for ctype<char>. It lacks "do_is" + // and related virtuals. These are filled in by _Ctype, below. + template<typename _CharT> + class _Ctype_nois : public locale::facet, public ctype_base + { + public: + // Types: + typedef _CharT char_type; + + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } + + const char_type* + toupper(char_type *__low, const char_type* __high) const + { return this->do_toupper(__low, __high); } + + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } + + const char_type* + tolower(char_type* __low, const char_type* __high) const + { return this->do_tolower(__low, __high); } + + char_type + widen(char __c) const + { return this->do_widen(__c); } + + const char* + widen(const char* __low, const char* __high, char_type* __to) const + { return this->do_widen(__low, __high, __to); } + + char + narrow(char_type __c, char __dfault) const + { return this->do_narrow(__c, __dfault); } + + const char_type* + narrow(const char_type* __low, const char_type* __high, + char __dfault, char *__to) const + { return this->do_narrow(__low, __high, __dfault, __to); } + + protected: + explicit + _Ctype_nois(size_t __refs = 0): locale::facet(__refs) { } + + virtual + ~_Ctype_nois() { } + + virtual char_type + do_toupper(char_type) const = 0; + + virtual const char_type* + do_toupper(char_type* __low, const char_type* __high) const = 0; + + virtual char_type + do_tolower(char_type) const = 0; + + virtual const char_type* + do_tolower(char_type* __low, const char_type* __high) const = 0; + + virtual char_type + do_widen(char) const = 0; + + virtual const char* + do_widen(const char* __low, const char* __high, + char_type* __dest) const = 0; + + virtual char + do_narrow(char_type, char __dfault) const = 0; + + virtual const char_type* + do_narrow(const char_type* __low, const char_type* __high, + char __dfault, char* __dest) const = 0; + }; + + + template<typename _CharT> + class _Ctype : public _Ctype_nois<_CharT> + { + public: + // Types: + typedef _CharT char_type; + typedef typename _Ctype_nois<_CharT>::mask mask; + + bool + is(mask __m, char_type __c) const + { return this->do_is(__m, __c); } + + const char_type* + is(const char_type *__lo, const char_type *__hi, mask *__vec) const + { return this->do_is(__lo, __hi, __vec); } + + const char_type* + scan_is(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_is(__m, __lo, __hi); } + + const char_type* + scan_not(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_not(__m, __lo, __hi); } + + protected: + explicit + _Ctype(size_t __refs = 0) : _Ctype_nois<_CharT>(__refs) { } + + virtual + ~_Ctype() { } + + virtual bool + do_is(mask __m, char_type __c) const = 0; + + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, + mask* __vec) const = 0; + + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; + + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; + }; + + template<typename _CharT> + class ctype : public _Ctype<_CharT> + { + public: + // Types: + typedef _CharT char_type; + typedef typename ctype::mask mask; + + explicit + ctype(size_t __refs = 0) : _Ctype<_CharT>(__refs) { } + + static locale::id id; + + protected: + virtual + ~ctype() { } + + virtual bool + do_is(mask, char_type) const + { + // XXX Need definitions for these abstract mf's. + return true; + } + + virtual const char_type* + do_is(const char_type* __lo, const char_type*, mask*) const + { + // XXX Need definitions for these abstract mf's. + return __lo; + } + + virtual const char_type* + do_scan_is(mask, const char_type* __lo, const char_type*) const + { + // XXX Need definitions for these abstract mf's. + return __lo; + } + + virtual const char_type* + do_scan_not(mask, const char_type* __lo, const char_type*) const + { + // XXX Need definitions for these abstract mf's. + return __lo; + } + + virtual char_type + do_toupper(char_type __c) const + { + // XXX Need definitions for these abstract mf's. + return __c; + } + + virtual const char_type* + do_toupper(char_type* __lo, const char_type*) const + { + // XXX Need definitions for these abstract mf's. + return __lo; + } + + virtual char_type + do_tolower(char_type __c) const + { + // XXX Need definitions for these abstract mf's. + return __c; + } + + virtual const char_type* + do_tolower(char_type* __lo, const char_type*) const + { + // XXX Need definitions for these abstract mf's. + return __lo; + } + + virtual char_type + do_widen(char __c) const + { + // XXX Need definitions for these abstract mf's. + return __c; + } + + virtual const char* + do_widen(const char* __lo, const char*, char_type*) const + { + // XXX Need definitions for these abstract mf's. + return __lo; + } + + virtual char + do_narrow(char_type, char __c) const + { + // XXX Need definitions for these abstract mf's. + return __c; + } + + virtual const char_type* + do_narrow(const char_type* __lo, const char_type*, char, char*) const + { + // XXX Need definitions for these abstract mf's. + return __lo; + } + }; + + + // 22.2.1.3 ctype specializations + // NB: Can use _Ctype_nois to actually implement the "is" + // functionality in the non-virtual (thus inline-able) member + // fuctions. + template<> + class ctype<char> : public _Ctype_nois<char> + { + public: + // Types: + typedef char char_type; + typedef ctype::mask mask; + + private: + // Data Members: + bool _M_del; + __to_type const& _M_toupper; + __to_type const& _M_tolower; + const mask* const& _M_ctable; + const mask* _M_table; + + public: + static locale::id id; + static const size_t table_size = 1 + static_cast<unsigned char>(-1); + + explicit + ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); + + inline bool + is(mask __m, char __c) const throw(); + + inline const char* + is(const char* __low, const char* __high, mask* __vec) const throw(); + + inline const char* + scan_is(mask __m, const char* __low, const char* __high) const throw(); + + inline const char* + scan_not(mask __m, const char* __low, const char* __high) const throw(); + + protected: + virtual + ~ctype(); + + // XXX + const mask* + table() const throw() + { return _M_table; } + + // XXX + const mask* + classic_table() throw() + { return _M_ctable; } + + virtual char_type + do_toupper(char_type) const; + + virtual const char_type* + do_toupper(char_type* __low, const char_type* __high) const; + + virtual char_type + do_tolower(char_type) const; + + virtual const char_type* + do_tolower(char_type* __low, const char_type* __high) const; + + virtual char_type + do_widen(char) const; + + virtual const char* + do_widen(const char* __low, const char* __high, + char_type* __dest) const; + + virtual char + do_narrow(char_type, char __dfault) const; + + virtual const char_type* + do_narrow(const char_type* __low, const char_type* __high, + char __dfault, char* __dest) const; + }; + + template<> + const ctype<char>& + use_facet<const ctype<char> >(const locale& __loc); + +#ifdef _GLIBCPP_USE_WCHAR_T + // ctype<wchar_t> specialization + template<> + class ctype<wchar_t> : public _Ctype<wchar_t> + { + public: + // Types: + typedef wchar_t char_type; + typedef ctype::mask mask; + typedef wctype_t __wmask_type; + + // Data Members: + static locale::id id; + + explicit + ctype(size_t __refs = 0); + + protected: + __wmask_type + _M_convert_to_wmask(const mask __m) const + { + __wmask_type __ret; + switch (__m) + { + case space: + __ret = wctype("space"); + break; + case print: + __ret = wctype("print"); + break; + case cntrl: + __ret = wctype("cntrl"); + break; + case upper: + __ret = wctype("upper"); + break; + case lower: + __ret = wctype("lower"); + break; + case alpha: + __ret = wctype("alpha"); + break; + case digit: + __ret = wctype("digit"); + break; + case punct: + __ret = wctype("punct"); + break; + case xdigit: + __ret = wctype("xdigit"); + break; + case alnum: + __ret = wctype("alnum"); + break; + case graph: + __ret = wctype("graph"); + break; + default: + __ret = 0; + } + return __ret; + }; + + virtual + ~ctype(); + + virtual bool + do_is(mask __m, char_type __c) const; + + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, + mask* __vec) const; + + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, + const char_type* __hi) const; + + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const; + + virtual char_type + do_toupper(char_type) const; + + virtual const char_type* + do_toupper(char_type* __low, const char_type* __high) const; + + virtual char_type + do_tolower(char_type) const; + + virtual const char_type* + do_tolower(char_type* __low, const char_type* __high) const; + + virtual char_type + do_widen(char) const; + + virtual const char* + do_widen(const char* __low, const char* __high, + char_type* __dest) const; + + virtual char + do_narrow(char_type, char __dfault) const; + + virtual const char_type* + do_narrow(const char_type* __low, const char_type* __high, + char __dfault, char* __dest) const; + + }; + + template<> + const ctype<wchar_t>& + use_facet< const ctype<wchar_t> >(const locale& __loc); +#endif //_GLIBCPP_USE_WCHAR_T + + // Include host-specific ctype specializations. + #include <bits/ctype_specializations.h> + + // 22.2.1.2 Template class ctype_byname + template<typename _CharT> + class ctype_byname : public ctype<_CharT> + { + public: + typedef _CharT char_type; + + explicit + ctype_byname(const char*, size_t __refs = 0); + + protected: + virtual + ~ctype_byname() { } + }; + + // 22.2.1.4 Class ctype_byname specializations + template<> + ctype_byname<char>::ctype_byname(const char*, size_t refs); +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs); +#endif + + + template<typename _CharT, typename _InIter> + class _Numeric_get; // forward + + // _Format_cache holds the information extracted from the numpunct<> + // and moneypunct<> facets in a form optimized for parsing and + // formatting. It is stored via a void* pointer in the pword() + // array of an iosbase object passed to the _get and _put facets. + // NB: contains no user-serviceable parts. + template<typename _CharT> + class _Format_cache + { + public: + // Types: + typedef _CharT char_type; + typedef char_traits<_CharT> traits_type; + typedef basic_string<_CharT> string_type; + typedef typename string_type::size_type size_type; + + // Forward decls and Friends: + friend class locale; + template<typename _Char, typename _InIter> + friend class _Numeric_get; + friend class num_get<_CharT>; + friend class num_put<_CharT>; + friend class time_get<_CharT>; + friend class money_get<_CharT>; + friend class time_put<_CharT>; + friend class money_put<_CharT>; + + // Data Members: + + // ios_base::pword() reserved cell + static int _S_pword_ix; + + // True iff data members are consistent with the current locale, + // ie imbue sets this to false. + bool _M_valid; + + // A list of valid numeric literals: for the standard "C" locale, + // this would usually be: "-+xX0123456789abcdef0123456789ABCDEF" + static const char _S_literals[]; + + // NB: Code depends on the order of definitions of the names + // these are indices into _S_literals, above. + // This string is formatted for putting, not getting. (output, not input) + enum + { + _S_minus, + _S_plus, + _S_x, + _S_X, + _S_digits, + _S_digits_end = _S_digits + 16, + _S_udigits = _S_digits_end, + _S_udigits_end = _S_udigits + 16, + _S_ee = _S_digits + 14, // For scientific notation, 'E' + _S_Ee = _S_udigits + 14 // For scientific notation, 'e' + }; + + // The sign used to separate decimal values: for standard US + // locales, this would usually be: "." + // Abstracted from numpunct::decimal_point(). + char_type _M_decimal_point; + + // The sign used to separate groups of digits into smaller + // strings that the eye can parse with less difficulty: for + // standard US locales, this would usually be: "," + // Abstracted from numpunct::thousands_sep(). + char_type _M_thousands_sep; + + // However the US's "false" and "true" are translated. + // From numpunct::truename() and numpunct::falsename(), respectively. + string_type _M_truename; + string_type _M_falsename; + + // If we are checking groupings. This should be equivalent to + // numpunct::groupings().size() != 0 + bool _M_use_grouping; + + // If we are using numpunct's groupings, this is the current + // grouping string in effect (from numpunct::grouping()). + string _M_grouping; + + _Format_cache(); + + ~_Format_cache() throw() { } + + // Given a member of the ios heirarchy as an argument, extract + // out all the current formatting information into a + // _Format_cache object and return a pointer to it. + static _Format_cache<_CharT>* + _S_get(ios_base& __ios); + + void + _M_populate(ios_base&); + + static void + _S_callback(ios_base::event __event, ios_base& __ios, int __ix) throw(); + }; + + template<> _Format_cache<char>::_Format_cache(); +#ifdef _GLIBCPP_USE_WCHAR_T + template<> _Format_cache<wchar_t>::_Format_cache(); +#endif + + // _Numeric_get is used by num_get, money_get, and time_get to help + // in parsing out numbers. + template<typename _CharT, typename _InIter> + class _Numeric_get + { + public: + // Types: + typedef _CharT char_type; + typedef _InIter iter_type; + + // Forward decls and Friends: + template<typename _Char, typename _InIterT> + friend class num_get; + template<typename _Char, typename _InIterT> + friend class time_get; + template<typename _Char, typename _InIterT> + friend class money_get; + template<typename _Char, typename _InIterT> + friend class num_put; + template<typename _Char, typename _InIterT> + friend class time_put; + template<typename _Char, typename _InIterT> + friend class money_put; + + private: + explicit + _Numeric_get() { } + + virtual + ~_Numeric_get() { } + + iter_type + _M_get_digits(iter_type __in, iter_type __end) const; + }; + + template<typename _CharT, typename _InIter> + class num_get : public locale::facet + { + public: + // Types: + typedef _CharT char_type; + typedef _InIter iter_type; + typedef char_traits<_CharT> __traits_type; + + static locale::id id; + + explicit + num_get(size_t __refs = 0) : locale::facet(__refs) { } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { return do_get(__in, __end, __io, __err, __v); } + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, short& __v) const + { return do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, int& __v) const + { return do_get(__in, __end, __io, __err, __v); } +#endif + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { return do_get(__in, __end, __io, __err, __v); } + +#ifdef _GLIBCPP_USE_LONG_LONG + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { return do_get(__in, __end, __io, __err, __v); } +#endif + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { return do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { return do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { return do_get(__in, __end, __io, __err, __v); } + +#ifdef _GLIBCPP_USE_LONG_LONG + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { return do_get(__in, __end, __io, __err, __v); } +#endif + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { return do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { return do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { return do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { return do_get(__in, __end, __io, __err, __v); } + + protected: + virtual ~num_get() { } + + // This consolidates the extraction, storage and + // error-processing parts of the do_get(...) overloaded member + // functions. + // NB: This is specialized for char. + void + _M_extract(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, char* __xtrc, + int& __base, bool __fp = true) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, short&) const; + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, int&) const; +#endif + virtual iter_type + do_get (iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; +#ifdef _GLIBCPP_USE_LONG_LONG + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + long long&) const; +#endif + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned short&) const; + virtual iter_type + do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& __err, unsigned int&) const; + virtual iter_type + do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& __err, unsigned long&) const; +#ifdef _GLIBCPP_USE_LONG_LONG + virtual iter_type + do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& __err, unsigned long long&) const; +#endif + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + float&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + double&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& __err, long double&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + void*&) const; + }; + + // Declare specialized extraction member function. + template<> + void + num_get<char, istreambuf_iterator<char> >:: + _M_extract(istreambuf_iterator<char> __beg, + istreambuf_iterator<char> __end, ios_base& __io, + ios_base::iostate& __err, char* __xtrc, + int& __base, bool __fp) const; + + // _Numeric_put is used by num_put, money_put, and time_put + // to help in formatting out numbers. + template<typename _CharT, typename _OutIter> + class _Numeric_put + { + public: + typedef _CharT char_type; + typedef _OutIter iter_type; + protected: + explicit + _Numeric_put() { } + + virtual + ~_Numeric_put() { } + }; + + template<typename _CharT, typename _OutIter> + class num_put : public locale::facet + { + public: + // Types: + typedef _CharT char_type; + typedef _OutIter iter_type; + + static locale::id id; + + explicit + num_put(size_t __refs = 0) : locale::facet(__refs) { } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const + { return do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, long __v) const + { return do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + unsigned long __v) const + { return do_put(__s, __f, __fill, __v); } + +#ifdef _GLIBCPP_USE_LONG_LONG + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const + { return do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + unsigned long long __v) const + { return do_put(__s, __f, __fill, __v); } +#endif + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, double __v) const + { return do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + long double __v) const + { return do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + const void* __v) const + { return do_put(__s, __f, __fill, __v); } + + protected: + virtual + ~num_put() { }; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, bool __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long __v) const; + +#ifdef _GLIBCPP_USE_LONG_LONG + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long long __v) const; +#endif + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, unsigned long) const; + +#ifdef _GLIBCPP_USE_LONG_LONG + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const; +#endif + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, double __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long double __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, const void* __v) const; + }; + + template<typename _CharT> + class _Punct : public locale::facet + { + public: + // Types: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + char_type + decimal_point() const + { return do_decimal_point(); } + + char_type + thousands_sep() const + { return do_thousands_sep(); } + + string + grouping() const + { return do_grouping(); } + protected: + + explicit + _Punct(size_t __refs = 0) : locale::facet(__refs) { } + + virtual + ~_Punct() { } + + virtual char_type + do_decimal_point() const + { return _M_decimal_point; } + + virtual char_type + do_thousands_sep() const + { return _M_thousands_sep; } + + virtual string + do_grouping() const + { return _M_grouping; } + + private: + char_type _M_decimal_point; + char_type _M_thousands_sep; + string _M_grouping; + + protected: + // for use at construction time only: + void + _M_init(char_type __d, char_type __t, const string& __g) + { + _M_decimal_point = __d; + _M_thousands_sep = __t; + _M_grouping = __g; + } + + }; + + template<typename _CharT> + class _Numpunct : public _Punct<_CharT> + { + public: + // Types: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + string_type + truename() const + { return do_truename(); } + + string_type + falsename() const + { return do_falsename(); } + + protected: + explicit + _Numpunct(size_t __refs = 0) : _Punct<_CharT> (__refs) { } + + virtual + ~_Numpunct() { } + + virtual string_type + do_truename() const + { return _M_truename; } + + virtual string_type + do_falsename() const + { return _M_falsename; } + + private: + string_type _M_truename; + string_type _M_falsename; + + protected: + // For use only during construction + void + _M_boolnames_init(const string_type& __t, const string_type& __f) + { + _M_truename = __t; + _M_falsename = __f; + } + + }; + + template<typename _CharT> + class numpunct : public _Numpunct<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + static locale::id id; + + explicit + numpunct(size_t __refs = 0) : _Numpunct<_CharT>(__refs) { } + protected: + + virtual + ~numpunct() { } + }; + + template<> + numpunct<char>::numpunct(size_t __refs): _Numpunct<char>(__refs) + { + _M_init('.', ',', ""); + _M_boolnames_init("true", "false"); + } + +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + numpunct<wchar_t>::numpunct(size_t __refs): _Numpunct<wchar_t>(__refs) + { + _M_init(L'.', L',', ""); + _M_boolnames_init(L"true", L"false"); + } +#endif + + template<typename _CharT> + class numpunct_byname : public numpunct<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + numpunct_byname(const char*, size_t __refs = 0); + + protected: + virtual + ~numpunct_byname() { } + }; + + template<> + numpunct_byname<char>::numpunct_byname(const char*, size_t __refs); +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + numpunct_byname<wchar_t>::numpunct_byname(const char*, size_t __refs); +#endif + + template<typename _CharT> + class _Collate : public locale::facet + { + public: + // Types: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + int + compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const + { return do_compare(__lo1, __hi1, __lo2, __hi2); } + + string_type + transform(const _CharT* __lo, const _CharT* __hi) const + { return do_transform(__lo, __hi); } + + long + hash(const _CharT* __lo, const _CharT* __hi) const + { return do_hash(__lo, __hi); } + + protected: + explicit + _Collate(size_t __refs = 0) : locale::facet(__refs) { } + + ~_Collate() { } // virtual + + virtual int + do_compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const = 0; + + virtual string_type + do_transform(const _CharT* __lo, const _CharT* __hi) const = 0; + + virtual long + do_hash(const _CharT* __lo, const _CharT* __hi) const = 0; + }; + + template<typename _CharT> + class collate : public _Collate<_CharT> + { + public: + // Types: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + collate(size_t __refs = 0) : _Collate<_CharT> (__refs) { } + + static locale::id id; + + protected: + virtual + ~collate() { } + }; + + template<> + class collate<char> : public _Collate<char> + { + public: + // Types: + typedef char char_type; + typedef basic_string<char> string_type; + + explicit + collate(size_t __refs = 0); + + static locale::id id; + + protected: + virtual + ~collate(); + + virtual int + do_compare(const char* __lo1, const char* __hi1, + const char* __lo2, const char* __hi2) const; + + virtual string_type + do_transform(const char* __lo, const char* __hi) const; + + virtual long + do_hash(const char* __lo, const char* __hi) const; + }; + +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + class collate<wchar_t> : public _Collate<wchar_t> + { + public: + // Types: + typedef wchar_t char_type; + typedef basic_string<wchar_t> string_type; + + explicit + collate(size_t __refs = 0); + + static locale::id id; + + protected: + virtual + ~collate(); + + virtual int + do_compare(const wchar_t* __lo1, const wchar_t* __hi1, + const wchar_t* __lo2, const wchar_t* __hi2) const; + + virtual string_type + do_transform(const wchar_t* __lo, const wchar_t* __hi) const; + + virtual long + do_hash(const wchar_t* __lo, const wchar_t* __hi) const; + }; +#endif + + template<typename _CharT> + class collate_byname : public collate<_CharT> + { + public: + // Types: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + collate_byname(const char*, size_t __refs = 0); + + protected: + virtual + ~collate_byname() { } + }; + + template<> + collate_byname<char>::collate_byname(const char*, size_t __refs); +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + collate_byname<wchar_t>::collate_byname(const char*, size_t __refs); +#endif + + class time_base + { + public: + enum dateorder { no_order, dmy, mdy, ymd, ydm }; + }; + + template<typename _CharT, typename _InIter> + class time_get : public locale::facet, public time_base + { + public: + // Types: + typedef _CharT char_type; + typedef _InIter iter_type; + + static locale::id id; + + explicit + time_get(size_t __refs = 0) + : locale::facet (__refs), _M_daynames(0), _M_monthnames(0) { } + + dateorder + date_order() const + { return do_date_order(); } + + iter_type + get_time(iter_type __s, iter_type __end, ios_base& __f, + ios_base::iostate& __err, tm* __t) const + { return do_get_time(__s, __end, __f, __err, __t); } + + iter_type + get_date(iter_type __s, iter_type __end, ios_base& __f, + ios_base::iostate& __err, tm* __t) const + { return do_get_date(__s, __end, __f, __err, __t); } + + iter_type + get_weekday(iter_type __s, iter_type __end, ios_base& __f, + ios_base::iostate& __err, tm* __t) const + { return do_get_weekday(__s,__end,__f,__err,__t); } + + iter_type + get_monthname(iter_type __s, iter_type __end, ios_base& __f, + ios_base::iostate& __err, tm* __t) const + { return do_get_monthname(__s,__end,__f,__err,__t); } + + iter_type + get_year(iter_type __s, iter_type __end, ios_base& __f, + ios_base::iostate& __err, tm* __t) const + { return do_get_year(__s,__end,__f,__err,__t); } + + protected: + virtual + ~time_get() + { + delete [] _M_monthnames; + delete [] _M_daynames; + } + + virtual dateorder + do_date_order() const + { return time_base::ymd; } + + virtual iter_type + do_get_time(iter_type __s, iter_type /*__end*/, ios_base&, + ios_base::iostate& /*__err*/, tm* /*__t*/) const + { return __s; } + + virtual iter_type + do_get_date(iter_type __s, iter_type /*__end*/, ios_base&, + ios_base::iostate& /*__err*/, tm* /*__t*/) const + { return __s; } + + virtual iter_type + do_get_weekday(iter_type __s, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __t) const; + + virtual iter_type + do_get_monthname(iter_type __s, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __t) const; + + virtual iter_type + do_get_year(iter_type __s, iter_type /*__end*/, ios_base&, + ios_base::iostate& /*__err*/, tm* /*__t*/) const + { return __s; } + + mutable basic_string<_CharT>* _M_daynames; + mutable basic_string<_CharT>* _M_monthnames; + }; + + template<typename _CharT, typename _InIter> + class time_get_byname : public time_get<_CharT, _InIter> + { + public: + typedef _CharT char_type; + typedef _InIter iter_type; + + explicit + time_get_byname(const char*, size_t __refs = 0) + : time_get<_CharT, _InIter>(__refs) { } + protected: + virtual + ~time_get_byname() { } + }; + + template<typename _CharT, typename _OutIter> + class time_put : public locale::facet, public time_base + { + public: + typedef _CharT char_type; + typedef _OutIter iter_type; + + static locale::id id; + + explicit + time_put(size_t __refs = 0) : locale::facet (__refs) { } + + // NB: this is a nonvirtual, calls do_put in a loop. + iter_type + put(iter_type __s, ios_base& /*__f*/, char_type /*__fill*/, + const tm* /*__tmb*/, const _CharT* /*__pattern*/, + const _CharT* /*__pat_end*/) const + { return __s; } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + const tm* __tmb, char __format, char __modifier = 0) const + { return do_put(__s, __f, __fill, __tmb, __format, __modifier); } + + protected: + virtual + ~time_put() { } + + virtual iter_type + do_put(iter_type __s, ios_base&, char_type, const tm* /*__t*/, + char /*__format*/, char /*__mod*/) const + { return __s; } + }; + + template<typename _CharT, typename _OutIter> + class time_put_byname : public time_put<_CharT, _OutIter> + { + public: + typedef _CharT char_type; + typedef _OutIter iter_type; + + explicit + time_put_byname(const char*, size_t __refs = 0) + : time_put<_CharT, _OutIter> (__refs) { } + + protected: + virtual + ~time_put_byname() { } + }; + + + template<typename _CharT, typename _InIter> + class money_get : public locale::facet + { + public: + typedef _CharT char_type; + typedef _InIter iter_type; + typedef basic_string<_CharT> string_type; + + static locale::id id; + + explicit + money_get(size_t __refs = 0) : locale::facet(__refs) { } + + iter_type + get(iter_type __s, iter_type __end, bool __intl, + ios_base& __f, ios_base::iostate& __err, long double& __units) const + { return do_get(__s, __end, __intl, __f, __err, __units); } + + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __f, + ios_base::iostate& __err, string_type& __digits) const + { return do_get(__s, __end, __intl, __f, __err, __digits); } + + protected: + virtual + ~money_get() { } + + virtual iter_type + do_get(iter_type __s, iter_type /*__end*/, bool /*__intl*/, + ios_base& /*__io*/, ios_base::iostate& /*__err*/, + long double& /*__units*/) const + { return __s; } + + virtual iter_type + do_get(iter_type __s, iter_type /*__end*/, bool /*__intl*/, + ios_base& /*__io*/, ios_base::iostate& /*__err*/, + string_type& /*__digits*/) const + { return __s; } + }; + + template<typename _CharT, typename _OutIter> + class money_put : public locale::facet + { + public: + typedef _CharT char_type; + typedef _OutIter iter_type; + typedef basic_string<_CharT> string_type; + + static locale::id id; + + explicit + money_put(size_t __refs = 0) : locale::facet(__refs) { } + + iter_type + put(iter_type __s, bool __intl, ios_base& __f, + char_type __fill, long double __units) const + { return do_put(__s, __intl, __f, __fill, __units); } + + iter_type + put(iter_type __s, bool __intl, ios_base& __f, + char_type __fill, const string_type& __digits) const + { return do_put(__s, __intl, __f, __fill, __digits); } + + protected: + virtual + ~money_put() { } + + virtual iter_type + do_put(iter_type __s, bool, ios_base& /*__io*/, char_type /*__fill*/, + long double /*__units*/) const + { return __s; } + + virtual iter_type + do_put(iter_type __s, bool, ios_base& /*__io*/, char_type /*__fill*/, + const string_type& /*__digits*/) const + { return __s; } + }; + + struct money_base + { + enum part { none, space, symbol, sign, value }; + struct pattern { char field[4]; }; + + static const pattern _S_default_pattern; + }; + + template<typename _CharT> + class _Moneypunct : public _Punct<_CharT>, public money_base + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + string_type + curr_symbol() const + { return do_curr_symbol(); } + + string_type + positive_sign() const + { return do_positive_sign(); } + + string_type + negative_sign() const + { return do_negative_sign(); } + + int + frac_digits() const + { return do_frac_digits(); } + + pattern + pos_format() const + { return do_pos_format(); } + + pattern + neg_format() const + { return do_neg_format(); } + + protected: + explicit + _Moneypunct(size_t __refs = 0) : _Punct<_CharT> (__refs) { } + + virtual + ~_Moneypunct() { } + + virtual string_type + do_curr_symbol() const + { return basic_string<_CharT>(); } + + virtual string_type + do_positive_sign() const + { return basic_string<_CharT>(); } + + virtual string_type + do_negative_sign() const + { return basic_string<_CharT>(); } + + virtual int + do_frac_digits() const + { return 0; } + + virtual pattern + do_pos_format() const + { return money_base::_S_default_pattern; } + + virtual pattern + do_neg_format() const + { return money_base::_S_default_pattern; } + }; + + template<typename _CharT, bool _Intl> + class moneypunct : public _Moneypunct<_CharT> + { + public: + // Types: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + static const bool intl = _Intl; + static locale::id id; + + explicit + moneypunct(size_t __refs = 0) : _Moneypunct<_CharT> (__refs) { } + + protected: + virtual + ~moneypunct() { } + }; + + template<typename _CharT, bool _Intl> + class moneypunct_byname : public moneypunct<_CharT,_Intl> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + static const bool intl = _Intl; + + explicit + moneypunct_byname(const char*, size_t __refs = 0); + + protected: + virtual + ~moneypunct_byname() { } + }; + + template<> + moneypunct_byname<char, false>:: + moneypunct_byname(const char*, size_t __refs); + template<> + moneypunct_byname<char, true>:: + moneypunct_byname(const char*, size_t __refs); +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + moneypunct_byname<wchar_t,false>:: + moneypunct_byname(const char*, size_t __refs); + template<> + moneypunct_byname<wchar_t,true>:: + moneypunct_byname (const char*, size_t __refs); +#endif + + struct messages_base + { + typedef int catalog; + }; + + template<typename _CharT> + class _Messages : public locale::facet, public messages_base + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + catalog + open(const basic_string<char>& __s, const locale& __loc) const + { return do_open(__s, __loc); } + + string_type + get(catalog __c, int __set, int __msgid, const string_type& __s) const + { return do_get(__c,__set,__msgid,__s); } + + void + close(catalog __c) const + { return do_close(__c); } + + protected: + explicit + _Messages(size_t __refs = 0) : locale::facet(__refs) { } + + virtual + ~_Messages() { } + + // NB: Probably these should be pure, and implemented only in + // specializations of messages<>. But for now... + virtual catalog + do_open(const basic_string<char>&, const locale&) const + { return 0; } + + virtual string_type + do_get(catalog, int, int /*__msgid*/, const string_type& __dfault) const + { return __dfault; } + + virtual void + do_close (catalog) const { } + }; + + template<typename _CharT> + class messages : public _Messages<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + static locale::id id; + + explicit + messages(size_t __refs = 0) : _Messages<_CharT> (__refs) { } + protected: + virtual + ~messages() { } + }; + + template<typename _CharT> + class messages_byname : public messages<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + messages_byname(const char*, size_t __refs = 0); + + protected: + virtual + ~messages_byname() { } + }; + + template<> + messages_byname<char>::messages_byname(const char*, size_t __refs); +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + messages_byname<wchar_t>::messages_byname(const char*, size_t __refs); +#endif + + // Subclause convenience interfaces, inlines + // NB: these are inline + // because, when used in a loop, some compilers can hoist the body + // out of the loop; then it's just as fast as the C is*() function. + template<typename _CharT> + inline bool + isspace(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); } + + template<typename _CharT> + inline bool + isprint(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); } + + template<typename _CharT> + inline bool + iscntrl(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); } + + template<typename _CharT> + inline bool + isupper(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); } + + template<typename _CharT> + inline bool islower(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); } + + template<typename _CharT> + inline bool + isalpha(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); } + + template<typename _CharT> + inline bool + isdigit(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); } + + template<typename _CharT> + inline bool + ispunct(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); } + + template<typename _CharT> + inline bool + isxdigit(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); } + + template<typename _CharT> + inline bool + isalnum(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); } + + template<typename _CharT> + inline bool + isgraph(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); } + + template<typename _CharT> + inline _CharT + toupper(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).toupper(__c); } + + template<typename _CharT> + inline _CharT + tolower(_CharT __c, const locale& __loc) + { return use_facet<ctype<_CharT> >(__loc).tolower(__c); } + +} // namespace std + +#endif /* _CPP_BITS_LOCFACETS_H */ + +// Local Variables: +// mode:c++ +// End: + diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc new file mode 100644 index 00000000000..594e6047a31 --- /dev/null +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -0,0 +1,1277 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Warning: this file is not meant for user inclusion. Use <locale>. + +#ifndef _CPP_BITS_LOCFACETS_TCC +#define _CPP_BITS_LOCFACETS_TCC 1 + +#include <bits/std_cerrno.h> +#include <bits/std_cstdlib.h> // For strof, strtold +#include <bits/std_limits.h> // For numeric_limits +#include <bits/std_memory.h> // For auto_ptr +#include <bits/sbuf_iter.h> // For streambuf_iterators +#include <bits/std_cctype.h> // For isspace +#include <bits/std_vector.h> + +namespace std +{ + template<typename _Facet> + locale + locale::combine(const locale& __other) + { + locale __copy(*this); + __copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id); + __copy._M_impl->_M_has_name = false; + return __copy; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + bool + locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, + const basic_string<_CharT, _Traits, _Alloc>& __s2) const + { + // XXX should not need to qualify here. + // typedef collate<_CharT> __collate_type; + typedef std::collate<_CharT> __collate_type; + const __collate_type* __fcoll = &use_facet<__collate_type>(*this); + return (__fcoll->compare(__s1.data(), __s1.data() + __s1.length(), + __s2.data(), __s2.data() + __s2.length()) < 0); + } + + template<typename _Facet> + const _Facet& + use_facet(const locale& __loc) + { + typedef locale::_Impl::__vec_facet __vec_facet; + const locale::facet* __fp = (const _Facet*)0; // check derivation + locale::id& __id = _Facet::id; // check member id + size_t __i = __id._M_index; + __vec_facet* __facet = __loc._M_impl->_M_facets; + if (__i >= __facet->size() || (__fp = (*(__facet))[__i]) == 0) + return _Use_facet_failure_handler<_Facet>(__loc); + return static_cast<const _Facet&>(*__fp); + } + + template<typename _Facet> + bool + has_facet(const locale& __loc) throw() + { + typedef locale::_Impl::__vec_facet __vec_facet; + locale::id& __id = _Facet::id; // check member id + size_t __i = __id._M_index; + __vec_facet* __facet = __loc._M_impl->_M_facets; + return (__i < __facet->size() && (*__facet)[__i] != 0); + } + + // __match_parallel + // matches input __s against a set of __ntargs strings in __targets, + // placing in __matches a vector of indices into __targets which + // match, and in __remain the number of such matches. If it hits + // end of sequence before it minimizes the set, sets __eof. + // Empty strings are never matched. + template<typename _InIter, typename _CharT> + _InIter + __match_parallel(_InIter __s, _InIter __end, int __ntargs, + const basic_string<_CharT>* __targets, + int* __matches, int& __remain, bool& __eof) + { + typedef basic_string<_CharT> __string_type; + __eof = false; + for (int __ti = 0; __ti < __ntargs; ++__ti) + __matches[__ti] = __ti; + __remain = __ntargs; + size_t __pos = 0; + do + { + { + int __ti = 0; + for (;__ti < __remain && + __pos == __targets[__matches[__ti]].size(); ++__ti) + { } + if (__ti == __remain) + { + if (__pos == 0) __remain = 0; + return __s; + } + } + if (__s == __end) + __eof = true; + bool __matched = false; + for (int __ti = 0; __ti < __remain; ) + { + const __string_type& __target = __targets[__matches[__ti]]; + if (__pos < __target.size()) + { + if (__eof || __target[__pos] != *__s) + { + __matches[__ti] = __matches[--__remain]; + continue; + } + __matched = true; + } + ++__ti; + } + if (__matched) + { + ++__s; + ++__pos; + } + for (int __ti = 0; __ti < __remain;) + { + if (__pos > __targets[__matches[__ti]].size()) + { + __matches[__ti] = __matches[--__remain]; + continue; + } + ++__ti; + } + } + while (__remain); + return __s; + } + + template<typename _CharT> + locale::id ctype<_CharT>::id; + + template<typename _CharT> + int _Format_cache<_CharT>::_S_pword_ix; + + template<typename _CharT> + const char _Format_cache<_CharT>:: + _S_literals[] = "-+xX0123456789abcdef0123456789ABCDEF"; + + template<typename _CharT> + _Format_cache<_CharT>::_Format_cache() + : _M_valid(true), _M_use_grouping(false) + { } + + template<> + _Format_cache<char>::_Format_cache(); + + template<> + _Format_cache<wchar_t>::_Format_cache(); + + template<typename _CharT> + void + _Format_cache<_CharT>::_M_populate(ios_base& __io) + { + locale __loc = __io.getloc (); + numpunct<_CharT> const& __np = use_facet<numpunct<_CharT> >(__loc); + _M_truename = __np.truename(); + _M_falsename = __np.falsename(); + _M_thousands_sep = __np.thousands_sep(); + _M_decimal_point = __np.decimal_point(); + _M_grouping = __np.grouping(); + _M_use_grouping = _M_grouping.size() != 0 && _M_grouping.data()[0] != 0; + _M_valid = true; + } + + // This function is always called via a pointer installed in + // an ios_base by ios_base::register_callback. + template<typename _CharT> + void + _Format_cache<_CharT>:: + _S_callback(ios_base::event __ev, ios_base& __ios, int __ix) throw() + { + void*& __p = __ios.pword(__ix); + switch (__ev) + { + case ios_base::erase_event: + delete static_cast<_Format_cache<_CharT>*> (__p); __p = 0; + break; + case ios_base::copyfmt_event: + // If just stored zero, the callback would get registered again. + try { + __p = new _Format_cache<_CharT>; + } + catch(...) { + } + break; + case ios_base::imbue_event: + static_cast<_Format_cache<_CharT>*>(__p)->_M_valid = false; + break; + } + } + + template<typename _CharT> + _Format_cache<_CharT>* + _Format_cache<_CharT>::_S_get(ios_base& __ios) + { + if (!_S_pword_ix) + _S_pword_ix = ios_base::xalloc(); // XXX MT + void*& __p = __ios.pword(_S_pword_ix); + + // XXX What if pword fails? must check failbit, throw. + if (__p == 0) // XXX MT? maybe sentry takes care of it + { + auto_ptr<_Format_cache<_CharT> > __ap(new _Format_cache<_CharT>); + __ios.register_callback(&_Format_cache<_CharT>::_S_callback, + _S_pword_ix); + __p = __ap.release(); + } + _Format_cache<_CharT>* __ncp = static_cast<_Format_cache<_CharT>*>(__p); + if (!__ncp->_M_valid) + __ncp->_M_populate(__ios); + + return __ncp; + } + + template<typename _CharT, typename _InIter> + locale::id num_get<_CharT, _InIter>::id; + + // This member function takes an (w)istreambuf_iterator object and + // parses it into a generic char array suitable for parsing with + // strto[l,ll,f,d]. The thought was to encapsulate the conversion + // into this one function, and thus the num_get::do_get member + // functions can just adjust for the type of the overloaded + // argument and process the char array returned from _M_extract. + // Other things were also considered, including a fused + // multiply-add loop that would obviate the need for any call to + // strto... at all: however, it would b e a bit of a pain, because + // you'd have to be able to return either floating or integral + // types, etc etc. The current approach seems to be smack dab in + // the middle between an unoptimized approach using sscanf, and + // some kind of hyper-optimized approach alluded to above. + + // XXX + // Need to do partial specialization to account for differences + // between character sets. For char, this is pretty + // straightforward, but for wchar_t, the conversion to a plain-jane + // char type is a bit more involved. + template<typename _CharT, typename _InIter> + void + num_get<_CharT, _InIter>:: + _M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/, + ios_base::iostate& /*__err*/, char* /*__xtrc*/, + int& /*__base*/, bool /*__fp*/) const + { + // XXX Not currently done: need to expand upon char version below. + } + + template<> + void + num_get<char, istreambuf_iterator<char> >:: + _M_extract(istreambuf_iterator<char> __beg, + istreambuf_iterator<char> __end, ios_base& __io, + ios_base::iostate& __err, char* __xtrc, int& __base, + bool __fp) const; + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // NB: This is an unresolved library defect #17 + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { + // Parse bool values as long + if (!(__io.flags() & ios_base::boolalpha)) + { + // NB: We can't just call do_get(long) here, as it might + // refer to a derived class. + + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32] = {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + long __l = strtol(__xtrc, &__sanity, __base); + if (!(__err & ios_base::failbit) + && __l <= 1 + && __sanity != __xtrc && *__sanity == '\0' && errno == 0) + __v = __l; + else + __err |= ios_base::failbit; + } + + // Parse bool values as alphanumeric + else + { + typedef _Format_cache<char_type> __fcache_type; + __fcache_type* __fmt = __fcache_type::_S_get(__io); + const char_type* __true = __fmt->_M_truename.c_str(); + const char_type* __false = __fmt->_M_falsename.c_str(); + const size_t __truelen = __traits_type::length(__true) - 1; + const size_t __falselen = __traits_type::length(__false) - 1; + + for (size_t __pos = 0; __beg != __end; ++__pos) + { + char_type __c = *__beg++; + bool __testf = __c == __false[__pos]; + bool __testt = __c == __true[__pos]; + if (!(__testf || __testt)) + { + __err |= ios_base::failbit; + break; + } + else if (__testf && __pos == __falselen) + { + __v = 0; + break; + } + else if (__testt && __pos == __truelen) + { + __v = 1; + break; + } + } + if (__beg == __end) + __err |= ios_base::eofbit; + } + + return __beg; + } +#endif + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, short& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + long __l = strtol(__xtrc, &__sanity, __base); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0 + && __l >= SHRT_MIN && __l <= SHRT_MAX) + __v = static_cast<short>(__l); + else + __err |= ios_base::failbit; + + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, int& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32] = {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + long __l = strtol(__xtrc, &__sanity, __base); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0 + && __l >= INT_MIN && __l <= INT_MAX) + __v = static_cast<int>(__l); + else + __err |= ios_base::failbit; + + return __beg; + } +#endif + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + long __l = strtol(__xtrc, &__sanity, __base); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0) + __v = __l; + else + __err |= ios_base::failbit; + + return __beg; + } + +#ifdef _GLIBCPP_USE_LONG_LONG + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + long long __ll = strtoll(__xtrc, &__sanity, __base); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0) + __v = __ll; + else + __err |= ios_base::failbit; + + return __beg; + } +#endif + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + unsigned long __ul = strtoul(__xtrc, &__sanity, __base); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0 + && __ul <= USHRT_MAX) + __v = static_cast<unsigned short>(__ul); + else + __err |= ios_base::failbit; + + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + unsigned long __ul = strtoul(__xtrc, &__sanity, __base); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0 + && __ul <= UINT_MAX) + __v = static_cast<unsigned int>(__ul); + else + __err |= ios_base::failbit; + + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32] = {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + unsigned long __ul = strtoul(__xtrc, &__sanity, __base); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0) + __v = __ul; + else + __err |= ios_base::failbit; + + return __beg; + } + +#ifdef _GLIBCPP_USE_LONG_LONG + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + unsigned long long __ull = strtoull(__xtrc, &__sanity, __base); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0) + __v = __ull; + else + __err |= ios_base::failbit; + + return __beg; + } +#endif + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 256 for + // floating-point types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, true); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; +#ifdef _GLIBCPP_HAVE_STRTOF + float __f = strtof(__xtrc, &__sanity); +#else + float __f = static_cast<float>(strtod(__xtrc, &__sanity)); +#endif + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0) + __v = __f; + else + __err |= ios_base::failbit; + + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 256 for + // floating-point types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, true); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + double __d = strtod(__xtrc, &__sanity); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0) + __v = __d; + else + __err |= ios_base::failbit; + + return __beg; + } + +#if defined(_GLIBCPP_HAVE_STRTOLD) && !defined(__hpux) + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 256 for + // floating-point types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, true); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + long double __ld = strtold(__xtrc, &__sanity); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0) + __v = __ld; + else + __err |= ios_base::failbit; + + return __beg; + } +#else + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { + // Stage 1: extract + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, true); + + // Stage 2: determine a conversion specifier. + ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; + const char* __conv; + if (__basefield == ios_base::oct) + __conv = "%Lo"; + else if (__basefield == ios_base::hex) + __conv = "%LX"; + else if (__basefield == 0) + __conv = "%Li"; + else + __conv = "%Lg"; + + // Stage 3: store results. + long double __ld; + int __p = sscanf(__xtrc, __conv, &__ld); + if (__p + && static_cast<__traits_type::int_type>(__p) != __traits_type::eof()) + __v = __ld; + else + __err |= ios_base::failbit; + + return __beg; + } +#endif + + template<typename _CharT, typename _InIter> + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { + // Prepare for hex formatted input + typedef ios_base::fmtflags fmtflags; + fmtflags __fmt = __io.flags(); + fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield + | ios_base::uppercase | ios_base::internal); + __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase)); + + // Stage 1: extract and determine the conversion specifier. + // Assuming leading zeros eliminated, thus the size of 32 for + // integral types. + char __xtrc[32]= {'\0'}; + int __base; + _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); + + // Stage 2: convert and store results. + char* __sanity; + errno = 0; + void* __vp = reinterpret_cast<void*>(strtoul(__xtrc, &__sanity, __base)); + if (!(__err & ios_base::failbit) + && __sanity != __xtrc && *__sanity == '\0' && errno == 0) + __v = __vp; + else + __err |= ios_base::failbit; + + // Reset from hex formatted input + __io.flags(__fmt); + return __beg; + } + + template <typename _CharT, typename _OutIter> + locale::id num_put<_CharT, _OutIter>::id; + + // _S_fill is specialized for ostreambuf_iterator, random access iterator. + template <typename _CharT, typename _OutIter> + inline _OutIter + _S_fill(_OutIter __s, _CharT __fill, int __padding); + + template <typename _CharT, typename _RaIter> + _RaIter + _S_fill(_RaIter __s, _CharT __fill, int __padding, + random_access_iterator_tag) + { + fill_n(__s, __fill); + return __s + __padding; + } + + template <typename _CharT, typename _OutIter, typename _Tag> + _OutIter + _S_fill(_OutIter __s, _CharT __fill, int __padding, _Tag) + { + while (--__padding >= 0) { *__s = __fill; ++__s; } + return __s; + } + + template <typename _CharT, typename _OutIter> + inline _OutIter + _S_fill(_OutIter __s, _CharT __fill, int __padding) + { + return _S_fill(__s, __fill, __padding, + iterator_traits<_OutIter>::iterator_category()); + } + + template <typename _CharT, typename _OutIter> + _OutIter + _S_pad_numeric(_OutIter __s, ios_base::fmtflags /*__flags*/, + _CharT /*__fill*/, int /*__width*/, + _CharT const* /*__first*/, _CharT const* /*__middle*/, + _CharT const* /*__last*/) + { + // XXX Not currently done: non streambuf_iterator + return __s; + } + + // Partial specialization for ostreambuf_iterator. + template <typename _CharT> + ostreambuf_iterator<_CharT> + _S_pad_numeric(ostreambuf_iterator<_CharT> __s, ios_base::fmtflags __flags, + _CharT __fill, int __width, _CharT const* __first, + _CharT const* __middle, _CharT const* __last) + { + typedef ostreambuf_iterator<_CharT> __out_iter; + int __padding = __width - (__last - __first); + if (__padding < 0) + __padding = 0; + ios_base::fmtflags __aflags = __flags & ios_base::adjustfield; + bool __testfield = __padding == 0 || __aflags == ios_base::left + || __aflags == ios_base::internal; + + // This was needlessly complicated. + if (__first != __middle) + { + if (!__testfield) + { + _S_fill(__s, __fill, __padding); + __padding = 0; + } + copy(__first, __middle, __s); + } + __out_iter __s2 = __s; + + if (__padding && __aflags != ios_base::left) + { + _S_fill(__s2, __fill, __padding); + __padding = 0; + } + __out_iter __s3 = copy(__middle, __last, __s2); + if (__padding) + _S_fill(__s3, __fill, __padding); + return __s3; + } + + template <typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const + { + const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io); + ios_base::fmtflags __flags = __io.flags(); + + if ((__flags & ios_base::boolalpha) == 0) + { + unsigned long __uv = __v; + return _S_format(__s, __io, __fill, false, __uv); + } + else + { + const char_type* __first; + const char_type* __last; + if (__v) + { + __first = __fmt->_M_truename.data(); + __last = __first + __fmt->_M_truename.size(); + } + else + { + __first = __fmt->_M_falsename.data(); + __last = __first + __fmt->_M_falsename.size(); + } + copy(__first, __last, __s); + } + return __s; + } + + // _S_group_digits inserts "group separator" characters into an array + // of characters. It's recursive, one iteration per group. It moves + // the characters in the buffer this way: "xxxx12345" -> "12,345xxx". + // Call this only with __grouping != __grend. + template <typename _CharT> + _CharT* + _S_group_digits(_CharT* __s, _CharT __grsep, char const* __grouping, + char const* __grend, _CharT const* __first, + _CharT const* __last) + { + if (__last - __first > *__grouping) + { + __s = _S_group_digits(__s, __grsep, + (__grouping + 1 == __grend ? __grouping : __grouping + 1), + __grend, __first, __last - *__grouping); + __first = __last - *__grouping; + *__s++ = __grsep; + } + do + { + *__s++ = *__first++; + } + while (__first != __last); + return __s; + } + + template <typename _CharT, typename _OutIter, typename _ValueT> + _OutIter + _S_format(_OutIter __s, ios_base& __io, _CharT __fill, bool __neg, + _ValueT __v) + { + // Leave room for "+/-," "0x," and commas. + const long _M_room = numeric_limits<_ValueT>::digits10 * 2 + 4; + _CharT __digits[_M_room]; + _CharT* __front = __digits + _M_room; + ios_base::fmtflags __flags = __io.flags(); + const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io); + char const* __table = __fmt->_S_literals + __fmt->_S_digits; + + ios_base::fmtflags __basefield = (__flags & __io.basefield); + _CharT* __sign_end = __front; + if (__basefield == ios_base::hex) + { + if (__flags & ios_base::uppercase) + __table += 16; // use ABCDEF + do + *--__front = __table[__v & 15]; + while ((__v >>= 4) != 0); + __sign_end = __front; + if (__flags & ios_base::showbase) + { + *--__front = __fmt->_S_literals[__fmt->_S_x + + ((__flags & ios_base::uppercase) ? 1 : 0)]; + *--__front = __table[0]; + } + } + else if (__basefield == ios_base::oct) + { + do + *--__front = __table[__v & 7]; + while ((__v >>= 3) != 0); + if (__flags & ios_base::showbase + && static_cast<char>(*__front) != __table[0]) + *--__front = __table[0]; + __sign_end = __front; + } + else + { + // NB: This is _lots_ faster than using ldiv. + do + *--__front = __table[__v % 10]; + while ((__v /= 10) != 0); + __sign_end = __front; + // NB: ios_base:hex || ios_base::oct assumed to be unsigned. + if (__neg || (__flags & ios_base::showpos)) + *--__front = __fmt->_S_literals[__fmt->_S_plus - __neg]; + } + + // XXX should specialize! + if (!__fmt->_M_use_grouping && !__io.width()) + return copy(__front, __digits + _M_room, __s); + + if (!__fmt->_M_use_grouping) + return _S_pad_numeric(__s, __flags, __fill, __io.width(0), + __front, __sign_end, __digits + _M_room); + + _CharT* __p = __digits; + while (__front < __sign_end) + *__p++ = *__front++; + const char* __gr = __fmt->_M_grouping.data(); + __front = _S_group_digits(__p, __fmt->_M_thousands_sep, __gr, + __gr + __fmt->_M_grouping.size(), __sign_end, __digits + _M_room); + return _S_pad_numeric(__s, __flags, __fill, __io.width(0), + __digits, __p, __front); + } + + template <typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const + { + unsigned long __uv = __v; + bool __neg = false; + if (__v < 0) + { + __neg = true; + __uv = -__uv; + } + return _S_format(__s, __io, __fill, __neg, __uv); + } + + template <typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long __v) const + { return _S_format(__s, __io, __fill, false, __v); } + +#ifdef _GLIBCPP_USE_LONG_LONG + template <typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const + { + unsigned long long __uv = __v; + bool __neg = false; + if (__v < 0) + { + __neg = true; + __uv = -__uv; + } + return _S_format(__s, __b, __fill, __neg, __uv); + } + + template <typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long long __v) const + { return _S_format(__s, __io, __fill, false, __v); } +#endif + + // Generic helper function + template<typename _CharT, typename _OutIter> + static _OutIter + _S_output_float(_OutIter __s, ios_base& __io, _CharT __fill, + const char* __sptr, size_t __slen) + { + // XXX Not currently done: non streambuf_iterator + return __s; + } + + // Partial specialization for ostreambuf_iterator. + template<typename _CharT> + static ostreambuf_iterator<_CharT> + _S_output_float(ostreambuf_iterator<_CharT> __s, ios_base& __io, + _CharT __fill, const char* __sptr, size_t __slen) + { + size_t __padding = __io.width() > streamsize(__slen) ? + __io.width() -__slen : 0; + locale __loc = __io.getloc(); + ctype<_CharT> const& __ct = use_facet<ctype<_CharT> >(__loc); + ios_base::fmtflags __adjfield = __io.flags() & ios_base::adjustfield; + const char* const __eptr = __sptr + __slen; + // [22.2.2.2.2.19] Table 61 + if (__adjfield == ios_base::internal) + { + // [22.2.2.2.2.14]; widen() + if (__sptr < __eptr && (*__sptr == '+' || *__sptr == '-')) + { + __s = __ct.widen(*__sptr); + ++__s; + ++__sptr; + } + __s = _S_fill(__s, __fill, __padding); + __padding = 0; + } + else if (__adjfield != ios_base::left) + { + __s = _S_fill(__s, __fill, __padding); + __padding = 0; + } + // the "C" locale decimal character + char __decimal_point = *(localeconv()->decimal_point); + const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io); + for (; __sptr != __eptr; ++__s, ++__sptr) + { + // [22.2.2.2.2.17]; decimal point conversion + if (*__sptr == __decimal_point) + __s = __fmt->_M_decimal_point; + // [22.2.2.2.2.14]; widen() + else + __s = __ct.widen(*__sptr); + } + // [22.2.2.2.2.19] Table 61 + if (__padding) + _S_fill(__s, __fill, __padding); + __io.width(0); + return __s; + } + + bool + _S_build_float_format(ios_base& __io, char* __fptr, char __modifier, + streamsize __prec); + + template <typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const + { + const streamsize __max_prec = numeric_limits<double>::digits10 + 3; + streamsize __prec = __io.precision(); + // Protect against sprintf() buffer overflows. + if (__prec > __max_prec) + __prec = __max_prec; + // The *2 provides for signs, exp, 'E', and pad. + char __sbuf[__max_prec*2]; + size_t __slen; + // Long enough for the max format spec. + char __fbuf[16]; + if (_S_build_float_format(__io, __fbuf, 0, __prec)) + __slen = sprintf(__sbuf, __fbuf, __prec, __v); + else + __slen = sprintf(__sbuf, __fbuf, __v); + // [22.2.2.2.2] Stages 2-4. + return _S_output_float(__s, __io, __fill, __sbuf, __slen); + } + + template <typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + long double __v) const + { + const streamsize __max_prec = numeric_limits<long double>::digits10 + 3; + streamsize __prec = __io.precision(); + // Protect against sprintf() buffer overflows. + if (__prec > __max_prec) + __prec = __max_prec; + // The *2 provides for signs, exp, 'E', and pad. + char __sbuf[__max_prec*2]; + size_t __slen; + // Long enough for the max format spec. + char __fbuf[16]; + // 'L' as per [22.2.2.2.2] Table 59 + if ( _S_build_float_format(__io, __fbuf, 'L', __prec)) + __slen = sprintf(__sbuf, __fbuf, __prec, __v); + else + __slen = sprintf(__sbuf, __fbuf, __v); + // [22.2.2.2.2] Stages 2-4 + return _S_output_float(__s, __io, __fill, __sbuf, __slen); + } + + template <typename _CharT, typename _OutIter> + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + const void* __v) const + { + typedef ios_base::fmtflags fmtflags; + fmtflags __fmt = __io.flags(); + fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield + | ios_base::uppercase | ios_base::internal); + __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase)); + try { + _OutIter __s2 = _S_format(__s, __io, __fill, false, + reinterpret_cast<unsigned long>(__v)); + __io.flags(__fmt); + return __s2; + } + catch (...) { + __io.flags(__fmt); + throw; + } + } + + template<typename _CharT> + locale::id numpunct<_CharT>::id; + + template<typename _CharT> + locale::id collate<_CharT>::id; + + // Support for time_get: + // Note that these partial specializations could, and maybe should, + // be changed to full specializations (by eliminating the _Dummy + // argument) and moved to a .cc file. + template<typename _CharT, typename _Dummy = int> + struct _Weekdaynames; + + template<typename _Dummy> + struct _Weekdaynames<char, _Dummy> + { static const char* const _S_names[14]; }; + + template<typename _Dummy> + const char* const + _Weekdaynames<char, _Dummy>::_S_names[14] = + { + "Sun", "Sunday", + "Mon", "Monday", "Tue", "Tuesday", "Wed", "Wednesday", + "Thu", "Thursday", "Fri", "Friday", "Sat", "Saturday" + }; + +#ifdef _GLIBCPP_USE_WCHAR_T + template<typename _Dummy> + struct _Weekdaynames<wchar_t, _Dummy> + { static const wchar_t* const _S_names[14]; }; + + template<typename _Dummy> + const wchar_t* const + _Weekdaynames<wchar_t, _Dummy>::_S_names[14] = + { + L"Sun", L"Sunday", + L"Mon", L"Monday", L"Tue", L"Tuesday", L"Wed", L"Wednesday", + L"Thu", L"Thursday", L"Fri", L"Friday", L"Sat", L"Saturday" + }; +#endif + + template<typename _CharT, typename _Dummy = int> + struct _Monthnames; + + template<typename _Dummy> + struct _Monthnames<char,_Dummy> + { static const char* const _S_names[24]; }; + + template<typename _Dummy> + const char* const + _Monthnames<char,_Dummy>::_S_names[24] = + { + "Jan", "January", "Feb", "February", "Mar", "March", + "Apr", "April", "May", "May", "Jun", "June", + "Jul", "July", "Aug", "August", "Sep", "September", + "Oct", "October", "Nov", "November", "Dec", "December" + }; + +#ifdef _GLIBCPP_USE_WCHAR_T + template<typename _Dummy> + struct _Monthnames<wchar_t, _Dummy> + { static const wchar_t* const _S_names[24]; }; + + template<typename _Dummy> + const wchar_t* const + _Monthnames<wchar_t,_Dummy>::_S_names[24] = + { + L"Jan", L"January", L"Feb", L"February", L"Mar", L"March", + L"Apr", L"April", L"May", L"May", L"Jun", L"June", + L"Jul", L"July", L"Aug", L"August", L"Sep", L"September", + L"Oct", L"October", L"Nov", L"November", L"Dec", L"December" + }; +#endif + + template<typename _CharT, typename _InIter> + locale::id time_get<_CharT, _InIter>::id; + + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + do_get_weekday(iter_type __s, iter_type __end, + ios_base& __io, ios_base::iostate& __err, tm* __t) const + { + if (!_M_daynames) + { + _M_daynames = new basic_string<_CharT>[14]; + for (int __i = 0; __i < 14; ++__i) + _M_daynames[__i] = _Weekdaynames<_CharT>::_S_names[__i]; + } + bool __at_eof = false; + int __remain = 0; + int __matches[14]; + iter_type __out = __match_parallel(__s, __end, 14, _M_daynames, + __matches, __remain, __at_eof); + __err = ios_base::iostate(0); + if (__at_eof) __err |= __io.eofbit; + if (__remain == 1 || + __remain == 2 && (__matches[0]>>1) == (__matches[1]>>1)) + __t->tm_wday = (__matches[0]>>1); + else + __err |= __io.failbit; + return __out; + } + + template<typename _CharT, typename _InIter> + _InIter + time_get<_CharT, _InIter>:: + do_get_monthname(iter_type __s, iter_type __end, + ios_base& __io, ios_base::iostate& __err, tm* __t) const + { + if (!_M_monthnames) + { + _M_monthnames = new basic_string<_CharT>[24]; + for (int __i = 0; __i < 24; ++__i) + _M_monthnames[__i] = _Monthnames<_CharT>::_S_names[__i]; + } + bool __at_eof = false; + int __remain = 0; + int __matches[24]; + iter_type __out = __match_parallel( __s, __end, 24, _M_monthnames, + __matches, __remain, __at_eof); + __err = ios_base::iostate(0); + if (__at_eof) __err |= __io.eofbit; + if (__remain == 1 || + __remain == 2 && (__matches[0]>>1) == (__matches[1]>>1)) + __t->tm_mon = (__matches[0]>>1); + else + __err |= __io.failbit; + return __out; + } + + template<typename _CharT, typename _OutIter> + locale::id time_put<_CharT, _OutIter>::id; + + template<typename _CharT, typename _InIter> + locale::id money_get<_CharT, _InIter>::id; + + template<typename _CharT, typename _OutIter> + locale::id money_put<_CharT, _OutIter>::id; + + template<typename _CharT, bool _Intl> + locale::id moneypunct<_CharT, _Intl>::id; + + template<typename _CharT, bool _Intl> + const bool moneypunct<_CharT, _Intl>::intl; + + template<typename _CharT, bool _Intl> + const bool moneypunct_byname<_CharT, _Intl>::intl; + + template<typename _CharT> + locale::id messages<_CharT>::id; +} // std:: + +#endif /* _CPP_BITS_LOCFACETS_TCC */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/localefwd.h b/libstdc++-v3/include/bits/localefwd.h new file mode 100644 index 00000000000..44e85604bdb --- /dev/null +++ b/libstdc++-v3/include/bits/localefwd.h @@ -0,0 +1,508 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997-2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +#ifndef _CPP_BITS_LOCCORE_H +#define _CPP_BITS_LOCCORE_H 1 + +#include <bits/c++config.h> +#include <bits/std_climits.h> // For CHAR_BIT +#include <bits/std_string.h> // For string +#include <bits/std_cctype.h> // For isspace, etc. + +namespace std +{ + + // _Count_ones: compile-time computation of number of 1-bits in a value N + // This takes only 5 (or 6) instantiations, doing recursive descent + // in parallel -- ncm + template<unsigned int _Num, int _Shift = (sizeof(unsigned) * CHAR_BIT)/2, + unsigned int _Mask = (~0u >> _Shift) > + struct _Count_ones; + + template<unsigned int _Num, unsigned int _Mask> + struct _Count_ones<_Num, 0, _Mask> + { static const unsigned int _S_count = _Num; }; + + template<unsigned int _Num, unsigned int _Mask> + const unsigned int _Count_ones<_Num, 0, _Mask>::_S_count; + + template<unsigned int _Num, int _Shift, unsigned int _Mask> + struct _Count_ones + { + static const unsigned int _S_halfcount = + _Count_ones<_Num, _Shift/2, (_Mask^((~_Mask)>>(_Shift/2))) >::_S_count; + static const unsigned int _S_count + = (_S_halfcount&_Mask) + ((_S_halfcount>>_Shift)&_Mask); + }; + + template<unsigned int _Num, int _Shift, unsigned int _Mask> + const unsigned int _Count_ones<_Num, _Shift, _Mask>::_S_count; + + template<unsigned int _Num, int _Shift, unsigned int _Mask> + const unsigned int _Count_ones<_Num, _Shift, _Mask>::_S_halfcount; + + // 22.1.1 Locale + template<typename _Tp> class allocator; + template<typename _Tp, typename _Alloc> class vector; + class locale; + + // 22.1.3 Convenience interfaces + template<typename _CharT> + inline bool + isspace(_CharT, const locale&); + + template<typename _CharT> + inline bool + isprint(_CharT, const locale&); + + template<typename _CharT> + inline bool + iscntrl(_CharT, const locale&); + + template<typename _CharT> + inline bool + isupper(_CharT, const locale&); + + template<typename _CharT> + inline bool + islower(_CharT, const locale&); + + template<typename _CharT> + inline bool + isalpha(_CharT, const locale&); + + template<typename _CharT> + inline bool + isdigit(_CharT, const locale&); + + template<typename _CharT> + inline bool + ispunct(_CharT, const locale&); + + template<typename _CharT> + inline bool + isxdigit(_CharT, const locale&); + + template<typename _CharT> + inline bool + isalnum(_CharT, const locale&); + + template<typename _CharT> + inline bool + isgraph(_CharT, const locale&); + + template<typename _CharT> + inline _CharT + toupper(_CharT, const locale&); + + template<typename _CharT> + inline _CharT + tolower(_CharT, const locale&); + + + // 22.2.1 and 22.2.1.3 ctype + class ctype_base; + template<typename _CharT> + class ctype; + template<> class ctype<char>; +#ifdef _GLIBCPP_USE_WCHAR_T + template<> class ctype<wchar_t>; +#endif + + template<typename _CharT> + class ctype_byname; + // NB: Specialized for char and wchar_t in locfacets.h. + + class codecvt_base; + template<typename _InternT, typename _ExternT, typename _StateT> + class codecvt; + template<> class codecvt<char, char, mbstate_t>; +#ifdef _GLIBCPP_USE_WCHAR_T + template<> class codecvt<wchar_t, char, mbstate_t>; +#endif + + template<typename _InternT, typename _ExternT, typename _StateT> + class codecvt_byname; + template<> class codecvt_byname<char, char, mbstate_t>; +#ifdef _GLIBCPP_USE_WCHAR_T + template<> class codecvt_byname<wchar_t, char, mbstate_t>; +#endif + + // 22.2.2 and 22.2.3 numeric + template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > + class num_get; + template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > + class num_put; + template<typename _CharT> class numpunct; + template<typename _CharT> class numpunct_byname; + + // 22.2.4 collation + template<typename _CharT> + class collate; + template<> class collate<char>; +#ifdef _GLIBCPP_USE_WCHAR_T + template<> class collate<wchar_t>; +#endif + template<typename _CharT> class + collate_byname; + + // 22.2.5 date and time + class time_base; + template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > + class time_get; + template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > + class time_get_byname; + template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > + class time_put; + template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > + class time_put_byname; + + // 22.2.6 money + class money_base; + template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > + class money_get; + template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > + class money_put; + template<typename _CharT, bool _Intl = false> + class moneypunct; + template<typename _CharT, bool _Intl = false> + class moneypunct_byname; + + // 22.2.7 message retrieval + class messages_base; + template<typename _CharT> + class messages; + template<typename _CharT> + class messages_byname; + + + // 22.1.1 Class locale + class locale + { + public: + // Types: + typedef int category; + + // Forward decls and friends: + class facet; + class id; + class _Impl; + + friend class _Impl; + + template<typename _Facet> + friend const _Facet& + use_facet(const locale&); + + template<typename _Facet> + friend bool + has_facet(const locale&) throw(); + + // Category values: + // NB much depends on the order in which these appear: + static const category none = 0; + static const category collate = 0x0100; + static const category ctype = 0x0200; + static const category monetary = 0x0400; + static const category numeric = 0x0800; + static const category time = 0x1000; + static const category messages = 0x2000; + static const category all = (collate | ctype | monetary | + numeric | time | messages); + + // Construct/copy/destroy: + inline + locale() throw(); + + inline + locale(const locale& __other) throw(); + + explicit + locale(const char* __std_name); + + locale(const locale& __other, const char* __std_name, category __cat); + + locale(const locale& __other, const locale& __one, category __cat); + + template<typename _Facet> + locale(const locale& __other, _Facet* __f); + + inline + ~locale() throw(); + + const locale& + operator=(const locale& __other) throw(); + + template<typename _Facet> + locale + combine(const locale& __other); + + // Locale operations: + string + name() const; + + bool + operator==(const locale& __other) const throw (); + + inline bool + operator!=(const locale& __other) const throw () + { return !(operator==(__other)); } + + template<typename _Char, typename _Traits, typename _Alloc> + bool + operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, + const basic_string<_Char, _Traits, _Alloc>& __s2) const; + + // Global locale objects: + static locale + global(const locale&); + + static const locale& + classic(); + + private: + // The (shared) implementation + _Impl* _M_impl; + + // The "C" reference locale + static _Impl* _S_classic; + + // Current global reference locale + static _Impl* _S_global; + + static const int _S_categories_num = _Count_ones<all>::_S_count; + static const int _S_facets_num = 26; + + explicit + locale(_Impl*) throw(); + + static inline void + _S_initialize() + { if (!_S_classic) classic(); } + + static int + _S_normalize_category(int); + }; + + + // locale implementation object + class locale::_Impl + { + public: + // Types. + typedef vector<facet*, allocator<facet*> > __vec_facet; + typedef vector<string, allocator<string> > __vec_string; + + // Friends. + friend class locale; + friend class locale::facet; + + template<typename _Facet> + friend const _Facet& + use_facet(const locale&); + + template<typename _Facet> + friend bool + has_facet(const locale&) throw(); + + private: + // Data Members. + size_t _M_references; + __vec_facet* _M_facets; + __vec_string* _M_category_names; + bool _M_has_name; + string _M_name; + static const locale::id* const _S_id_collate[]; + static const locale::id* const _S_id_ctype[]; + static const locale::id* const _S_id_monetary[]; + static const locale::id* const _S_id_numeric[]; + static const locale::id* const _S_id_time[]; + static const locale::id* const _S_id_messages[]; + static const locale::id* const* const _S_facet_categories[]; + + inline void + _M_add_reference() throw() + { ++_M_references; } // XXX MT + + inline void + _M_remove_reference() throw() + { + if (_M_references-- == 0) // XXX MT + { + try { + delete this; + } + catch(...) { + } + } + } + + _Impl(const _Impl&, size_t __refs); + _Impl(const _Impl&, const string&, category, size_t __refs); + _Impl(size_t __facets, size_t __refs, bool __has_name, string __name); + ~_Impl() throw(); + + void + _M_replace_categories(const _Impl*, category); + + void + _M_replace_category(const _Impl*, const locale::id* const*); + + void + _M_replace_facet(const _Impl*, const locale::id*); + + void + _M_install_facet(const locale::id*, facet*); + + template<typename _Facet> + inline void + _M_facet_init(_Facet* __facet) + { _M_install_facet(&_Facet::id, __facet); } + + void + _M_construct_collate(const char*); + + void + _M_construct_ctype(const char*); + + void + _M_construct_monetary(const char*); + + void + _M_construct_numeric(const char*); + + void + _M_construct_time(const char*); + + void + _M_construct_messages(const char*); + + category + _M_normalize_category_names(const string&, category __cat); + }; + + // class locale inlines, that need declaration of locale::_Imp + locale::locale() throw() + { + _S_initialize(); + (_M_impl = _S_global)->_M_add_reference(); + } // XXX MT + + locale::locale(const locale& __other) throw() + { (_M_impl = __other._M_impl)->_M_add_reference(); } + + template<typename _Facet> + locale::locale(const locale& __other, _Facet* __f) + { + _M_impl = new _Impl(*__other._M_impl, 1); + _M_impl->_M_install_facet(&_Facet::id, __f); + _M_impl->_M_has_name = false; + _M_impl->_M_name = "*"; + } + + locale::~locale() throw() + { _M_impl->_M_remove_reference(); } + + // 22.1.1.1.2 Class locale::facet + class locale::facet + { + friend class locale; + friend class locale::_Impl; + + protected: + explicit + facet(size_t __refs = 0) throw(); + + virtual + ~facet() { }; + + private: + size_t _M_references; + + void + _M_add_reference() throw(); + + void + _M_remove_reference() throw(); + + facet(const facet&); // not defined + + void + operator=(const facet&); // not defined + }; + + + // 22.1.1.1.3 Class locale::id + class locale::id + { + friend class locale; + friend class locale::_Impl; + template<typename _Facet> + friend const _Facet& + use_facet(const locale&); + template<typename _Facet> + friend bool + has_facet(const locale&) throw (); + public: + id() {}; + private: + // NB: There is no accessor for _M_index because it may be used + // before the constructor is run; the effect of calling a member + // function (even an inline) would be undefined. + mutable size_t _M_index; + + // Last id number assigned + static size_t _S_highwater; + + void + operator=(const id&); // not defined + + id(const id&); // not defined + }; + + template<typename _Facet> + const _Facet& + use_facet(const locale& __loc); + + template<typename _Facet> + bool + has_facet(const locale& __loc) throw(); + +} // namespace std + +#endif /* _CPP_BITS_LOCCORE_H */ + +// Local Variables: +// mode:c++ +// End: + diff --git a/libstdc++-v3/include/bits/mask_array.h b/libstdc++-v3/include/bits/mask_array.h new file mode 100644 index 00000000000..5a15f7a5e97 --- /dev/null +++ b/libstdc++-v3/include/bits/mask_array.h @@ -0,0 +1,160 @@ +// The template and inlines for the -*- C++ -*- mask_array class. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _CPP_BITS_MASK_ARRAY_H +#define _CPP_BITS_MASK_ARRAY_H 1 + +namespace std { + + template <class _Tp> class mask_array + { + public: + typedef _Tp value_type; + + void operator= (const valarray<_Tp>&) const; + void operator*= (const valarray<_Tp>&) const; + void operator/= (const valarray<_Tp>&) const; + void operator%= (const valarray<_Tp>&) const; + void operator+= (const valarray<_Tp>&) const; + void operator-= (const valarray<_Tp>&) const; + void operator^= (const valarray<_Tp>&) const; + void operator&= (const valarray<_Tp>&) const; + void operator|= (const valarray<_Tp>&) const; + void operator<<=(const valarray<_Tp>&) const; + void operator>>=(const valarray<_Tp>&) const; + void operator= (const _Tp&); + + // ~mask_array (); + + template<class _Dom> + void operator= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator*= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator/= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator%= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator+= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator-= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator^= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator&= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator|= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator<<=(const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator>>=(const _Expr<_Dom,_Tp>&) const; + + private: + mask_array (_Array<_Tp>, size_t, _Array<bool>); + friend class valarray<_Tp>; + + const size_t _M_sz; + const _Array<bool> _M_mask; + const _Array<_Tp> _M_array; + + mask_array (const mask_array&); + + // not implemented + mask_array (); + mask_array& operator= (const mask_array&); + }; + + + template<typename _Tp> + inline mask_array<_Tp>::mask_array (const mask_array<_Tp>& a) + : _M_sz (a._M_sz), _M_mask (a._M_mask), _M_array (a._M_array) {} + + template<typename _Tp> + inline + mask_array<_Tp>::mask_array (_Array<_Tp> __a, size_t __s, _Array<bool> __m) + : _M_sz (__s), _M_mask (__m), _M_array (__a) {} + + // template<typename _Tp> + // inline mask_array<_Tp>::~mask_array () {} + + template<typename _Tp> + inline void + mask_array<_Tp>::operator= (const _Tp& __t) + { __valarray_fill (_M_array, _M_sz, _M_mask, __t); } + + template<typename _Tp> + inline void + mask_array<_Tp>::operator= (const valarray<_Tp>& __v) const + { __valarray_copy (_Array<_Tp> (__v), __v.size (), _M_array, _M_mask); } + + template<typename _Tp> + template<class E> + inline void + mask_array<_Tp>::operator= (const _Expr<E, _Tp>& __e) const + { __valarray_copy (__e, __e.size (), _M_array, _M_mask); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template<typename _Tp> \ +inline void \ +mask_array<_Tp>::operator op##= (const valarray<_Tp>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _M_mask, \ + _Array<_Tp> (__v), __v.size ()); \ +} \ + \ +template<typename _Tp> template<class E> \ +inline void \ +mask_array<_Tp>::operator op##= (const _Expr<E, _Tp>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _M_mask, __e, __e.size ()); \ +} + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _CPP_BITS_MASK_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc new file mode 100644 index 00000000000..7f76b0d0e80 --- /dev/null +++ b/libstdc++-v3/include/bits/ostream.tcc @@ -0,0 +1,683 @@ +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.2 Output streams +// + +#include <bits/std_locale.h> + +namespace std { + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>::sentry:: + sentry(basic_ostream<_CharT,_Traits>& __os) + : _M_ok(__os.good()), _M_os(__os) + { + // XXX MT + if (_M_ok && __os.tie()) + __os.tie()->flush(); + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__ostream_type& (*__pf)(__ostream_type&)) + { + sentry __cerb(*this); + if (__cerb) + { + try { + __pf(*this); + } + catch(exception& __fail){ + // 27.6.2.5.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__ios_type& (*__pf)(__ios_type&)) + { + sentry __cerb(*this); + if (__cerb) + { + try { + __pf(*this); + } + catch(exception& __fail){ + // 27.6.2.5.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(ios_base& (*__pf)(ios_base&)) + { + sentry __cerb(*this); + if (__cerb) + { + try { + __pf(*this); + } + catch(exception& __fail){ + // 27.6.2.5.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::operator<<(bool __n) + { + sentry __cerb(*this); + if (__cerb) + { + try { + if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) + this->setstate(ios_base::badbit); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::operator<<(long __n) + { + sentry __cerb(*this); + if (__cerb) + { + try { + bool __f; + ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt & ios_base::oct || __fmt & ios_base::hex) + __f = _M_fnumput->put(*this, *this, this->fill(), + static_cast<unsigned long>(__n)).failed(); + else + __f = _M_fnumput->put(*this, *this, this->fill(), __n).failed(); + + if (__f) + this->setstate(ios_base::badbit); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n) + { + sentry __cerb(*this); + if (__cerb) + { + try { + if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) + this->setstate(ios_base::badbit); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + +#ifdef _GLIBCPP_USE_LONG_LONG + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::operator<<(long long __n) + { + sentry __cerb(*this); + if (__cerb) + { + try { + bool __f; + ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt & ios_base::oct || __fmt & ios_base::hex) + __f = _M_fnumput->put(*this, *this, this->fill(), + static_cast<unsigned long long>(__n)).failed(); + else + __f = _M_fnumput->put(*this, *this, this->fill(), __n).failed(); + + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n) + { + sentry __cerb(*this); + if (__cerb) + { + try { + if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) + this->setstate(ios_base::badbit); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } +#endif + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::operator<<(double __n) + { + sentry __cerb(*this); + if (__cerb) + { + try { + if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) + this->setstate(ios_base::badbit); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::operator<<(long double __n) + { + sentry __cerb(*this); + if (__cerb) + { + try { + if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) + this->setstate(ios_base::badbit); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::operator<<(const void* __n) + { + sentry __cerb(*this); + if (__cerb) + { + try { + if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) + this->setstate(ios_base::badbit); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + this->setstate(ios_base::badbit); + if ((this->exceptions() & ios_base::badbit) != 0) + throw; + } + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type* __sbin) + { + streamsize __xtrct = 0; + __streambuf_type* __sbout = this->rdbuf(); + sentry __cerb(*this); + if (__sbin && __cerb) + __xtrct = _S_copy_streambufs(*this, __sbin, __sbout); + if (!__sbin || !__xtrct) + this->setstate(ios_base::failbit); + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::put(char_type __c) + { + sentry __cerb(*this); + if (__cerb) + { + int_type __put = rdbuf()->sputc(__c); + if (__put != traits_type::to_int_type(__c)) + this->setstate(ios_base::badbit); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::write(const _CharT* __s, streamsize __n) + { + sentry __cerb(*this); + if (__cerb) + { + streamsize __put = this->rdbuf()->sputn(__s, __n); + if ( __put != __n) + this->setstate(ios_base::badbit); + } + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::flush() + { + sentry __cerb(*this); + if (__cerb) + { + if (this->rdbuf() && this->rdbuf()->pubsync() == -1) + this->setstate(ios_base::badbit); + } + return *this; + } + + template<typename _CharT, typename _Traits> + typename basic_ostream<_CharT, _Traits>::pos_type + basic_ostream<_CharT, _Traits>::tellp() + { + pos_type __ret = pos_type(-1); + bool __testok = this->fail() != true; + + if (__testok) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); + return __ret; + } + + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>::seekp(pos_type __pos) + { + bool __testok = this->fail() != true; + + if (__testok) +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +// 136. seekp, seekg setting wrong streams? + this->rdbuf()->pubseekpos(__pos, ios_base::out); +#endif + return *this; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + seekp(off_type __off, ios_base::seekdir __d) + { + bool __testok = this->fail() != true; + + if (__testok) +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +// 136. seekp, seekg setting wrong streams? + rdbuf()->pubseekoff(__off, __d, ios_base::out); +#endif + return *this; + } + + // 27.6.2.5.4 Character inserters + + // Construct correctly padded string, as per 22.2.2.2.2 + // Similar in theory to _S_pad_numeric, from num_put, but it doesn't + // use _S_fill: perhaps it should. + // Assumes + // __newlen > __oldlen + // __news is allocated for __newlen size + template<typename _CharT, typename _Traits> + void + _S_pad_char(basic_ios<_CharT, _Traits>& __ios, + _CharT* __news, const _CharT* __olds, + const streamsize __newlen, const streamsize __oldlen) + { + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + + int_type __plen = static_cast<size_t>(__newlen - __oldlen); + char_type __pads[__plen]; + traits_type::assign(__pads, __plen, __ios.fill()); + + char_type* __beg; + char_type* __end; + size_t __mod = 0; + size_t __beglen; //either __plen or __oldlen + ios_base::fmtflags __fmt = __ios.flags() & ios_base::adjustfield; + + if (__fmt == ios_base::left) + { + // Padding last. + __beg = const_cast<char_type*>(__olds); + __beglen = __oldlen; + __end = __pads; + } + else if (__fmt == ios_base::internal) + { + // Pad after the sign, if there is one. + // Pad after 0[xX], if there is one. + // Who came up with these rules, anyway? Jeeze. + typedef _Format_cache<_CharT> __cache_type; + __cache_type const* __fmt = __cache_type::_S_get(__ios); + const char_type* __minus = traits_type::find(__olds, __oldlen, + __fmt->_S_minus); + const char_type* __plus = traits_type::find(__olds, __oldlen, + __fmt->_S_plus); + bool __testsign = __minus || __plus; + bool __testhex = __olds[0] == '0' + && (__olds[1] == 'x' || __olds[1] == 'X'); + + if (__testhex) + { + __news[0] = __olds[0]; + __news[1] = __olds[1]; + __mod += 2; + __beg = const_cast<char_type*>(__olds + __mod); + __beglen = __oldlen - __mod; + __end = __pads; + } + else if (__testsign) + { + __mod += __plen; + const char_type* __sign = __minus ? __minus + 1: __plus + 1; + __beg = const_cast<char_type*>(__olds); + __beglen = __sign - __olds; + __end = const_cast<char_type*>(__sign + __plen); + traits_type::copy(__news + __beglen, __pads, __plen); + } + else + { + // Padding first. + __beg = __pads; + __beglen = __plen; + __end = const_cast<char_type*>(__olds); + } + } + else + { + // Padding first. + __beg = __pads; + __beglen = __plen; + __end = const_cast<char_type*>(__olds); + } + + traits_type::copy(__news, __beg, __beglen); + traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod); + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try { + streamsize __w = __out.width(); + _CharT __pads[__w]; + __pads[0] = __c; + streamsize __len = 1; + if (__w > __len) + { + _S_pad_char(__out, __pads, &__c, __w, __len); + __len = __w; + } + __out.write(__pads, __len); + __out.width(0); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + __out.setstate(ios_base::badbit); + if ((__out.exceptions() & ios_base::badbit) != 0) + throw; + } + } + return __out; + } + + // Specialization + template <class _Traits> + basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, char __c) + { + typedef basic_ostream<char, _Traits> __ostream_type; + __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try { + streamsize __w = __out.width(); + char __pads[__w + 1]; + __pads[0] = __c; + streamsize __len = 1; + if (__w > __len) + { + _S_pad_char(__out, __pads, &__c, __w, __len); + __len = __w; + } + __out.write(__pads, __len); + __out.width(0); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + __out.setstate(ios_base::badbit); + if ((__out.exceptions() & ios_base::badbit) != 0) + throw; + } + } + return __out; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try { + streamsize __w = __out.width(); + _CharT __pads[__w]; + streamsize __len = static_cast<streamsize>(_Traits::length(__s)); + if (__w > __len) + { + _S_pad_char(__out, __pads, __s, __w, __len); + __s = __pads; + __len = __w; + } + __out.write(__s, __len); + __out.width(0); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + __out.setstate(ios_base::badbit); + if ((__out.exceptions() & ios_base::badbit) != 0) + throw; + } + } + return __out; + } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +// 167. Improper use of traits_type::length() + typedef char_traits<char> __ctraits_type; +#endif + __ostream_type::sentry __cerb(__out); + if (__cerb) + { + size_t __clen = __ctraits_type::length(__s); + _CharT __ws[__clen + 1]; + for (size_t __i = 0; __i <= __clen; ++__i) + __ws[__i] = __out.widen(__s[__i]); + _CharT* __str = __ws; + + try { + streamsize __len = static_cast<streamsize>(__clen); + streamsize __w = __out.width(); + _CharT __pads[__w]; + + if (__w > __len) + { + _S_pad_char(__out, __pads, __ws, __w, __len); + __str = __pads; + __len = __w; + } + __out.write(__str, __len); + __out.width(0); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + __out.setstate(ios_base::badbit); + if ((__out.exceptions() & ios_base::badbit) != 0) + throw; + } + } + return __out; + } + + // Partial specializationss + template<class _Traits> + basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, const char* __s) + { + typedef basic_ostream<char, _Traits> __ostream_type; + __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try { + streamsize __w = __out.width(); + char __pads[__w]; + streamsize __len = static_cast<streamsize>(_Traits::length(__s)); + if (__w > __len) + { + _S_pad_char(__out, __pads, __s, __w, __len); + __s = __pads; + __len = __w; + } + __out.write(__s, __len); + __out.width(0); + } + catch(exception& __fail){ + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + __out.setstate(ios_base::badbit); + if ((__out.exceptions() & ios_base::badbit) != 0) + throw; + } + } + return __out; + } + + // 21.3.7.8 basic_string::operator<< + template<typename _CharT, typename _Traits, typename _Alloc> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, + const basic_string<_CharT, _Traits, _Alloc>& __s) + { return (__out << __s.c_str()); } + +} // namespace std + +// Local Variables: +// mode:C++ +// End: + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/pthread_allocimpl.h b/libstdc++-v3/include/bits/pthread_allocimpl.h new file mode 100644 index 00000000000..3b63127ced7 --- /dev/null +++ b/libstdc++-v3/include/bits/pthread_allocimpl.h @@ -0,0 +1,495 @@ +/* + * 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 _CPP_BITS_PTHREAD_ALLOCIMPL_H +#define _CPP_BITS_PTHREAD_ALLOCIMPL_H 1 + +// 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 <bits/std_cerrno.h> +#include <bits/stl_config.h> +#include <bits/stl_alloc.h> +#ifndef __RESTRICT +# define __RESTRICT +#endif + +#ifndef __STL_NO_BAD_ALLOC +# include <bits/std_new.h> +#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<size_t _Max_size> +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 <size_t _Max_size = 128> +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 <size_t _Max_size> +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 <size_t _Max_size> +_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 <size_t _Max_size> +_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 <size_t _Max_size> +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 <size_t _Max_size> +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 <size_t _Max_size> +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 <size_t _Max_size> +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0; + +template <size_t _Max_size> +pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key; + +template <size_t _Max_size> +bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false; + +template <size_t _Max_size> +pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock += PTHREAD_MUTEX_INITIALIZER; + +template <size_t _Max_size> +char *_Pthread_alloc_template<_Max_size> +::_S_start_free = 0; + +template <size_t _Max_size> +char *_Pthread_alloc_template<_Max_size> +::_S_end_free = 0; + +template <size_t _Max_size> +size_t _Pthread_alloc_template<_Max_size> +::_S_heap_size = 0; + +#ifdef __STL_USE_STD_ALLOCATORS + +template <class _Tp> +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 <class _NewType> struct rebind { + typedef pthread_allocator<_NewType> other; + }; + + pthread_allocator() __STL_NOTHROW {} + pthread_allocator(const pthread_allocator& a) __STL_NOTHROW {} + template <class _OtherType> + 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<void> { +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template <class _NewType> struct rebind { + typedef pthread_allocator<_NewType> other; + }; +}; + +template <size_t _Max_size> +inline bool operator==(const _Pthread_alloc_template<_Max_size>&, + const _Pthread_alloc_template<_Max_size>&) +{ + return true; +} + +template <class _T1, class _T2> +inline bool operator==(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>& a2) +{ + return true; +} + +template <class _T1, class _T2> +inline bool operator!=(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>&) +{ + return false; +} + +template <class _Tp, size_t _Max_size> +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 <class _Tp, class _Atype, size_t _Max> +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 <class _Tp, class _Atype> +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 /* _CPP_BITS_PTHREAD_ALLOCIMPL_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/sbuf_iter.h b/libstdc++-v3/include/bits/sbuf_iter.h new file mode 100644 index 00000000000..7a0e1d5db22 --- /dev/null +++ b/libstdc++-v3/include/bits/sbuf_iter.h @@ -0,0 +1,264 @@ +// Streambuf iterators + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// XXX Should specialize copy, find algorithms for streambuf iterators. + +#ifndef _CPP_BITS_SBUF_ITER_H +#define _CPP_BITS_SBUF_ITER_H 1 + +namespace std +{ + + template<typename _CharT, typename _Traits> + class ostreambuf_iterator +#if 0 // XXX this is standard: + : public iterator<output_iterator_tag, _CharT, void, void, void> +#else + : public output_iterator +#endif + { + public: + + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + + inline + ostreambuf_iterator(ostream_type& __s) throw () + : _M_sbuf(__s.rdbuf()), _M_failed(false) { } + + ostreambuf_iterator(streambuf_type* __s) throw () + : _M_sbuf(__s), _M_failed(false) { } + + ostreambuf_iterator& + operator=(_CharT __c); + + ostreambuf_iterator& + operator*() throw() + { return *this; } + + ostreambuf_iterator& + operator++(int) throw() + { return *this; } + + ostreambuf_iterator& + operator++() throw() + { return *this; } + + bool + failed() const throw() + { return _M_failed; } + + private: + streambuf_type* _M_sbuf; + bool _M_failed; + +#if 0 + template<> + friend char const* + copy(char const* __first, char const* __last, + ostreambuf_iterator<char,char_traits<char> > __to); + template<> + friend wchar_t const* + copy(wchar_t const* __first, wchar_t const* __last, + ostreambuf_iterator<wchar_t,char_traits<wchar_t> > __to); +#endif + }; + + template<typename _CharT, typename _Traits> + inline ostreambuf_iterator<_CharT, _Traits>& + ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c) + { + if (!_M_failed && + _Traits::eq_int_type(_M_sbuf->sputc(__c),_Traits::eof())) + _M_failed = true; + return *this; + } + + +#if 0 + // Optimized specializations of standard algorithms + // These are specialized only for standard types + // (with no unbound arguments) to avoid creating + // overload problems with user specializations. + + template<> + char const* + copy(char const* __first, char const* __last, + ostreambuf_iterator<char,char_traits<char> > __to) + { + if (!__to._M_failed) + __to._M_sbuf->sputn(__first, __last-__first); + return __last; + } + + template<> + wchar_t const* + copy(wchar_t const* __first, wchar_t const* __last, + ostreambuf_iterator<whar_t,char_traits<wchar_t> > __to) + { + if (!__to._M_failed) + __to._M_sbuf->sputn(__first, __last-__first); + return __last; + } +#endif + + // 24.5.3 Template class istreambuf_iterator + template<class _CharT, class _Traits> + class istreambuf_iterator + : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, + _CharT*, _CharT&> + { + public: + + // Types: + 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; + // Non-standard Types: + typedef istreambuf_iterator<_CharT, _Traits> __istreambufiter_type; + + istreambuf_iterator() throw() + : _M_istreambuf(NULL), _M_c(-2) { } + + istreambuf_iterator(istream_type& __s) throw() + : _M_istreambuf(__s.rdbuf()), _M_c(-2) { } + + istreambuf_iterator(streambuf_type* __s) throw() + : _M_istreambuf(__s), _M_c(-2) { } + + // NB: This should really have an int_type return + // value, so "end of stream" postion can be checked without + // hacking. + char_type + operator*() const + { + // The result of operator*() on an end of stream is undefined. + char_type __ret; + if (_M_istreambuf && _M_c != static_cast<int_type>(-2)) + __ret = _M_c; + else if (_M_istreambuf) + __ret = traits_type::to_char_type(_M_istreambuf->sgetc()); + else + __ret = static_cast<char_type>(traits_type::eof()); + return __ret; + } + + __istreambufiter_type& + operator++() + { + if (_M_istreambuf) + _M_istreambuf->sbumpc(); + _M_c = -2; + return *this; + } + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // 14882 says return a proxy object. It should be a const + // proxy object, but since this class is not mandated, it + // should allow this signature: + const __istreambufiter_type + operator++(int) + { + if (_M_istreambuf) + _M_c = _M_istreambuf->sbumpc(); + return *this; + } +#endif + + bool + equal(const __istreambufiter_type& __b) + { + int_type __eof = traits_type::eof(); + bool __thiseof = !_M_istreambuf || _M_istreambuf->sgetc() == __eof; + bool __beof = !__b._M_istreambuf + || __b._M_istreambuf->sgetc() == __eof; + return (__thiseof && __beof || (!__thiseof && !__beof)); + } + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // 110 istreambuf_iterator::equal not const + // NB: there is also number 111 pending on this function. + bool + equal(const __istreambufiter_type& __b) const + { + int_type __eof = traits_type::eof(); + bool __thiseof = !_M_istreambuf || _M_istreambuf->sgetc() == __eof; + bool __beof = !__b._M_istreambuf + || __b._M_istreambuf->sgetc() == __eof; + return (__thiseof && __beof || (!__thiseof && !__beof)); + } +#endif + + private: + // 24.5.3 istreambuf_iterator + // p 1 + // If the end of stream is reached (streambuf_type::sgetc() + // returns traits_type::eof()), the iterator becomes equal to + // the "end of stream" iterator value. + // NB: This implementation assumes the "end of stream" value + // is EOF, or -1. + streambuf_type* _M_istreambuf; + int_type _M_c; + }; + + template<typename _CharT, typename _Traits> + inline bool + operator==(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return __a.equal(__b); } + + template<typename _CharT, typename _Traits> + inline bool + operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return !__a.equal(__b); } + +} // std:: + +#endif /* _CPP_BITS_SBUF_ITER_H */ + + + + + + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/sequence_concepts.h b/libstdc++-v3/include/bits/sequence_concepts.h new file mode 100644 index 00000000000..af582fb3345 --- /dev/null +++ b/libstdc++-v3/include/bits/sequence_concepts.h @@ -0,0 +1,204 @@ +/* + * 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 <bits/container_concepts.h> + +#ifdef __STL_USE_CONCEPT_CHECKS + +// This file covers the following concepts: +// _Sequence +// _FrontInsertionSequence +// _BackInsertionSequence + +struct _ERROR_IN_STL_SEQ { + + template <class _XX> + 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 <class _XX> + 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 <class _XX> + static void + __range_constructor_requirement_violation(_XX& __s) { + _XX __x(__s.begin(), __s.end()); + __sink_unused_warning(__x); + } + template <class _XX> + 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 <class _XX> + 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 <class _XX> + 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 <class _XX> + static void + __insert_element_function_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + std::pair<typename _XX::iterator, bool> __r; + __r = __s.insert(__t); + __sink_unused_warning(__r); + } + template <class _XX> + 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 <class _XX> + static void + __erase_function_requirement_violation(_XX& __s) { + typename _XX::iterator __p = typename _XX::iterator(); + __p = __s.erase(__p); + } + template <class _XX> + 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 <class _XX> + static void + __const_front_function_requirement_violation(const _XX& __s) { + typename _XX::const_reference __t = __s.front(); + __sink_unused_warning(__t); + } + template <class _XX> + 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 <class _XX> + static void + __const_back_function_requirement_violation(const _XX& __s) { + typename _XX::const_reference __t = __s.back(); + __sink_unused_warning(__t); + } + template <class _XX> + 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 <class _XX> + static void + __push_front_function_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + __s.push_front(__t); + } + template <class _XX> + static void + __pop_front_function_requirement_violation(_XX& __s) { + __s.pop_front(); + } + template <class _XX> + static void + __push_back_function_requirement_violation(_XX& __s) { + typename _XX::value_type __t = typename _XX::value_type(); + __s.push_back(__t); + } + template <class _XX> + static void + __pop_back_function_requirement_violation(_XX& __s) { + __s.pop_back(); + } + +}; + +/* Sequence Containers */ + +template <class _Sequence> +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 <class _FrontInsertionSequence> +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 <class _BackInsertionSequence> +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 */ diff --git a/libstdc++-v3/include/bits/slice.h b/libstdc++-v3/include/bits/slice.h new file mode 100644 index 00000000000..3e4f7a743f6 --- /dev/null +++ b/libstdc++-v3/include/bits/slice.h @@ -0,0 +1,77 @@ +// The template and inlines for the -*- C++ -*- slice class. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _CPP_BITS_SLICE_H +#define _CPP_BITS_SLICE_H + +namespace std { + +class slice +{ +public: + slice (); + slice (size_t, size_t, size_t); + + size_t start () const; + size_t size () const; + size_t stride () const; + +private: + size_t _M_off; // offset + size_t _M_sz; // size + size_t _M_st; // stride unit +}; + +inline slice::slice () {} + +inline slice::slice (size_t __o, size_t __d, size_t __s) + : _M_off (__o), _M_sz (__d), _M_st (__s) {} + +inline size_t +slice::start () const + { return _M_off; } + +inline size_t +slice::size () const + { return _M_sz; } + +inline size_t +slice::stride () const + { return _M_st; } + +} // std:: + + +#endif /* _CPP_BITS_SLICE_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/slice_array.h b/libstdc++-v3/include/bits/slice_array.h new file mode 100644 index 00000000000..4681cb590dc --- /dev/null +++ b/libstdc++-v3/include/bits/slice_array.h @@ -0,0 +1,161 @@ +// The template and inlines for the -*- C++ -*- slice_array class. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _CPP_BITS_SLICE_ARRAY_H +#define _CPP_BITS_SLICE_ARRAY_H 1 + +namespace std { + + template<typename _Tp> + class slice_array + { + public: + typedef _Tp value_type; + + void operator= (const valarray<_Tp>&) const; + void operator*= (const valarray<_Tp>&) const; + void operator/= (const valarray<_Tp>&) const; + void operator%= (const valarray<_Tp>&) const; + void operator+= (const valarray<_Tp>&) const; + void operator-= (const valarray<_Tp>&) const; + void operator^= (const valarray<_Tp>&) const; + void operator&= (const valarray<_Tp>&) const; + void operator|= (const valarray<_Tp>&) const; + void operator<<= (const valarray<_Tp>&) const; + void operator>>= (const valarray<_Tp>&) const; + void operator= (const _Tp &); + // ~slice_array (); + + template<class _Dom> + void operator= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator*= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator/= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator%= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator+= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator-= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator^= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator&= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator|= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator<<= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator>>= (const _Expr<_Dom,_Tp>&) const; + + private: + friend class valarray<_Tp>; + slice_array(_Array<_Tp>, const slice&); + + const size_t _M_sz; + const size_t _M_stride; + const _Array<_Tp> _M_array; + + // this constructor is implemented since we need to return a value. + slice_array (const slice_array&); + + // not implemented + slice_array (); + slice_array& operator= (const slice_array&); + }; + + template<typename _Tp> + inline slice_array<_Tp>::slice_array (_Array<_Tp> __a, const slice& __s) + : _M_sz (__s.size ()), _M_stride (__s.stride ()), + _M_array (__a.begin () + __s.start ()) {} + + + template<typename _Tp> + inline slice_array<_Tp>::slice_array(const slice_array<_Tp>& a) + : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {} + + // template<typename _Tp> + // inline slice_array<_Tp>::~slice_array () {} + + template<typename _Tp> + inline void + slice_array<_Tp>::operator= (const _Tp& __t) + { __valarray_fill (_M_array, _M_sz, _M_stride, __t); } + + template<typename _Tp> + inline void + slice_array<_Tp>::operator= (const valarray<_Tp>& __v) const + { __valarray_copy (_Array<_Tp> (__v), _M_array, _M_sz, _M_stride); } + + template<typename _Tp> + template<class _Dom> + inline void + slice_array<_Tp>::operator= (const _Expr<_Dom,_Tp>& __e) const + { __valarray_copy (__e, _M_sz, _M_array, _M_stride); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template<typename _Tp> \ +inline void \ +slice_array<_Tp>::operator op##= (const valarray<_Tp>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _M_sz, _M_stride, _Array<_Tp> (__v));\ +} \ + \ +template<typename _Tp> template<class _Dom> \ +inline void \ +slice_array<_Tp>::operator op##= (const _Expr<_Dom,_Tp>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _M_stride, __e, _M_sz); \ +} + + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _CPP_BITS_SLICE_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc new file mode 100644 index 00000000000..5c737b4fa2e --- /dev/null +++ b/libstdc++-v3/include/bits/sstream.tcc @@ -0,0 +1,220 @@ +// String based streams -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.7 String-based streams +// + +#ifndef _CPP_BITS_SSTREAM_TCC +#define _CPP_BITS_SSTREAM_TCC 1 + +#include <bits/std_sstream.h> + +namespace std { + + template <class _CharT, class _Traits, class _Alloc> + basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + pbackfail(int_type __c) + { + int_type __ret = traits_type::eof(); + bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); + bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; + + // Try to put back __c into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (__testpos) + { + if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]) + && !__testeof) + { + --_M_in_cur; + __ret = __c; + } + else if (!__testeof) + { + --_M_in_cur; + *_M_in_cur = traits_type::to_char_type(__c); + __ret = __c; + } + else if (__testeof) + { + --_M_in_cur; + __ret = traits_type::not_eof(__c); + } + } + return __ret; + } + + template <class _CharT, class _Traits, class _Alloc> + basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + overflow(int_type __c) + { + int_type __ret = traits_type::eof(); + bool __testeof = traits_type::eq_int_type(__c, __ret); + bool __testwrite = _M_out_cur < _M_buf + _M_buf_size; + bool __testout = _M_mode & ios_base::out; + + // Try to append __c into output sequence in one of two ways. + // Order these tests done in is unspecified by the standard. + if (__testout) + { + if (!__testeof) + { + __size_type __len = max(_M_buf_size, _M_buf_size_opt); + __len *= 2; + + if (__testwrite) + __ret = this->sputc(__c); + else if (__len <= _M_string.max_size()) + { + // Force-allocate, re-sync. + _M_string = this->str(); + _M_string.reserve(__len); + _M_buf_size = static_cast<int_type>(__len); + _M_really_sync(_M_in_cur - _M_in_beg, + _M_out_cur - _M_out_beg); + *_M_out_cur = traits_type::to_char_type(__c); + _M_out_cur_move(1); + __ret = __c; + } + } + else + __ret = traits_type::not_eof(__c); + } + return __ret; + } + + template <class _CharT, class _Traits, class _Alloc> + basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) + { + pos_type __ret = pos_type(off_type(-1)); + bool __testin = __mode & ios_base::in && _M_mode & ios_base::in; + bool __testout = __mode & ios_base::out && _M_mode & ios_base::out; + bool __testboth = __testin && __testout && __way != ios_base::cur; + + if (_M_buf_size && ((__testin != __testout) || __testboth)) + { + char_type* __beg = _M_buf; + char_type* __curi = NULL; + char_type* __curo = NULL; + char_type* __endi = NULL; + char_type* __endo = NULL; + + if (__testin) + { + __curi = this->gptr(); + __endi = this->egptr(); + } + if (__testout) + { + __curo = this->pptr(); + __endo = this->epptr(); + } + + off_type __newoffi = 0; + off_type __newoffo = 0; + if (__way == ios_base::cur) + { + __newoffi = __curi - __beg; + __newoffo = __curo - __beg; + } + else if (__way == ios_base::end) + { + __newoffi = __endi - __beg; + __newoffo = __endo - __beg; + } + + if (__testin + && __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off) + { + _M_in_cur = __beg + __newoffi + __off; + __ret = pos_type(__newoffi); + } + if (__testout + && __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off) + { + _M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg)); + __ret = pos_type(__newoffo); + } + } + return __ret; + } + + template <class _CharT, class _Traits, class _Alloc> + basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + seekpos(pos_type __sp, ios_base::openmode __mode) + { + pos_type __ret = pos_type(off_type(-1)); + off_type __pos = __sp._M_position(); + char_type* __beg = NULL; + char_type* __end = NULL; + bool __testin = __mode & ios_base::in && _M_mode & ios_base::in; + bool __testout = __mode & ios_base::out && _M_mode & ios_base::out; + + if (__testin) + { + __beg = this->eback(); + __end = this->egptr(); + } + if (__testout) + { + __beg = this->pbase(); + __end = _M_buf + _M_buf_size; + } + + if (0 <= __pos && __pos <= __end - __beg) + { + // Need to set both of these if applicable + if (__testin) + _M_in_cur = _M_in_beg + __pos; + if (__testout) + _M_out_cur_move((__pos) - (_M_out_cur - __beg)); + __ret = pos_type(off_type(__pos)); + } + + return __ret; + } + +} // namespace std + +#endif /* _CPP_BITS_SSTREAM_TCC */ + + + + + + + + + diff --git a/libstdc++-v3/include/bits/std_algorithm.h b/libstdc++-v3/include/bits/std_algorithm.h new file mode 100644 index 00000000000..3f084265506 --- /dev/null +++ b/libstdc++-v3/include/bits/std_algorithm.h @@ -0,0 +1,40 @@ +/* + * + * 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 _CPP_ALGORITHM +#define _CPP_ALGORITHM 1 + +#include <bits/stl_algobase.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_tempbuf.h> +#include <bits/stl_algo.h> + +#endif /* _CPP_ALGORITHM */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_bitset.h b/libstdc++-v3/include/bits/std_bitset.h new file mode 100644 index 00000000000..52f567854cb --- /dev/null +++ b/libstdc++-v3/include/bits/std_bitset.h @@ -0,0 +1,1076 @@ +/* + * 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 <bits/std_cstddef.h> // for size_t +#include <bits/std_cstring.h> // for memset +#include <bits/std_string.h> +#include <bits/std_stdexcept.h> // for invalid_argument, out_of_range, + // overflow_error + +#ifdef __STL_USE_NEW_IOSTREAMS +#include <iostream> +#else +#include <bits/std_iostream.h> // 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<bool __dummy> +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<bool __dummy> +struct _First_one { + static unsigned char _S_first_one[256]; +}; + +// +// Base class: general case. +// + +template<size_t _Nw> +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<true>::_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<size_t _Nw> +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<size_t _Nw> +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<size_t _Nw> +unsigned long _Base_bitset<_Nw>::_M_do_to_ulong() const +{ + for (size_t __i = 1; __i < _Nw; ++__i) + if (_M_w[__i]) + __STL_THROW(overflow_error("bitset")); + + return _M_w[0]; +} + +template<size_t _Nw> +size_t _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const +{ + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _WordT __thisword = _M_w[__i]; + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORD + __j*CHAR_BIT + + _First_one<true>::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + } + // not found, so return an indication of failure. + return __not_found; +} + +template<size_t _Nw> +size_t +_Base_bitset<_Nw>::_M_do_find_next(size_t __prev, size_t __not_found) const +{ + // make bound inclusive + ++__prev; + + // check out of bounds + if ( __prev >= _Nw * __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<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORD + __j*CHAR_BIT + + _First_one<true>::_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<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORD + __j*CHAR_BIT + + _First_one<true>::_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<true>::_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<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __j*CHAR_BIT + _First_one<true>::_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<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __j*CHAR_BIT + _First_one<true>::_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 <size_t _Extrabits> struct _Sanitize { + static void _M_do_sanitize(unsigned long& __val) + { __val &= ~((~static_cast<unsigned long>(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<size_t _Nb> +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<class _CharT, class _Traits, class _Alloc> + 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<class _CharT, class _Traits, class _Alloc> + 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<char>& __s, + size_t __pos = 0, + size_t __n = basic_string<char>::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 <class _CharT, class _Traits, class _Alloc> + 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<class _CharT, class _Traits, class _Alloc> + void _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t, + size_t); + + template<class _CharT, class _Traits, class _Alloc> + void _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const; +#else /* __STL_MEMBER_TEMPLATES */ + void _M_copy_from_string(const basic_string<char>&, size_t, size_t); + void _M_copy_to_string(basic_string<char>&) 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 <size_t _Nb> +template<class _CharT, class _Traits, class _Alloc> +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 <size_t _Nb> +template <class _CharT, class _Traits, class _Alloc> +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 <size_t _Nb> +void bitset<_Nb>::_M_copy_from_string(const basic_string<char>& __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 <size_t _Nb> +void bitset<_Nb>::_M_copy_to_string(basic_string<char>& __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 <size_t _Nb> +inline bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { + bitset<_Nb> __result(__x); + __result &= __y; + return __result; +} + + +template <size_t _Nb> +inline bitset<_Nb> operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { + bitset<_Nb> __result(__x); + __result |= __y; + return __result; +} + +template <size_t _Nb> +inline bitset<_Nb> operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) { + bitset<_Nb> __result(__x); + __result ^= __y; + return __result; +} + +#ifdef __STL_USE_NEW_IOSTREAMS + +template <class _CharT, class _Traits, size_t _Nb> +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) +{ + typedef typename _Traits::char_type char_type; + 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_type __c2 = _Traits::to_char_type(__c1); + char_type __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<size_t>(0), _Nb); + } + + return __is; +} + +template <class _CharT, class _Traits, size_t _Nb> +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 <size_t _Nb> +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<size_t>(0), _Nb); + + return __is; +} + +template <size_t _Nb> +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<bool __dummy> +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<bool __dummy> +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: + diff --git a/libstdc++-v3/include/bits/std_cassert.h b/libstdc++-v3/include/bits/std_cassert.h new file mode 100644 index 00000000000..5d9d18445f9 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cassert.h @@ -0,0 +1,39 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.2 Assertions +// + +// Note: This is not a conforming implementation. + +// No include guards on this header... + +# pragma GCC system_header +# include_next <assert.h> diff --git a/libstdc++-v3/include/bits/std_cctype.h b/libstdc++-v3/include/bits/std_cctype.h new file mode 100644 index 00000000000..1c1e69c6c5d --- /dev/null +++ b/libstdc++-v3/include/bits/std_cctype.h @@ -0,0 +1,211 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: <ccytpe> +// + +#ifndef _CPP_CCTYPE +#define _CPP_CCTYPE 1 + +// This keeps isanum, et al from being propagated as macros. +#if __linux__ +#define __NO_CTYPE 1 +#endif + +# pragma GCC system_header +# include_next <ctype.h> + +// Sequester the C non-inline implementations in the _C_Swamp:: +// namespace, and provide C++ inlines for them in the std:: namespace +// where they belong. + +namespace std +{ + // NB: If not using namespaces, can't have any of these definitions, + // as they will duplicate what's in the global namespace. + +#ifdef toupper + inline int + _S_toupper_helper(int __c) { return toupper(__c); } +# undef toupper + inline int + toupper(int __c) { return _S_toupper_helper(__c); } +#else + inline int + toupper(int __c) { return ::toupper(__c); } +#endif + +#ifdef tolower + inline int + _S_tolower_helper(int __c) { return tolower(__c); } +# undef tolower + inline int + tolower(int __c) { return _S_tolower_helper(__c); } +#else + inline int + tolower(int __c) { return ::tolower(__c); } +#endif + +#ifdef isspace + inline int + _S_isspace_helper(int __c) { return isspace(__c); } +# undef isspace + inline int + isspace(int __c) { return _S_isspace_helper(__c); } +#else + inline int + isspace(int __c) { return ::isspace(__c); } +#endif + +#ifdef isprint + inline int + _S_isprint_helper(int __c) { return isprint(__c); } +# undef isprint + inline int + isprint(int __c) { return _S_isprint_helper(__c); } +#else + inline int + isprint(int __c) { return ::isprint(__c); } +#endif + +#ifdef iscntrl + inline int + _S_iscntrl_helper(int __c) { return iscntrl(__c); } +# undef iscntrl + inline int + iscntrl(int __c) { return _S_iscntrl_helper(__c); } +#else + inline int + iscntrl(int __c) { return ::iscntrl(__c); } +#endif + +#ifdef isupper + inline int + _S_isupper_helper(int __c) { return isupper(__c); } +# undef isupper + inline int + isupper(int __c) { return _S_isupper_helper(__c); } +#else + inline int + isupper(int __c) { return ::isupper(__c); } +#endif + +#ifdef islower + inline int + _S_islower_helper(int __c) { return islower(__c); } +# undef islower + inline int + islower(int __c) { return _S_islower_helper(__c); } +#else + inline int + islower(int __c) { return ::islower(__c); } +#endif + +#ifdef isalpha + inline int + _S_isalpha_helper(int __c) { return isalpha(__c); } +# undef isalpha + inline int + isalpha(int __c) { return _S_isalpha_helper(__c); } +#else + inline int + isalpha(int __c) { return ::isalpha(__c); } +#endif + +#ifdef isdigit + inline int + _S_isdigit_helper(int __c) { return isdigit(__c); } +# undef isdigit + inline int + isdigit(int __c) { return _S_isdigit_helper(__c); } +#else + inline int + isdigit(int __c) { return ::isdigit(__c); } +#endif + +#ifdef ispunct + inline int + _S_ispunct_helper(int __c) { return ispunct(__c); } +# undef ispunct + inline int + ispunct(int __c) { return _S_ispunct_helper(__c); } +#else + inline int + ispunct(int __c) { return ::ispunct(__c); } +#endif + +#ifdef isxdigit + inline int + _S_isxdigit_helper(int __c) { return isxdigit(__c); } +# undef isxdigit + inline int + isxdigit(int __c) { return _S_isxdigit_helper(__c); } +#else + inline int + isxdigit(int __c) { return ::isxdigit(__c); } +#endif + +#ifdef isalnum + inline int + _S_isalnum_helper(int __c) { return isalnum(__c); } +# undef isalnum + inline int + isalnum(int __c) { return _S_isalnum_helper(__c); } +#else + inline int + isalnum(int __c) { return ::isalnum(__c); } +#endif + +#ifdef isgraph + inline int + _S_isgraph_helper(int __c) { return isgraph(__c); } +# undef isgraph + inline int + isgraph(int __c) { return _S_isgraph_helper(__c); } +#else + inline int + isgraph(int __c) { return ::isgraph(__c); } +#endif + +} // namespace std + +#endif // _CPP_CCTYPE + + + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/std_cerrno.h b/libstdc++-v3/include/bits/std_cerrno.h new file mode 100644 index 00000000000..abd28d560d8 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cerrno.h @@ -0,0 +1,40 @@ +// The -*- C++ -*- error number header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.3 Error numbers +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CERRNO +#define _CPP_CERRNO 1 +# pragma GCC system_header +# include_next <errno.h> +#endif diff --git a/libstdc++-v3/include/bits/std_cfloat.h b/libstdc++-v3/include/bits/std_cfloat.h new file mode 100644 index 00000000000..8a317fcb490 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cfloat.h @@ -0,0 +1,47 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CFLOAT +#define _CPP_CFLOAT 1 +# pragma GCC system_header +# include_next <float.h> + +#if 0 +# ifdef __GLIBC__ +// For GNU libc we must also include this one: +# include <fenv.h> +# endif +#endif +#endif diff --git a/libstdc++-v3/include/bits/std_climits.h b/libstdc++-v3/include/bits/std_climits.h new file mode 100644 index 00000000000..ddd6bd8b40f --- /dev/null +++ b/libstdc++-v3/include/bits/std_climits.h @@ -0,0 +1,42 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +// Note: This is not a conforming implementation. + +#ifndef _CPP_CLIMITS +#define _CPP_CLIMITS 1 +# pragma GCC system_header +# include_next <limits.h> +#endif + + diff --git a/libstdc++-v3/include/bits/std_clocale.h b/libstdc++-v3/include/bits/std_clocale.h new file mode 100644 index 00000000000..a8a44b8571a --- /dev/null +++ b/libstdc++-v3/include/bits/std_clocale.h @@ -0,0 +1,41 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CLOCALE +#define _CPP_CLOCALE 1 +# pragma GCC system_header +# include_next <locale.h> +#endif + diff --git a/libstdc++-v3/include/bits/std_cmath.h b/libstdc++-v3/include/bits/std_cmath.h new file mode 100644 index 00000000000..d7df14b2198 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cmath.h @@ -0,0 +1,506 @@ +// -*- C++ -*- C math library. + +// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 26.5 C library +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CMATH +#define _CPP_CMATH 1 +# pragma GCC system_header +# include_next <math.h> +# include_next <stdlib.h> + +# include <bits/c++config.h> + +namespace std { + + // + // int + // + + inline int abs(int i) + { return i > 0 ? i : -i; } + + inline long abs(long i) + { return i > 0 ? i : -i; } + + // + // float + // + +#if _GLIBCPP_HAVE___BUILTIN_FABSF + inline float abs(float __x) + { return __builtin_fabsf(__x); } +#elif _GLIBCPP_HAVE_FABSF + inline float abs(float __x) + { return ::fabsf(__x); } +#else + inline float abs(float __x) + { return ::fabs(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_ACOSF + inline float acos(float __x) + { return ::acosf(__x); } +#else + inline float acos(float __x) + { return ::acos(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_ASINF + inline float asin(float __x) + { return ::asinf(__x); } +#else + inline float asin(float __x) + { return ::asin(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_ATANF + inline float atan(float __x) + { return ::atanf(__x); } +#else + inline float atan(float __x) + { return ::atan(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_ATAN2F + inline float atan2(float __y, float __x) + { return ::atan2f(__y, __x); } +#else + inline float atan2(float __y, float __x) + { return ::atan2(static_cast<double>(__y), static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_CEILF + inline float ceil(float __x) + { return ::ceilf(__x); } +#else + inline float ceil(float __x) + { return ::ceil(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE___BUILTIN_COSF + inline float cos(float __x) + { return __builtin_cosf(__x); } +#elif _GLIBCPP_HAVE_COSF + inline float cos(float __x) + { return ::cosf(__x); } +#else + inline float cos(float __x) + { return ::cos(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_COSHF + inline float cosh(float __x) + { return ::coshf(__x); } +#else + inline float cosh(float __x) + { return ::cosh(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_EXPF + inline float exp(float __x) + { return ::expf(__x); } +#else + inline float exp(float __x) + { return ::exp(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE___BUILTIN_FABSF + inline float fabs(float __x) + { return __builtin_fabsf(__x); } +#elif _GLIBCPP_HAVE_FABSF + inline float fabs(float __x) + { return ::fabsf(__x); } +#else + inline float fabs(float __x) + { return ::fabs(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_FLOORF + inline float floor(float __x) + { return ::floorf(__x); } +#else + inline float floor(float __x) + { return ::floor(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_FMODF + inline float fmod(float __x, float __y) + { return ::fmodf(__x, __y); } +#else + inline float fmod(float __x, float __y) + { return ::fmod(static_cast<double>(__x), static_cast<double>(__y)); } +#endif + +#if _GLIBCPP_HAVE_FREXPF + inline float frexp(float __x, int* __exp) + { return ::frexpf(__x, __exp); } +#else + inline float frexp(float __x, int* __exp) + { return ::frexp(__x, __exp); } +#endif + +#if _GLIBCPP_HAVE_LDEXPF + inline float ldexp(float __x, int __exp) + { return ::ldexpf(__x, __exp); } +#else + inline float ldexp(float __x, int __exp) + { return ::ldexp(static_cast<double>(__x), __exp); } +#endif + +#if _GLIBCPP_HAVE_LOGF + inline float log(float __x) + { return ::logf(__x); } +#else + inline float log(float __x) + { return ::log(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_LOG10F + inline float log10(float __x) + { return ::log10f(__x); } +#else + inline float log10(float __x) + { return ::log10(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_MODFF + inline float modf(float __x, float* __iptr) + { return ::modff(__x, __iptr); } +#else + inline float modf(float __x, float* __iptr) + { + double __tmp; + double __res = ::modf(static_cast<double>(__x), &__tmp); + *__iptr = static_cast<float> (__tmp); + return __res; + } +#endif + +#if _GLIBCPP_HAVE_POWF + inline float pow(float __x, float __y) + { return ::powf(__x, __y); } +#else + inline float pow(float __x, float __y) + { return ::pow(static_cast<double>(__x), static_cast<double>(__y)); } +#endif + + float pow(float, int); + +#if _GLIBCPP_HAVE___BUILTIN_SINF + inline float sin(float __x) + { return __builtin_sinf(__x); } +#elif _GLIBCPP_HAVE_SINF + inline float sin(float __x) + { return ::sinf(__x); } +#else + inline float sin(float __x) + { return ::sin(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_SINHF + inline float sinh(float __x) + { return ::sinhf(__x); } +#else + inline float sinh(float __x) + { return ::sinh(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE___BUILTIN_SQRTF + inline float sqrt(float __x) + { return __builtin_sqrtf(__x); } +#elif _GLIBCPP_HAVE_SQRTF + inline float sqrt(float __x) + { return ::sqrtf(__x); } +#else + inline float sqrt(float __x) + { return ::sqrt(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_TANF + inline float tan(float __x) + { return ::tanf(__x); } +#else + inline float tan(float __x) + { return ::tan(static_cast<double>(__x)); } +#endif + +#if _GLIBCPP_HAVE_TANHF + inline float tanh(float __x) + { return ::tanhf(__x); } +#else + inline float tanh(float __x) + { return ::tanh(static_cast<double>(__x)); } +#endif + + // + // double + // + +#if _GLIBCPP_HAVE___BUILTIN_FABS + inline double abs(double __x) + { return __builtin_fabs(__x); } +#else + inline double abs(double __x) + { return ::fabs(__x); } +#endif + + inline double acos(double __x) + { return ::acos(__x); } + + inline double asin(double __x) + { return ::asin(__x); } + + inline double atan(double __x) + { return ::atan(__x); } + + inline double atan2(double __y, double __x) + { return ::atan2(__y, __x); } + + inline double ceil(double __x) + { return ::ceil(__x); } + +#if _GLIBCPP_HAVE___BUILTIN_COS + inline double cos(double __x) + { return __builtin_cos(__x); } +#else + inline double cos(double __x) + { return ::cos(__x); } +#endif + + inline double cosh(double __x) + { return ::cosh(__x); } + + inline double exp(double __x) + { return ::exp(__x); } + + +#if _GLIBCPP_HAVE___BUILTIN_FABS + inline double fabs(double __x) + { return __builtin_fabs(__x); } +#else + inline double fabs(double __x) + { return ::fabs(__x); } +#endif + + inline double floor(double __x) + { return ::floor(__x); } + + inline double fmod(double __x, double __y) + { return ::fmod(__x, __y); } + + inline double frexp(double __x, int* __exp) + { return ::frexp(__x, __exp); } + + inline double ldexp(double __x, int __exp) + { return ::ldexp(__x, __exp); } + + inline double log(double __x) + { return ::log(__x); } + + inline double log10(double __x) + { return ::log10(__x); } + + inline double modf(double __x, double* __iptr) + { return ::modf(__x, __iptr); } + + inline double pow(double __x, double __y) + { return ::pow(__x, __y); } + + double pow (double, int); + +#if _GLIBCPP_HAVE___BUILTIN_SIN + inline double sin(double __x) + { return __builtin_sin(__x); } +#else + inline double sin(double __x) + { return ::sin(__x); } +#endif + + inline double sinh(double __x) + { return ::sinh(__x); } + +#if _GLIBCPP_HAVE___BUILTIN_SQRT + inline double sqrt(double __x) + { return __builtin_fsqrt(__x); } +#else + inline double sqrt(double __x) + { return ::sqrt(__x); } +#endif + + inline double tan(double __x) + { return ::tan(__x); } + + inline double tanh(double __x) + { return ::tanh(__x); } + + // + // long double + // +#if _GLIBCPP_HAVE___BUILTIN_FABSL + inline long double abs(long double __x) + { return __builtin_fabsl(__x); } +#elif _GLIBCPP_HAVE_FABSL + inline long double abs(long double __x) + { return ::fabsl(__x); } +#endif + +#if _GLIBCPP_HAVE_ACOSL + inline long double acos(long double __x) + { return ::acosl(__x); } +#endif + +#if _GLIBCPP_HAVE_ASINL + inline long double asin(long double __x) + { return ::asinl(__x); } +#endif + +#if _GLIBCPP_HAVE_ATANL + inline long double atan(long double __x) + { return ::atanl(__x); } +#endif + +#if _GLIBCPP_HAVE_ATAN2L + inline long double atan2(long double __y, long double __x) + { return ::atan2l(__y, __x); } +#endif + +#if _GLIBCPP_HAVE_CEILL + inline long double ceil(long double __x) + { return ::ceill(__x); } +#endif + +#if _GLIBCPP_HAVE___BUILTIN_COSL + inline long double cos(long double __x) + { return __builtin_cosl(__x); } +#elif _GLIBCPP_HAVE_COSL + inline long double cos(long double __x) + { return ::cosl(__x); } +#endif + +#if _GLIBCPP_HAVE_COSHL + inline long double cosh(long double __x) + { return ::coshl(__x); } +#endif + +#if _GLIBCPP_HAVE_EXPL + inline long double exp(long double __x) + { return ::expl(__x); } +#endif + +#if _GLIBCPP_HAVE___BUILTIN_FABSL + inline long double fabs(long double __x) + { return __builtin_fabsl(__x); } +#elif _GLIBCPP_HAVE_FABSL + inline long double fabs(long double __x) + { return ::fabsl(__x); } +#endif + +#if _GLIBCPP_HAVE_FLOORL + inline long double floor(long double __x) + { return ::floorl(__x); } +#endif + +#if _GLIBCPP_HAVE_FMODL + inline long double fmod(long double __x, long double __y) + { return ::fmodl(__x, __y); } +#endif + +#if _GLIBCPP_HAVE_FREXPL + inline long double frexp(long double __x, int* __exp) + { return ::frexpl(__x, __exp); } +#endif + +#if _GLIBCPP_HAVE_LDEXPL + inline long double ldexp(long double __x, int __exp) + { return ::ldexpl(__x, __exp); } +#endif + +#if _GLIBCPP_HAVE_LOGL + inline long double log(long double __x) + { return ::logl(__x); } +#endif + +#if _GLIBCPP_HAVE_LOG10L + inline long double log10(long double __x) + { return ::log10l(__x); } +#endif + +#if _GLIBCPP_HAVE_MODFL + inline long double modf(long double __x, long double* __iptr) + { return ::modfl(__x, __iptr); } +#endif + +#if _GLIBCPP_HAVE_POWL + inline long double pow(long double __x, long double __y) + { return ::powl(__x, __y); } +#endif + + long double pow(long double, int); + +#if _GLIBCPP_HAVE___BUILTIN_SINL + inline long double sin(long double __x) + { return __builtin_sinl(__x); } +#elif _GLIBCPP_HAVE_SINL + inline long double sin(long double __x) + { return ::sinl(__x); } +#endif + +#if _GLIBCPP_HAVE_SINHL + inline long double sinh(long double __x) + { return ::sinhl(__x); } +#endif + +#if _GLIBCPP_HAVE___BUILTIN_SQRTL + inline long double sqrt(long double __x) + { return __builtin_sqrtl(__x); } +#elif _GLIBCPP_HAVE_SQRTL + inline long double sqrt(long double __x) + { return ::sqrtl(__x); } +#endif + +#if _GLIBCPP_HAVE_TANL + inline long double tan(long double __x) + { return ::tanl(__x); } +#endif + +#if _GLIBCPP_HAVE_TANHL + inline long double tanh(long double __x) + { return ::tanhl(__x); } +#endif + +} // std + +#endif // _CPP_CMATH + + diff --git a/libstdc++-v3/include/bits/std_complex.h b/libstdc++-v3/include/bits/std_complex.h new file mode 100644 index 00000000000..63f735181da --- /dev/null +++ b/libstdc++-v3/include/bits/std_complex.h @@ -0,0 +1,961 @@ +// The template and inlines for the -*- C++ -*- complex number classes. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO 14882/26.2.1 +// Note: this is not a conforming implementation. +// Initially implemented by Ulrich Drepper <drepper@cygnus.com> +// Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> +// + +#ifndef _CPP_COMPLEX +#define _CPP_COMPLEX 1 + +#include <bits/c++config.h> +#include <bits/std_iosfwd.h> + +namespace std +{ + + // Forward declarations + template<typename _Tp> class complex; + template<> class complex<float>; + template<> class complex<double>; + template<> class complex<long double>; + + template<typename _Tp> _Tp abs(const complex<_Tp>&); + template<typename _Tp> _Tp arg(const complex<_Tp>&); + + template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp&); + + // Transcendentals: + template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); + template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); + template<typename _Tp> complex<_Tp> pow (const complex<_Tp>&, + const complex<_Tp>&); + template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); + template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); + template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); + + + // + // 26.2.2 Primary template class complex + // + template <typename _Tp> + class complex + { + public: + typedef _Tp value_type; + + complex(const _Tp& = _Tp(), const _Tp & = _Tp()); + + // Let's the compiler synthetize the copy constructor + // complex (const complex<_Tp>&); + template <typename _Up> + complex(const complex<_Up>&); + + _Tp real() const; + _Tp imag() const; + + complex<_Tp>& operator=(const _Tp&); + complex<_Tp>& operator+=(const _Tp&); + complex<_Tp>& operator-=(const _Tp&); + complex<_Tp>& operator*=(const _Tp&); + complex<_Tp>& operator/=(const _Tp&); + + // Let's the compiler synthetize the + // copy and assignment operator + // complex<_Tp>& operator= (const complex<_Tp>&); + template <typename _Up> + complex<_Tp>& operator=(const complex<_Up>&); + template <typename _Up> + complex<_Tp>& operator+=(const complex<_Up>&); + template <typename _Up> + complex<_Tp>& operator-=(const complex<_Up>&); + template <typename _Up> + complex<_Tp>& operator*=(const complex<_Up>&); + template <typename _Up> + complex<_Tp>& operator/=(const complex<_Up>&); + + private: + _Tp _M_real, _M_imag; + }; + + template<typename _Tp> + inline _Tp + complex<_Tp>::real() const { return _M_real; } + + template<typename _Tp> + inline _Tp + complex<_Tp>::imag() const { return _M_imag; } + + + // + // 26.2.3 complex specializations + // + + // + // complex<float> specialization + // + template<> class complex<float> + { + public: + typedef float value_type; + + complex(float = 0.0f, float = 0.0f); +#ifdef _GLIBCPP_BUGGY_COMPLEX + complex(const complex& __z) : _M_value(__z._M_value) { } +#endif + explicit complex(const complex<double>&); + explicit complex(const complex<long double>&); + + float real() const; + float imag() const; + + complex<float>& operator=(float); + complex<float>& operator+=(float); + complex<float>& operator-=(float); + complex<float>& operator*=(float); + complex<float>& operator/=(float); + + // Let's the compiler synthetize the copy and assignment + // operator. It always does a pretty good job. + // complex& operator= (const complex&); + template <typename _Tp> + complex<float>&operator=(const complex<_Tp>&); + template <typename _Tp> + complex<float>& operator+=(const complex<_Tp>&); + template <class _Tp> + complex<float>& operator-=(const complex<_Tp>&); + template <class _Tp> + complex<float>& operator*=(const complex<_Tp>&); + template <class _Tp> + complex<float>&operator/=(const complex<_Tp>&); + + private: + typedef __complex__ float _ComplexT; + _ComplexT _M_value; + + complex(_ComplexT __z) : _M_value(__z) { } + + friend class complex<double>; + friend class complex<long double>; + + friend float abs<>(const complex<float>&); + friend float arg<>(const complex<float>&); + + friend complex<float> conj<>(const complex<float>&); + + friend complex<float> cos<>(const complex<float>&); + friend complex<float> cosh<>(const complex<float>&); + friend complex<float> exp<>(const complex<float>&); + friend complex<float> log<>(const complex<float>&); + friend complex<float> log10<>(const complex<float>&); + friend complex<float> pow<>(const complex<float>&, int); + friend complex<float> pow<>(const complex<float>&, const float&); + friend complex<float> pow<>(const complex<float>&, + const complex<float>&); + friend complex<float> pow<>(const float&, const complex<float>&); + friend complex<float> sin<>(const complex<float>&); + friend complex<float> sinh<>(const complex<float>&); + friend complex<float> sqrt<>(const complex<float>&); + friend complex<float> tan<>(const complex<float>&); + friend complex<float> tanh<>(const complex<float>&); + }; + + inline float + complex<float>::real() const + { return __real__ _M_value; } + + inline float + complex<float>::imag() const + { return __imag__ _M_value; } + + + // + // complex<double> specialization + // + template<> class complex<double> + { + public: + typedef double value_type; + + complex(double =0.0, double =0.0); +#ifdef _GLIBCPP_BUGGY_COMPLEX + complex(const complex& __z) : _M_value(__z._M_value) { } +#endif + complex(const complex<float>&); + explicit complex(const complex<long double>&); + + double real() const; + double imag() const; + + complex<double>& operator=(double); + complex<double>& operator+=(double); + complex<double>& operator-=(double); + complex<double>& operator*=(double); + complex<double>& operator/=(double); + + // The compiler will synthetize this, efficiently. + // complex& operator= (const complex&); + template <typename _Tp> + complex<double>& operator=(const complex<_Tp>&); + template <typename _Tp> + complex<double>& operator+=(const complex<_Tp>&); + template <typename _Tp> + complex<double>& operator-=(const complex<_Tp>&); + template <typename _Tp> + complex<double>& operator*=(const complex<_Tp>&); + template <typename _Tp> + complex<double>& operator/=(const complex<_Tp>&); + + private: + typedef __complex__ double _ComplexT; + _ComplexT _M_value; + + complex(_ComplexT __z) : _M_value(__z) { } + + friend class complex<float>; + friend class complex<long double>; + + friend double abs<>(const complex<double>&); + friend double arg<>(const complex<double>&); + + friend complex<double> conj<>(const complex<double>&); + friend complex<double> cos<>(const complex<double>&); + friend complex<double> cosh<>(const complex<double>&); + friend complex<double> exp<>(const complex<double>&); + friend complex<double> log<>(const complex<double>&); + friend complex<double> log10<>(const complex<double>&); + friend complex<double> pow<>(const complex<double>&, int); + friend complex<double> pow<>(const complex<double>&, const double&); + friend complex<double> pow<>(const complex<double>&, + const complex<double>&); + friend complex<double> pow<>(const double&, const complex<double>&); + friend complex<double> sin<>(const complex<double>&); + friend complex<double> sinh<>(const complex<double>&); + friend complex<double> sqrt<>(const complex<double>&); + friend complex<double> tan<>(const complex<double>&); + friend complex<double> tanh<>(const complex<double>&); + }; + + inline double + complex<double>::real() const + { return __real__ _M_value; } + + inline double + complex<double>::imag() const + { return __imag__ _M_value; } + + + // + // complex<long double> specialization + // + template<> class complex<long double> + { + public: + typedef long double value_type; + + complex(long double = 0.0L, long double = 0.0L); +#ifdef _GLIBCPP_BUGGY_COMPLEX + complex(const complex& __z) : _M_value(__z._M_value) { } +#endif + complex(const complex<float>&); + complex(const complex<double>&); + + long double real() const; + long double imag() const; + + complex<long double>& operator= (long double); + complex<long double>& operator+= (long double); + complex<long double>& operator-= (long double); + complex<long double>& operator*= (long double); + complex<long double>& operator/= (long double); + + // The compiler knows how to do this efficiently + // complex& operator= (const complex&); + + template<typename _Tp> + complex<long double>& operator=(const complex<_Tp>&); + template<typename _Tp> + complex<long double>& operator+=(const complex<_Tp>&); + template<typename _Tp> + complex<long double>& operator-=(const complex<_Tp>&); + template<typename _Tp> + complex<long double>& operator*=(const complex<_Tp>&); + template<typename _Tp> + complex<long double>& operator/=(const complex<_Tp>&); + + private: + typedef __complex__ long double _ComplexT; + _ComplexT _M_value; + + complex(_ComplexT __z) : _M_value(__z) { } + + friend class complex<float>; + friend class complex<double>; + + friend long double abs<>(const complex<long double>&); + friend long double arg<>(const complex<long double>&); + + friend complex<long double> conj<>(const complex<long double>&); + friend complex<long double> cos<>(const complex<long double>&); + friend complex<long double> cosh<>(const complex<long double>&); + friend complex<long double> exp<>(const complex<long double>&); + friend complex<long double> log<>(const complex<long double>&); + friend complex<long double> log10<>(const complex<long double>&); + friend complex<long double> pow<>(const complex<long double>&, int); + friend complex<long double> pow<>(const complex<long double>&, + const long double&); + friend complex<long double> pow<>(const complex<long double>&, + const complex<long double>&); + friend complex<long double> pow<>(const long double&, + const complex<long double>&); + friend complex<long double> sin<>(const complex<long double>&); + friend complex<long double> sinh<>(const complex<long double>&); + friend complex<long double> sqrt<>(const complex<long double>&); + friend complex<long double> tan<>(const complex<long double>&); + friend complex<long double> tanh<>(const complex<long double>&); + }; + + inline + complex<long double>::complex(long double __r, long double __i) + { + __real__ _M_value = __r; + __imag__ _M_value = __i; + } + + inline + complex<long double>::complex(const complex<float>& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex<long double>::complex(const complex<double>& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline long double + complex<long double>::real() const + { return __real__ _M_value; } + + inline long double + complex<long double>::imag() const + { return __imag__ _M_value; } + + inline complex<long double>& + complex<long double>::operator=(long double __r) + { + __real__ _M_value = __r; + __imag__ _M_value = 0.0L; + return *this; + } + + inline complex<long double>& + complex<long double>::operator+=(long double __r) + { + __real__ _M_value += __r; + return *this; + } + + inline complex<long double>& + complex<long double>::operator-=(long double __r) + { + __real__ _M_value -= __r; + return *this; + } + + inline complex<long double>& + complex<long double>::operator*=(long double __r) + { + __real__ _M_value *= __r; + return *this; + } + + inline complex<long double>& + complex<long double>::operator/=(long double __r) + { + __real__ _M_value /= __r; + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template<typename _Tp> + inline complex<long double>& + complex<long double>::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // + // complex<float> continued. + // + inline + complex<float>::complex(float r, float i) + { + __real__ _M_value = r; + __imag__ _M_value = i; + } + + inline + complex<float>::complex(const complex<double>& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex<float>::complex(const complex<long double>& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline complex<float>& + complex<float>::operator=(float __f) + { + __real__ _M_value = __f; + __imag__ _M_value = 0.0f; + return *this; + } + + inline complex<float>& + complex<float>::operator+=(float __f) + { + __real__ _M_value += __f; + return *this; + } + + inline complex<float>& + complex<float>::operator-=(float __f) + { + __real__ _M_value -= __f; + return *this; + } + + inline complex<float>& + complex<float>::operator*=(float __f) + { + _M_value *= __f; + return *this; + } + + inline complex<float>& + complex<float>::operator/=(float __f) + { + _M_value /= __f; + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.real(); + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template<typename _Tp> + inline complex<float>& + complex<float>::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + + // + // complex<double> continued. + // + inline + complex<double>::complex(double __r, double __i) + { + __real__ _M_value = __r; + __imag__ _M_value = __i; + } + + inline + complex<double>::complex(const complex<float>& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex<double>::complex(const complex<long double>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + } + + inline complex<double>& + complex<double>::operator=(double __d) + { + __real__ _M_value = __d; + __imag__ _M_value = 0.0; + return *this; + } + + inline complex<double>& + complex<double>::operator+=(double __d) + { + __real__ _M_value += __d; + return *this; + } + + inline complex<double>& + complex<double>::operator-=(double __d) + { + __real__ _M_value -= __d; + return *this; + } + + inline complex<double>& + complex<double>::operator*=(double __d) + { + _M_value *= __d; + return *this; + } + + inline complex<double>& + complex<double>::operator/=(double __d) + { + _M_value /= __d; + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template<typename _Tp> + inline complex<double>& + complex<double>::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // + // Primary template class complex continued. + // + // 26.2.4 + template<typename _Tp> + inline + complex<_Tp>::complex(const _Tp& __r, const _Tp& __i) + : _M_real(__r), _M_imag(__i) { } + + template<typename _Tp> + template<typename _Up> + inline + complex<_Tp>::complex(const complex<_Up>& __z) + : _M_real(__z.real()), _M_imag(__z.imag()) { } + + // 26.2.7/6 + template<typename _Tp> + inline complex<_Tp> + conj(const complex<_Tp>& __z) + { return complex<_Tp>(__z.real(), -__z.imag()); } + + // 26.2.7/4 + template<typename _Tp> + inline _Tp + norm(const complex<_Tp>& __z) + { + // XXX: Grammar school computation + return __z.real() * __z.real() + __z.imag() * __z.imag(); + } + + template<typename _Tp> + complex<_Tp>& + complex<_Tp>::operator=(const _Tp& __t) + { + _M_real = __t; + _M_imag = _Tp(); + return *this; + } + + // 26.2.5/1 + template<typename _Tp> + inline complex<_Tp>& + complex<_Tp>::operator+=(const _Tp& __t) + { + _M_real += __t; + return *this; + } + + // 26.2.5/3 + template<typename _Tp> + inline complex<_Tp>& + complex<_Tp>::operator-=(const _Tp& __t) + { + _M_real -= __t; + return *this; + } + + // 26.2.5/5 + template<typename _Tp> + complex<_Tp>& + complex<_Tp>::operator*=(const _Tp& __t) + { + _M_real *= __t; + _M_imag *= __t; + return *this; + } + + // 26.2.5/7 + template<typename _Tp> + complex<_Tp>& + complex<_Tp>::operator/=(const _Tp& __t) + { + _M_real /= __t; + _M_imag /= __t; + return *this; + } + + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator=(const complex<_Up>& __z) + { + _M_real = __z.real(); + _M_imag = __z.imag(); + return *this; + } + + // 26.2.5/9 + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator+=(const complex<_Up>& __z) + { + _M_real += __z.real(); + _M_imag += __z.imag(); + return *this; + } + + // 26.2.5/11 + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator-=(const complex<_Up>& __z) + { + _M_real -= __z.real(); + _M_imag -= __z.imag(); + return *this; + } + + // 26.2.5/13 + // XXX: this is a grammar school implementation. + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator*=(const complex<_Up>& __z) + { + _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); + _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); + _M_real = __r; + return *this; + } + + // 26.2.5/15 + // XXX: this is a grammar school implementation. + template<typename _Tp> + template<typename _Up> + complex<_Tp>& + complex<_Tp>::operator/=(const complex<_Up>& __z) + { + _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); + _Tp __n = norm(__z); + _M_imag = (_M_real * __z.imag() - _M_imag * __z.real()) / __n; + _M_real = __r / __n; + return *this; + } + + // Operators: + template<typename _Tp> + inline complex<_Tp> + operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return complex<_Tp> (__x) += __y; } + + template<typename _Tp> + inline complex<_Tp> + operator+(const complex<_Tp>& __x, const _Tp& __y) + { return complex<_Tp> (__x) += __y; } + + template<typename _Tp> + inline complex<_Tp> + operator+(const _Tp& __x, const complex<_Tp>& __y) + { return complex<_Tp> (__y) += __x; } + + template<typename _Tp> + inline complex<_Tp> + operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return complex<_Tp> (__x) -= __y; } + + template<typename _Tp> + inline complex<_Tp> + operator-(const complex<_Tp>& __x, const _Tp& __y) + { return complex<_Tp> (__x) -= __y; } + + template<typename _Tp> + inline complex<_Tp> + operator-(const _Tp& __x, const complex<_Tp>& __y) + { return complex<_Tp> (__x) -= __y; } + + template<typename _Tp> + inline complex<_Tp> + operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return complex<_Tp> (__x) *= __y; } + + template<typename _Tp> + inline complex<_Tp> + operator*(const complex<_Tp>& __x, const _Tp& __y) + { return complex<_Tp> (__x) *= __y; } + + template<typename _Tp> + inline complex<_Tp> + operator*(const _Tp& __x, const complex<_Tp>& __y) + { return complex<_Tp> (__y) *= __x; } + + template<typename _Tp> + inline complex<_Tp> + operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return complex<_Tp> (__x) /= __y; } + + template<typename _Tp> + inline complex<_Tp> + operator/(const complex<_Tp>& __x, const _Tp& __y) + { return complex<_Tp> (__x) /= __y; } + + template<typename _Tp> + inline complex<_Tp> + operator/(const _Tp& __x, const complex<_Tp>& __y) + { return complex<_Tp> (__x) /= __y; } + + template<typename _Tp> + inline complex<_Tp> + operator+(const complex<_Tp>& __x) + { return __x; } + + template<typename _Tp> + inline complex<_Tp> + operator-(const complex<_Tp>& __x) + { return complex<_Tp>(-__x.real(), -__x.imag()); } + + template<typename _Tp> + inline bool + operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __x.real() == __y.real() && __x.imag() == __y.imag(); } + + template<typename _Tp> + inline bool + operator==(const complex<_Tp>& __x, const _Tp& __y) + { return __x.real() == __y && __x.imag() == 0; } + + template<typename _Tp> + inline bool + operator==(const _Tp& __x, const complex<_Tp>& __y) + { return __x == __y.real() && 0 == __y.imag(); } + + template<typename _Tp> + inline bool + operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __x.real() != __y.real() || __x.imag() != __y.imag(); } + + template<typename _Tp> + inline bool + operator!=(const complex<_Tp>& __x, const _Tp& __y) + { return __x.real() != __y || __x.imag() != 0; } + + template<typename _Tp> + inline bool + operator!=(const _Tp& __x, const complex<_Tp>& __y) + { return __x != __y.real() || 0 != __y.imag(); } + + template<typename _Tp, typename _CharT, class _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>&, complex<_Tp>&); + + template<typename _Tp, typename _CharT, class _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>&, const complex<_Tp>&); + + + // Values: + template <typename _Tp> + inline _Tp + real(const complex<_Tp>& __z) + { return __z.real(); } + + template <typename _Tp> + inline _Tp + imag(const complex<_Tp>& __z) + { return __z.imag(); } + + + // We use here a few more specializations. + template<> + inline complex<float> + conj(const complex<float> &__x) +#ifdef _GLIBCPP_BUGGY_FLOAT_COMPLEX + { + complex<float> __tmpf(~__x._M_value); + return __tmpf; + } +#else + { return complex<float>(~__x._M_value); } +#endif + + template<> + inline complex<double> + conj(const complex<double> &__x) + { return complex<double> (~__x._M_value); } + + template<> + inline complex<long double> + conj(const complex<long double> &__x) + { return complex<long double> (~__x._M_value); } + +} // namespace std + +#endif /* _CPP_COMPLEX */ + + + + diff --git a/libstdc++-v3/include/bits/std_csetjmp.h b/libstdc++-v3/include/bits/std_csetjmp.h new file mode 100644 index 00000000000..fc5b339036a --- /dev/null +++ b/libstdc++-v3/include/bits/std_csetjmp.h @@ -0,0 +1,40 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CSETJMP +#define _CPP_CSETJMP 1 +# pragma GCC system_header +# include_next <setjmp.h> +#endif diff --git a/libstdc++-v3/include/bits/std_csignal.h b/libstdc++-v3/include/bits/std_csignal.h new file mode 100644 index 00000000000..34c03eb3df1 --- /dev/null +++ b/libstdc++-v3/include/bits/std_csignal.h @@ -0,0 +1,40 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CSIGNAL +#define _CPP_CSIGNAL 1 +# pragma GCC system_header +# include_next <signal.h> +#endif diff --git a/libstdc++-v3/include/bits/std_cstdarg.h b/libstdc++-v3/include/bits/std_cstdarg.h new file mode 100644 index 00000000000..f7f4235a290 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cstdarg.h @@ -0,0 +1,40 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CSTDARG +#define _CPP_CSTDARG 1 +# pragma GCC system_header +# include_next <stdarg.h> +#endif diff --git a/libstdc++-v3/include/bits/std_cstddef.h b/libstdc++-v3/include/bits/std_cstddef.h new file mode 100644 index 00000000000..5557c759571 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cstddef.h @@ -0,0 +1,40 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.1 Types +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CSTDDEF +#define _CPP_CSTDDEF 1 +# pragma GCC system_header +# include_next <stddef.h> +#endif diff --git a/libstdc++-v3/include/bits/std_cstdio.h b/libstdc++-v3/include/bits/std_cstdio.h new file mode 100644 index 00000000000..919a03ca4c7 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cstdio.h @@ -0,0 +1,61 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8.2 C Library files +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CSTDIO +#define _CPP_CSTDIO 1 +# pragma GCC system_header +# include_next <stdio.h> + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 4 +#endif + +#endif + + + + + + + + diff --git a/libstdc++-v3/include/bits/std_cstdlib.h b/libstdc++-v3/include/bits/std_cstdlib.h new file mode 100644 index 00000000000..ee5435739ad --- /dev/null +++ b/libstdc++-v3/include/bits/std_cstdlib.h @@ -0,0 +1,54 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CSTDLIB +#define _CPP_CSTDLIB 1 + +// This keeps isanum, et al from being propagated as macros. +#if __linux__ +#define __USE_ISOC9X 1 +#endif + +# pragma GCC system_header +# include_next <stdlib.h> + +#endif // _CPP_CSTDLIB + + + + + + + diff --git a/libstdc++-v3/include/bits/std_cstring.h b/libstdc++-v3/include/bits/std_cstring.h new file mode 100644 index 00000000000..06bcdda6535 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cstring.h @@ -0,0 +1,44 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CSTRING +#define _CPP_CSTRING 1 +# if defined __GLIBC__ && __GLIBC__ >= 2 +// We must not see the optimized string functions GNU libc defines. +# define __NO_STRING_INLINES +# endif +# pragma GCC system_header +# include_next <string.h> +#endif diff --git a/libstdc++-v3/include/bits/std_ctime.h b/libstdc++-v3/include/bits/std_ctime.h new file mode 100644 index 00000000000..b30b318f595 --- /dev/null +++ b/libstdc++-v3/include/bits/std_ctime.h @@ -0,0 +1,40 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.5 Date and time +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CTIME +#define _CPP_CTIME 1 +# pragma GCC system_header +# include_next <time.h> +#endif diff --git a/libstdc++-v3/include/bits/std_cwchar.h b/libstdc++-v3/include/bits/std_cwchar.h new file mode 100644 index 00000000000..77349f9d318 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cwchar.h @@ -0,0 +1,78 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: ??? +// + +// Note: this is not a conforming implementation. + +#ifndef _CPP_CWCHAR +#define _CPP_CWCHAR 1 + +#include <bits/c++config.h> + +#if _GLIBCPP_USE_WCHAR_T + # pragma GCC system_header + # include_next <wchar.h> +#else +# ifdef __cplusplus +extern "C" +{ +#endif + typedef struct + { + int __fill[6]; + } mbstate_t; +# ifdef __cplusplus +} +# endif +#endif //_GLIBCPP_USE_WCHAR_T + +#endif // _CPP_CWCHAR + + + + + + + + + + + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/std_cwctype.h b/libstdc++-v3/include/bits/std_cwctype.h new file mode 100644 index 00000000000..c67f2ba9720 --- /dev/null +++ b/libstdc++-v3/include/bits/std_cwctype.h @@ -0,0 +1,160 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: <cwctype> +// + +#ifndef _CPP_CWCTYPE +#define _CPP_CWCTYPE 1 + +# pragma GCC system_header +# include_next <wctype.h> + +// Sequester the C non-inline implementations in the _C_Swamp:: +// namespace, and provide C++ inlines for them in the std:: namespace +// where they belong. + +namespace std +{ + +#ifdef towupper + inline wint_t + _S_towupper_helper(wint_t __wc) { return towupper(__wc); } +# undef towupper + inline wint_t + towupper(wint_t __wc) { return _S_towupper_helper(__wc); } +#endif + +#ifdef towlower + inline wint_t + _S_towlower_helper(wint_t __wc) { return towlower(__wc); } +# undef towlower + inline wint_t + towlower(wint_t __wc) { return _S_towlower_helper(__wc); } +#endif + +#ifdef iswspace + inline int + _S_iswspace_helper(wint_t __wc) { return iswspace(__wc); } +# undef iswspace + inline int + iswspace(wint_t __wc) { return _S_iswspace_helper(__wc); } +#endif + +#ifdef iswprint + inline int + _S_iswprint_helper(wint_t __wc) { return iswprint(__wc); } +# undef iswprint + inline int + iswprint(wint_t __wc) { return _S_iswprint_helper(__wc); } +#endif + +#ifdef iswcntrl + inline int + _S_iswcntrl_helper(wint_t __wc) { return iswcntrl(__wc); } +# undef iswcntrl + inline int + iswcntrl(wint_t __wc) { return _S_iswcntrl_helper(__wc); } +#endif + +#ifdef iswupper + inline int + _S_iswupper_helper(wint_t __wc) { return iswupper(__wc); } +# undef iswupper + inline int + iswupper(wint_t __wc) { return _S_iswupper_helper(__wc); } +#endif + +#ifdef iswlower + inline int + _S_iswlower_helper(wint_t __wc) { return iswlower(__wc); } +# undef iswlower + inline int + iswlower(wint_t __wc) { return _S_iswlower_helper(__wc); } +#endif + +#ifdef iswalpha + inline int + _S_iswalpha_helper(wint_t __wc) { return iswalpha(__wc); } +# undef iswalpha + inline int + iswalpha(wint_t __wc) { return _S_iswalpha_helper(__wc); } +#endif + +#ifdef iswdigit + inline int + _S_iswdigit_helper(wint_t __wc) { return iswdigit(__wc); } +# undef iswdigit + inline int + iswdigit(wint_t __wc) { return _S_iswdigit_helper(__wc); } +#endif + +#ifdef iswpunct + inline int + _S_iswpunct_helper(wint_t __wc) { return iswpunct(__wc); } +# undef iswpunct + inline int + iswpunct(wint_t __wc) { return _S_iswpunct_helper(__wc); } +#endif + +#ifdef iswxdigit + inline int + _S_iswxdigit_helper (wint_t __wc) { return iswxdigit(__wc); } +# undef iswxdigit + inline int + iswxdigit(wint_t __wc) { return _S_iswxdigit_helper(__wc); } +#endif + +#ifdef iswalnum + inline int + _S_iswalnum_helper(wint_t __wc) { return iswalnum(__wc); } +# undef iswalnum + inline int + iswalnum(wint_t __wc) { return _S_iswalnum_helper(__wc); } +#endif + +#ifdef iswgraph + inline int + _S_iswgraph_helper(wint_t __wc) { return iswgraph(__wc); } +# undef iswgraph + inline int + iswgraph(wint_t __wc) { return _S_iswgraph_helper(__wc); } +#endif + +} // namespace std + +#endif // _CPP_CWCTYPE + + + + + + + diff --git a/libstdc++-v3/include/bits/std_deque.h b/libstdc++-v3/include/bits/std_deque.h new file mode 100644 index 00000000000..574ab313755 --- /dev/null +++ b/libstdc++-v3/include/bits/std_deque.h @@ -0,0 +1,41 @@ +/* + * + * 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 _CPP_DEQUE +#define _CPP_DEQUE 1 + +#include <bits/stl_range_errors.h> +#include <bits/stl_algobase.h> +#include <bits/stl_alloc.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_deque.h> + +#endif /* _CPP_DEQUE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_exception.h b/libstdc++-v3/include/bits/std_exception.h new file mode 100644 index 00000000000..0735601891f --- /dev/null +++ b/libstdc++-v3/include/bits/std_exception.h @@ -0,0 +1,81 @@ + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_EXCEPTION +#define _CPP_EXCEPTION 1 + +#ifdef __GNUG__ +#pragma GCC system_header +#include_next <exception> +#else + +#include <bits/stl_config.h> + +__STL_BEGIN_NAMESPACE + + // 18.6 Exception handling + class exception; + class bad_exception; + + typedef void (*unexpected_handler)(); + unexpected_handler set_unexpected(unexpected_handler) throw(); + void unexpected(); + typedef void (*terminate_handler)(); + terminate_handler set_terminate(terminate_handler) throw(); + void terminate(); + bool uncaught_exception(); + + // 18.6.1 Class exception + class exception { + public: + exception() throw(); + exception(const exception&) throw(); + exception& operator=(const exception&) throw(); + virtual ~exception() throw(); + virtual const char* what() const throw(); + }; + + // 18.6.2.1 Class bad_exception + class bad_exception : public exception { + public: + bad_exception() throw(); + bad_exception(const bad_exception&) throw(); + bad_exception& operator=(const bad_exception&) throw(); + virtual ~bad_exception() throw(); + virtual const char* what() const throw(); + }; + +__STL_END_NAMESPACE + +#endif /* __GNUG__ */ + +#endif /* _CPP_EXCEPTION */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_fstream.h b/libstdc++-v3/include/bits/std_fstream.h new file mode 100644 index 00000000000..4cafb2d9ee3 --- /dev/null +++ b/libstdc++-v3/include/bits/std_fstream.h @@ -0,0 +1,420 @@ +// File based streams -*- C++ -*- + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8 File-based streams +// + +#ifndef _CPP_FSTREAM +#define _CPP_FSTREAM 1 + +#include <bits/std_istream.h> +#include <bits/std_ostream.h> +#include <bits/basic_file.h> +#include <bits/std_locale.h> // For codecvt +#include <bits/c++threads.h> // For __mutext_type + +namespace std { + + template<typename _CharT, typename _Traits> + class basic_filebuf : public basic_streambuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard Types: + typedef basic_streambuf<char_type, traits_type> __streambuf_type; + typedef basic_filebuf<char_type, traits_type> __filebuf_type; + typedef __basic_file<char_type> __file_type; + typedef typename traits_type::state_type __state_type; + typedef codecvt<char_type, char, __state_type> __codecvt_type; + typedef typename __codecvt_type::result __res_type; + + friend class ios_base; // For sync_with_stdio. + + private: + // Data Members: + // External buffer. + __file_type* _M_file; + + // Current and beginning state type for codecvt. + __state_type _M_state_cur; + __state_type _M_state_beg; + + // Cached value from use_facet. + const __codecvt_type* _M_fcvt; + + // MT lock inherited from libio or other low-level io library. + __c_lock _M_lock; + + // XXX Needed? + bool _M_last_overflowed; + + public: + // Constructors/destructor: + basic_filebuf(); + + // Non-standard ctor: + basic_filebuf(int __fd, const char* __name, ios_base::openmode __mode); + + virtual + ~basic_filebuf() + { + this->close(); + _M_fcvt = NULL; + _M_last_overflowed = false; + } + + // Members: + bool + is_open(void) const { return _M_file ? _M_file->is_open() : false; } + + __filebuf_type* + open(const char* __s, ios_base::openmode __mode); + + __filebuf_type* + close(void); + + protected: + // Allocate up pback and internal buffers. + void + _M_allocate_buffers(); + + // Create __file_type object and initialize it properly. + void + _M_filebuf_init(); + + // Overridden virtual functions: + virtual streamsize + showmanyc(void); + + // Stroustrup, 1998, p. 628 + // underflow() and uflow() functions are called to get the next + // charater from the real input source when the buffer is empty. + // Buffered input uses underflow() + virtual int_type + underflow(void); + + virtual int_type + pbackfail(int_type __c = _Traits::eof()); + + // NB: For what the standard expects of the overflow function, + // see _M_really_overflow(), below. Because basic_streambuf's + // sputc/sputn call overflow directly, and the complications of + // this implementation's setting of the initial pointers all + // equal to _M_buf when initializing, it seems essential to have + // this in actuality be a helper function that checks for the + // eccentricities of this implementation, and then call + // overflow() if indeed the buffer is full. + virtual int_type + overflow(int_type __c = _Traits::eof()); + + // Stroustrup, 1998, p 648 + // The overflow() function is called to transfer characters to the + // real output destination when the buffer is full. A call to + // overflow(c) outputs the contents of the buffer plus the + // character c. + // 27.5.2.4.5 + // Consume some sequence of the characters in the pending sequence. + int_type + _M_really_overflow(int_type __c = _Traits::eof()); + + virtual __streambuf_type* + setbuf(char_type* __s, streamsize __n) + { + if (!this->is_open() && __s == 0 && __n == 0) + { + _M_buf_size = 0; + _M_buf_size_opt = 0; + } + _M_last_overflowed = false; + return this; + } + + virtual pos_type + seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + virtual pos_type + seekpos(pos_type __pos, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + virtual int + sync(void) + { + bool __testput = _M_out_cur && _M_out_beg < _M_out_end; + if (__testput) + { + // Make sure that libio resyncs its idea of the file position + // with the external file. + _M_file->sync(); + + // Need to restore current position. This interpreted as + // the position of the external byte sequence (_M_file) + // plus the offset in the current internal buffer + // (_M_out_beg - _M_out_cur) + streamoff __cur = _M_file->seekoff(0, ios_base::cur); + off_type __off = _M_out_cur - _M_out_beg; + _M_really_overflow(); + _M_file->seekpos(__cur + __off); + } + _M_last_overflowed = false; + return 0; + } + + virtual void + imbue(const locale& __loc); + + virtual streamsize + xsgetn(char_type* __s, streamsize __n) + { + streamsize __ret = 0; + // Clear out pback buffer before going on to the real deal... + if (_M_pback_init) + { + while (__ret < __n && _M_in_cur < _M_in_end) + { + *__s = *_M_in_cur; + ++__ret; + ++__s; + ++_M_in_cur; + } + _M_pback_destroy(); + } + if (__ret < __n) + __ret += __streambuf_type::xsgetn(__s, __n - __ret); + return __ret; + } + + virtual streamsize + xsputn(const char_type* __s, streamsize __n) + { + _M_pback_destroy(); + return __streambuf_type::xsputn(__s, __n); + } + + void + _M_output_unshift(); + }; + + + // 27.8.1.5 Template class basic_ifstream + template<typename _CharT, typename _Traits> + class basic_ifstream : public basic_istream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_filebuf<char_type, traits_type> __filebuf_type; + typedef basic_istream<char_type, traits_type> __istream_type; + + // Constructors/Destructors: + basic_ifstream() + : __istream_type(new __filebuf_type()) + { } + + explicit + basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) + : __istream_type(new __filebuf_type()) + { this->open(__s, __mode); } + + ~basic_ifstream() + { + delete _M_streambuf; + _M_streambuf = NULL; + } + + // Members: + __filebuf_type* + rdbuf() const + { return static_cast<__filebuf_type*>(_M_streambuf); } + + bool + is_open(void) { return rdbuf()->is_open(); } + + void + open(const char* __s, ios_base::openmode __mode = ios_base::in) + { + if (rdbuf()->open(__s, __mode | ios_base::in) == NULL) + this->setstate(ios_base::failbit); + } + + void + close(void) + { + if (!rdbuf()->close()) + this->setstate(ios_base::failbit); + } + }; + + + // 27.8.1.8 Template class basic_ofstream + template<typename _CharT, typename _Traits> + class basic_ofstream : public basic_ostream<_CharT,_Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_filebuf<char_type, traits_type> __filebuf_type; + typedef basic_ostream<char_type, traits_type> __ostream_type; + + // Constructors: + basic_ofstream() + : __ostream_type(new __filebuf_type()) + { } + + explicit + basic_ofstream(const char* __s, + ios_base::openmode __mode = ios_base::out|ios_base::trunc) + : __ostream_type(new __filebuf_type()) + { this->open(__s, __mode); } + + ~basic_ofstream() + { + delete _M_streambuf; + _M_streambuf = NULL; + } + + // Members: + __filebuf_type* + rdbuf(void) const + { return static_cast<__filebuf_type*>(_M_streambuf); } + + bool + is_open(void) { return rdbuf()->is_open(); } + + void + open(const char* __s, + ios_base::openmode __mode = ios_base::out | ios_base::trunc) + { + if (!rdbuf()->open(__s, __mode | ios_base::out)) + this->setstate(ios_base::failbit); + } + + void + close(void) + { + if (!rdbuf()->close()) + setstate(ios_base::failbit); + } + }; + + + // 27.8.1.11 Template class basic_fstream + template<typename _CharT, typename _Traits> + class basic_fstream : public basic_iostream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_filebuf<char_type, traits_type> __filebuf_type; + typedef basic_ios<char_type, traits_type> __ios_type; + typedef basic_iostream<char_type, traits_type> __iostream_type; + + // Constructors/destructor: + basic_fstream() + : __iostream_type(new __filebuf_type()) + { } + + explicit + basic_fstream(const char* __s, + ios_base::openmode __mode = ios_base::in | ios_base::out) + : __iostream_type(new __filebuf_type()) + { this->open(__s, __mode); } + + ~basic_fstream() + { + delete _M_streambuf; + _M_streambuf = NULL; + } + + // Members: + __filebuf_type* + rdbuf(void) const + { return static_cast<__filebuf_type*>(_M_streambuf); } + + bool + is_open(void) { return rdbuf()->is_open(); } + + void + open(const char* __s, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { + if (!rdbuf()->open(__s, __mode)) + setstate (ios_base::failbit); + } + + void + close(void) + { + if (!rdbuf()->close()) + setstate (ios_base::failbit); + } + }; + +} // namespace std + + +#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT +# define export +#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS +# include <bits/fstream.tcc> +#endif +#endif + +#endif /* _CPP_FSTREAM */ + + + + + + diff --git a/libstdc++-v3/include/bits/std_functional.h b/libstdc++-v3/include/bits/std_functional.h new file mode 100644 index 00000000000..0336c2aedab --- /dev/null +++ b/libstdc++-v3/include/bits/std_functional.h @@ -0,0 +1,27 @@ +/* + * 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 _CPP_FUNCTIONAL +#define _CPP_FUNCTIONAL + +#include <bits/stl_config.h> +#include <bits/std_cstddef.h> +#include <bits/stl_function.h> + +#endif /* _CPP_FUNCTIONAL */ + +// Local Variables: +// mode:C++ +// End: + diff --git a/libstdc++-v3/include/bits/std_iomanip.h b/libstdc++-v3/include/bits/std_iomanip.h new file mode 100644 index 00000000000..6fa49386b67 --- /dev/null +++ b/libstdc++-v3/include/bits/std_iomanip.h @@ -0,0 +1,219 @@ +// Standard stream manipulators -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.3 Standard manipulators +// + +#ifndef _CPP_IOMANIP +#define _CPP_IOMANIP 1 + +#include <bits/c++config.h> +#include <bits/std_istream.h> +#include <bits/std_functional.h> + +namespace std { + + struct _Resetiosflags { ios_base::fmtflags _M_mask; }; + + inline _Resetiosflags + resetiosflags(ios_base::fmtflags __mask) + { + _Resetiosflags __x; + __x._M_mask = __mask; + return __x; + } + + template <class _CharT, class _Traits> + basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Resetiosflags __f) + { + __is.setf(ios_base::fmtflags(0), __f._M_mask); + return __is; + } + + template <class _CharT, class _Traits> + basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Resetiosflags __f) + { + __os.setf(ios_base::fmtflags(0), __f._M_mask); + return __os; + } + + + struct _Setiosflags { ios_base::fmtflags _M_mask; }; + + inline _Setiosflags + setiosflags (ios_base::fmtflags __mask) + { + _Setiosflags __x; + __x._M_mask = __mask; + return __x; + } + + template <class _CharT, class _Traits> + basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setiosflags __f) + { + __is.setf(__f._M_mask); + return __is; + } + + template <class _CharT, class _Traits> + basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setiosflags __f) + { + __os.setf(__f._M_mask); + return __os; + } + + + struct _Setbase { int _M_base; }; + + inline _Setbase + setbase (int __base) + { + _Setbase __x; + __x._M_base = __base; + return __x; + } + + template <class _CharT, class _Traits> + basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setbase __f) + { + __is.setf(__f._M_base == 8 ? ios_base::oct : + __f._M_base == 10 ? ios_base::dec : + __f._M_base == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __is; + } + + template <class _CharT, class _Traits> + basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setbase __f) + { + __os.setf(__f._M_base == 8 ? ios_base::oct : + __f._M_base == 10 ? ios_base::dec : + __f._M_base == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __os; + } + + + template<class _CharT> + struct _Setfill { _CharT _M_c; }; + + template<class _CharT> + _Setfill<_CharT> + setfill(_CharT __c) + { + _Setfill<_CharT> __x; + __x._M_c = __c; + return __x; + } + + template <class _CharT, class _Traits> + basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setfill<_CharT> __f) + { + __is.fill(__f._M_c); + return __is; + } + + template <class _CharT, class _Traits> + basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setfill<_CharT> __f) + { + __os.fill(__f._M_c); + return __os; + } + + + struct _Setprecision { int _M_n; }; + + inline _Setprecision + setprecision(int __n) + { + _Setprecision __x; + __x._M_n = __n; + return __x; + } + + template <class _CharT, class _Traits> + basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setprecision __f) + { + __is.precision(__f._M_n); + return __is; + } + + template <class _CharT, class _Traits> + basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setprecision __f) + { + __os.precision(__f._M_n); + return __os; + } + + + struct _Setw { int _M_n; }; + + inline _Setw + setw(int __n) + { + _Setw __x; + __x._M_n = __n; + return __x; + } + + template <class _CharT, class _Traits> + basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setw __f) + { + __is.width(__f._M_n); + return __is; + } + + template <class _CharT, class _Traits> + basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setw __f) + { + __os.width(__f._M_n); + return __os; + } + +} // namespace std + +#endif /* __IOMANIP */ + + + + + diff --git a/libstdc++-v3/include/bits/std_ios.h b/libstdc++-v3/include/bits/std_ios.h new file mode 100644 index 00000000000..5c61547bff9 --- /dev/null +++ b/libstdc++-v3/include/bits/std_ios.h @@ -0,0 +1,52 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.4 Iostreams base classes +// + +#ifndef _CPP_IOS +#define _CPP_IOS 1 + +#include <bits/std_iosfwd.h> +#include <bits/std_exception.h> // For ios_base::failure +#include <bits/char_traits.h> // For char_traits, streamoff, streamsize, fpos +#include <bits/stl_string_fwd.h>// For string. +#include <bits/std_cstdio.h> // For SEEK_SET, SEEK_CUR, SEEK_END +#include <bits/localefwd.h> // For class locale +#include <bits/ios_base.h> // For ios_base declarations. +#include <bits/std_streambuf.h> +#include <bits/basic_ios.h> + +#endif /* _CPP_IOS */ + + + + + diff --git a/libstdc++-v3/include/bits/std_iosfwd.h b/libstdc++-v3/include/bits/std_iosfwd.h new file mode 100644 index 00000000000..8f198800a01 --- /dev/null +++ b/libstdc++-v3/include/bits/std_iosfwd.h @@ -0,0 +1,157 @@ +// Forwarding declarations -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.2 Forward declarations +// + +#ifndef _CPP_IOSFWD +#define _CPP_IOSFWD 1 + +#include <bits/c++config.h> +#include <bits/std_cwchar.h> // For mbstate_t + +namespace std { + + // Generic declarations. + template<typename _CharT> struct char_traits; + template<typename _Alloc> class allocator; + + // Forward declarations + template<> class char_traits<char>; +#ifdef _GLIBCPP_USE_WCHAR_T + template<> class char_traits<wchar_t>; +#endif + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_ios; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_streambuf; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_istream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_ostream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_iostream; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_stringbuf; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_istringstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_ostringstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_stringstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_filebuf; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_ifstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_ofstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class basic_fstream; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class istreambuf_iterator; + + template<typename _CharT, typename _Traits = char_traits<_CharT> > + class ostreambuf_iterator; + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // Not included. + class ios_base; +#endif + + template<class _State> struct fpos; +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // Can't have self-recursive types for streampos. + // 21.1.3.1 char_traits sets size_type to streampos + // 27.4.1 + // And here, where streampos is typedefed to fpos<traits::state_type> + typedef fpos<mbstate_t> streampos; +# ifdef _GLIBCPP_USE_WCHAR_T + typedef fpos<mbstate_t> wstreampos; +# endif +#endif + + typedef basic_ios<char> ios; + typedef basic_streambuf<char> streambuf; + typedef basic_istream<char> istream; + typedef basic_ostream<char> ostream; + typedef basic_iostream<char> iostream; + typedef basic_stringbuf<char> stringbuf; + typedef basic_istringstream<char> istringstream; + typedef basic_ostringstream<char> ostringstream; + typedef basic_stringstream<char> stringstream; + typedef basic_filebuf<char> filebuf; + typedef basic_ifstream<char> ifstream; + typedef basic_ofstream<char> ofstream; + typedef basic_fstream<char> fstream; + +#ifdef _GLIBCPP_USE_WCHAR_T + typedef basic_ios<wchar_t> wios; + typedef basic_streambuf<wchar_t> wstreambuf; + typedef basic_istream<wchar_t> wistream; + typedef basic_ostream<wchar_t> wostream; + typedef basic_iostream<wchar_t> wiostream; + typedef basic_stringbuf<wchar_t> wstringbuf; + typedef basic_istringstream<wchar_t> wistringstream; + typedef basic_ostringstream<wchar_t> wostringstream; + typedef basic_stringstream<wchar_t> wstringstream; + typedef basic_filebuf<wchar_t> wfilebuf; + typedef basic_ifstream<wchar_t> wifstream; + typedef basic_ofstream<wchar_t> wofstream; + typedef basic_fstream<wchar_t> wfstream; +#endif + +} // namespace std + +#endif // _CPP_IOSFWD + + + + + + + diff --git a/libstdc++-v3/include/bits/std_iostream.h b/libstdc++-v3/include/bits/std_iostream.h new file mode 100644 index 00000000000..b08d038046d --- /dev/null +++ b/libstdc++-v3/include/bits/std_iostream.h @@ -0,0 +1,58 @@ +// Standard iostream objects -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.3 Standard iostream objects +// + +#ifndef _CPP_IOSTREAM +#define _CPP_IOSTREAM 1 + +#include <bits/c++config.h> +#include <bits/std_ostream.h> +#include <bits/std_istream.h> + +namespace std { + + extern istream cin; + extern ostream cout; + extern ostream cerr; + extern ostream clog; +#ifdef _GLIBCPP_USE_WCHAR_T + extern wistream wcin; + extern wostream wcout; + extern wostream wcerr; + extern wostream wclog; +#endif + + // For construction of filebuffers for cout, cin, cerr, clog et. al. + static ios_base::Init __ioinit; +} // namespace std + +#endif /* _CPP_IOSTREAM */ diff --git a/libstdc++-v3/include/bits/std_istream.h b/libstdc++-v3/include/bits/std_istream.h new file mode 100644 index 00000000000..baddea47f8a --- /dev/null +++ b/libstdc++-v3/include/bits/std_istream.h @@ -0,0 +1,307 @@ +// Input streams -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +#ifndef _CPP_ISTREAM +#define _CPP_ISTREAM 1 + +#include <bits/std_ios.h> +#include <bits/std_limits.h> // For numeric_limits + +namespace std { + + // 27.6.1.1 Template class basic_istream + template<typename _CharT, typename _Traits> + class basic_istream : virtual public basic_ios<_CharT, _Traits> + { + public: + + // Types (inherited from basic_ios (27.4.4)): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + // Non-standard Types: + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_ios<_CharT, _Traits> __ios_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef istreambuf_iterator<_CharT> __istreambuf_iter; + typedef num_get<_CharT, __istreambuf_iter> __numget_type; + typedef ctype<_CharT> __ctype_type; + + protected: + // Data Members: + streamsize _M_gcount; + + public: + // 27.6.1.1.1 Constructor/destructor: + explicit + basic_istream(__streambuf_type* __sb) + { + this->init(__sb); + _M_gcount = streamsize(0); + } + + virtual + ~basic_istream() + { + _M_gcount = streamsize(0); + _M_fnumget = NULL; + } + + // 27.6.1.1.2 Prefix/suffix: + class sentry; + friend class sentry; + + // 27.6.1.2 Formatted input: + // 27.6.1.2.3 basic_istream::operator>> + __istream_type& + operator>>(__istream_type& (*__pf)(__istream_type&)); + + __istream_type& + operator>>(__ios_type& (*__pf)(__ios_type&)); + + __istream_type& + operator>>(ios_base& (*__pf)(ios_base&)); + + // 27.6.1.2.2 Arithmetic Extractors + __istream_type& + operator>>(bool& __n); + + __istream_type& + operator>>(short& __n); + + __istream_type& + operator>>(unsigned short& __n); + + __istream_type& + operator>>(int& __n); + + __istream_type& + operator>>(unsigned int& __n); + + __istream_type& + operator>>(long& __n); + + __istream_type& + operator>>(unsigned long& __n); + +#ifdef _GLIBCPP_USE_LONG_LONG + __istream_type& + operator>>(long long& __n); + + __istream_type& + operator>>(unsigned long long& __n); +#endif + + __istream_type& + operator>>(float& __f); + + __istream_type& + operator>>(double& __f); + + __istream_type& + operator>>(long double& __f); + + __istream_type& + operator>>(void*& __p); + + __istream_type& + operator>>(__streambuf_type* __sb); + + // 27.6.1.3 Unformatted input: + inline streamsize + gcount(void) const + { return _M_gcount; } + + int_type + get(void); + + __istream_type& + get(char_type& __c); + + __istream_type& + get(char_type* __s, streamsize __n, char_type __delim); + + inline __istream_type& + get(char_type* __s, streamsize __n) + { return get(__s, __n, this->widen('\n')); } + + __istream_type& + get(__streambuf_type& __sb, char_type __delim); + + inline __istream_type& + get(__streambuf_type& __sb) + { return get(__sb, this->widen('\n')); } + + __istream_type& + getline(char_type* __s, streamsize __n, char_type __delim); + + inline __istream_type& + getline(char_type* __s, streamsize __n) + { return getline(__s, __n, this->widen('\n')); } + + __istream_type& + ignore(streamsize __n = 1, int_type __delim = traits_type::eof()); + + int_type + peek(void); + + __istream_type& + read(char_type* __s, streamsize __n); + + streamsize + readsome(char_type* __s, streamsize __n); + + __istream_type& + putback(char_type __c); + + __istream_type& + unget(void); + + int + sync(void); + + pos_type + tellg(void); + + __istream_type& + seekg(pos_type); + + __istream_type& + seekg(off_type, ios_base::seekdir); + + private: +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // Not defined. + __istream_type& + operator=(const __istream_type&); + + basic_istream(const __istream_type&); +#endif + }; + + template<typename _CharT, typename _Traits> + class basic_istream<_CharT, _Traits>::sentry + { + public: + + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef __istream_type::__ctype_type __ctype_type; + typedef typename _Traits::int_type __int_type; + + explicit + sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false); + + operator bool() { return _M_ok; } + + private: + bool _M_ok; + }; + + // 27.6.1.2.3 Character extraction templates + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c); + + template<class _Traits> + basic_istream<char, _Traits>& + operator>>(basic_istream<char, _Traits>& __in, unsigned char& __c) + { return (__in >> static_cast<char>(__c)); } + + template<class _Traits> + basic_istream<char, _Traits>& + operator>>(basic_istream<char, _Traits>& __in, signed char& __c) + { return (__in >> static_cast<char>(__c)); } + + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s); + + template<class _Traits> + basic_istream<char,_Traits>& + operator>>(basic_istream<char,_Traits>& __in, unsigned char* __s) + { return (__in >> reinterpret_cast<char*>(__s)); } + + template<class _Traits> + basic_istream<char,_Traits>& + operator>>(basic_istream<char,_Traits>& __in, signed char* __s) + { return (__in >> reinterpret_cast<char*>(__s)); } + + // 27.6.1.5 Template class basic_iostream + template<typename _CharT, typename _Traits> + class basic_iostream + : public basic_istream<_CharT, _Traits>, + public basic_ostream<_CharT, _Traits> + { + public: + + // Non-standard Types: + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_ostream<_CharT, _Traits> __ostream_type; + + explicit + basic_iostream(basic_streambuf<_CharT, _Traits>* __sb) + : __istream_type(__sb), __ostream_type(__sb) + { } + + virtual + ~basic_iostream() { } + }; + + // 27.6.1.4 Standard basic_istream manipulators + template<typename _CharT, typename _Traits> + basic_istream<_CharT, _Traits>& + ws(basic_istream<_CharT, _Traits>& __is); + +} // namespace std + +#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT +# define export +#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS +# include <bits/istream.tcc> +#endif +#endif + +#endif /* _CPP_ISTREAM */ + + + + + + + + diff --git a/libstdc++-v3/include/bits/std_iterator.h b/libstdc++-v3/include/bits/std_iterator.h new file mode 100644 index 00000000000..643cff99cb8 --- /dev/null +++ b/libstdc++-v3/include/bits/std_iterator.h @@ -0,0 +1,46 @@ +/* + * + * 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 _CPP_ITERATOR +#define _CPP_ITERATOR 1 + +#include <bits/stl_config.h> +#include <bits/stl_relops.h> +#include <bits/std_cstddef.h> +#include <bits/std_iosfwd.h> +#include <bits/stl_iterator_base.h> +#include <bits/stl_iterator.h> + +#endif /* _CPP_ITERATOR */ + +// Local Variables: +// mode:C++ +// End: + + + + + diff --git a/libstdc++-v3/include/bits/std_list.h b/libstdc++-v3/include/bits/std_list.h new file mode 100644 index 00000000000..eaf1258cca6 --- /dev/null +++ b/libstdc++-v3/include/bits/std_list.h @@ -0,0 +1,40 @@ +/* + * + * 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 _CPP_LIST +#define _CPP_LIST 1 + +#include <bits/stl_algobase.h> +#include <bits/stl_alloc.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_list.h> + +#endif /* _CPP_LIST */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_locale.h b/libstdc++-v3/include/bits/std_locale.h new file mode 100644 index 00000000000..7eaba90e7ea --- /dev/null +++ b/libstdc++-v3/include/bits/std_locale.h @@ -0,0 +1,46 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +#ifndef _CPP_LOCALE +#define _CPP_LOCALE 1 + +#include <bits/localefwd.h> +#include <bits/locale_facets.h> +#include <bits/locale_facets.tcc> +#include <bits/codecvt.h> + +#endif + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/std_map.h b/libstdc++-v3/include/bits/std_map.h new file mode 100644 index 00000000000..d7fe92d3ee0 --- /dev/null +++ b/libstdc++-v3/include/bits/std_map.h @@ -0,0 +1,40 @@ +/* + * + * 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 _CPP_MAP +#define _CPP_MAP 1 + +#ifndef _CPP_BITS_STL_TREE_H +#include <bits/stl_tree.h> +#endif +#include <bits/stl_map.h> +#include <bits/stl_multimap.h> + +#endif /* _CPP_MAP */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_memory.h b/libstdc++-v3/include/bits/std_memory.h new file mode 100644 index 00000000000..5ee126bd8e9 --- /dev/null +++ b/libstdc++-v3/include/bits/std_memory.h @@ -0,0 +1,128 @@ +/* + * 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 _CPP_MEMORY +#define _CPP_MEMORY 1 + +#include <bits/stl_algobase.h> +#include <bits/stl_alloc.h> +#include <bits/stl_construct.h> +#include <bits/stl_iterator_base.h> //for iterator_traits +#include <bits/stl_tempbuf.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_raw_storage_iter.h> + +__STL_BEGIN_NAMESPACE + +#if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \ + defined(__STL_MEMBER_TEMPLATES) + + template<class _Tp1> struct auto_ptr_ref { + _Tp1* _M_ptr; + auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} +}; + +#endif + +template <class _Tp> 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 <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW + : _M_ptr(__a.release()) {} +#endif /* __STL_MEMBER_TEMPLATES */ + + auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW { + reset(__a.release()); + return *this; + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class _Tp1> + auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW { + reset(__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 <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW + { return auto_ptr_ref<_Tp>(this->release()); } + template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW + { return auto_ptr<_Tp1>(this->release()); } + +#endif /* auto ptr conversions && member templates */ +}; + +__STL_END_NAMESPACE + +#endif /* _CPP_MEMORY */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_new.h b/libstdc++-v3/include/bits/std_new.h new file mode 100644 index 00000000000..2e019a9562d --- /dev/null +++ b/libstdc++-v3/include/bits/std_new.h @@ -0,0 +1,82 @@ + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_NEW +#define _CPP_NEW 1 + +#include <bits/c++config.h> + +#ifdef __GNUG__ +# pragma GCC system_header +# include_next <new> +#else + +#include <bits/std_exception.h> + + +// 18.4 Dynamic memory management + +__STL_BEGIN_NAMESPACE + + class bad_alloc; + struct nothrow_t {}; + extern const nothrow_t nothrow; + typedef void (*new_handler)(); + new_handler set_new_handler(new_handler) throw(); + + class bad_alloc : public exception { + public: + bad_alloc() throw(); + bad_alloc(const bad_alloc&) throw(); + bad_alloc& operator=(const bad_alloc&) throw(); + virtual ~bad_alloc() throw(); + virtual const char* what() const throw(); + }; + +__STL_END_NAMESPACE + + void* operator new(__STD::size_t) throw(__STD::bad_alloc); + void* operator new(__STD::size_t, const __STD::nothrow_t&) throw(); + void operator delete(void*) throw(); + void operator delete(void*, const __STD::nothrow_t&) throw(); + void* operator new[](__STD::size_t) throw(__STD::bad_alloc); + void* operator new[](__STD::size_t, const __STD::nothrow_t&) throw(); + void operator delete[](void*) throw(); + void operator delete[](void*, const __STD::nothrow_t&) throw(); + void* operator new (__STD::size_t, void*) throw(); + void* operator new[](__STD::size_t, void*) throw(); + void operator delete (void*, void*) throw(); + void operator delete[](void*, void*) throw(); + +#endif + +#endif /* _CPP_NEW */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_numeric.h b/libstdc++-v3/include/bits/std_numeric.h new file mode 100644 index 00000000000..8b7c6fd9666 --- /dev/null +++ b/libstdc++-v3/include/bits/std_numeric.h @@ -0,0 +1,41 @@ +/* + * + * 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 _CPP_NUMERIC +#define _CPP_NUMERIC 1 + +#include <bits/stl_config.h> +#include <bits/stl_relops.h> +#include <bits/std_cstddef.h> +#include <bits/std_iterator.h> +#include <bits/stl_function.h> +#include <bits/stl_numeric.h> + +#endif /* _CPP_NUMERIC */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_ostream.h b/libstdc++-v3/include/bits/std_ostream.h new file mode 100644 index 00000000000..eb63e93623a --- /dev/null +++ b/libstdc++-v3/include/bits/std_ostream.h @@ -0,0 +1,288 @@ +// Output streams -*- C++ -*- + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.2 Output streams +// + +#ifndef _CPP_OSTREAM +#define _CPP_OSTREAM 1 + +#include <bits/std_ios.h> + +namespace std { + + // 27.6.2.1 Template class basic_ostream + template<typename _CharT, typename _Traits> + class basic_ostream : virtual public basic_ios<_CharT, _Traits> + { + public: + + // Types (inherited from basic_ios (27.4.4)): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + // Non-standard Types: + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_ios<_CharT, _Traits> __ios_type; + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef ostreambuf_iterator<_CharT> __ostreambuf_iter; + typedef num_put<_CharT, __ostreambuf_iter> __numput_type; + typedef ctype<_CharT> __ctype_type; + + // 27.6.2.2 Constructor/destructor: + explicit + basic_ostream(__streambuf_type* __sb) + { this->init(__sb); } + + virtual + ~basic_ostream() + { _M_fnumput = NULL; } + + // 27.6.2.3 Prefix/suffix: + class sentry; + friend class sentry; + + // 27.6.2.5 Formatted output: + // 27.6.2.5.3 basic_ostream::operator<< + __ostream_type& + operator<<(__ostream_type& (*__pf)(__ostream_type&)); + + __ostream_type& + operator<<(__ios_type& (*__pf)(__ios_type&)); + + __ostream_type& + operator<<(ios_base& (*__pf) (ios_base&)); + + // 27.6.2.5.2 Arithmetic Inserters + __ostream_type& + operator<<(long __n); + + __ostream_type& + operator<<(unsigned long __n); + + __ostream_type& + operator<<(bool __n); + + __ostream_type& + operator<<(short __n) + { + ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt & ios_base::oct || __fmt & ios_base::hex) + return this->operator<<(static_cast<unsigned long> + (static_cast<unsigned short>(__n))); + else + return this->operator<<(static_cast<long>(__n)); + } + + __ostream_type& + operator<<(unsigned short __n) + { return this->operator<<(static_cast<unsigned long>(__n)); } + + __ostream_type& + operator<<(int __n) + { + ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt & ios_base::oct || __fmt & ios_base::hex) + return this->operator<<(static_cast<unsigned long> + (static_cast<unsigned int>(__n))); + else + return this->operator<<(static_cast<long>(__n)); + } + + __ostream_type& + operator<<(unsigned int __n) + { return this->operator<<(static_cast<unsigned long>(__n)); } + +#ifdef _GLIBCPP_USE_LONG_LONG + __ostream_type& + operator<<(long long __n); + + __ostream_type& + operator<<(unsigned long long __n); +#endif + + __ostream_type& + operator<<(double __f); + + __ostream_type& + operator<<(float __f) + { return this->operator<<(static_cast<double>(__f)); } + + __ostream_type& + operator<<(long double __f); + + __ostream_type& + operator<<(const void* __p); + + __ostream_type& + operator<<(__streambuf_type* __sb); + + // Unformatted output: + __ostream_type& + put(char_type __c); + + __ostream_type& + write(const char_type* __s, streamsize __n); + + __ostream_type& + flush(); + + // Seeks: + pos_type + tellp(); + + __ostream_type& + seekp(pos_type); + + __ostream_type& + seekp(off_type, ios_base::seekdir); + + private: +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // Not defined. + __ostream_type& + operator=(const __ostream_type&); + + basic_ostream(const __ostream_type&); +#endif + }; + + // 27.6.2.3 Class basic_ostream::sentry + template <typename _CharT, typename _Traits> + class basic_ostream<_CharT, _Traits>::sentry + { + // Data Members: + bool _M_ok; + basic_ostream<_CharT,_Traits>& _M_os; + + public: + explicit + sentry(basic_ostream<_CharT,_Traits>& __os); + + ~sentry() + { + // XXX MT + if (_M_os.flags() & ios_base::unitbuf && !uncaught_exception()) + { + // Can't call flush directly or else will get into recursive lock. + if (_M_os.rdbuf() && _M_os.rdbuf()->pubsync() == -1) + _M_os.setstate(ios_base::badbit); + } + } + + operator bool() + { return _M_ok; } + }; + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c); + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) + { return (__out << __out.widen(__c)); } + + // Specialization + template <class _Traits> + basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, char __c); + + // Signed and unsigned + template<class _Traits> + basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, signed char __c) + { return (__out << static_cast<char>(__c)); } + + template<class _Traits> + basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c) + { return (__out << static_cast<char>(__c)); } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s); + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits> & + operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s); + + // Partial specializationss + template<class _Traits> + basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, const char* __s); + + // Signed and unsigned + template<class _Traits> + basic_ostream<char, _Traits>& + operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s) + { return (__out << reinterpret_cast<const char*>(__s)); } + + template<class _Traits> + basic_ostream<char, _Traits> & + operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s) + { return (__out << reinterpret_cast<const char*>(__s)); } + + // 27.6.2.7 Standard basic_ostream manipulators + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + endl(basic_ostream<_CharT, _Traits>& __os) + { return flush(__os.put(__os.widen('\n'))); } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + ends(basic_ostream<_CharT, _Traits>& __os) + { return __os.put(_Traits::_S_eos()); } + + template<typename _CharT, typename _Traits> + basic_ostream<_CharT, _Traits>& + flush(basic_ostream<_CharT, _Traits>& __os) + { return __os.flush(); } + +} // namespace std + +#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT +# define export +#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS +# include <bits/ostream.tcc> +#endif +#endif + +#endif /* _CPP_OSTREAM */ + + + + + + + diff --git a/libstdc++-v3/include/bits/std_queue.h b/libstdc++-v3/include/bits/std_queue.h new file mode 100644 index 00000000000..198b2c03508 --- /dev/null +++ b/libstdc++-v3/include/bits/std_queue.h @@ -0,0 +1,45 @@ +/* + * + * 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 _CPP_QUEUE +#define _CPP_QUEUE 1 + +#include <bits/stl_algobase.h> +#include <bits/stl_alloc.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_vector.h> +#include <ext/stl_bvector.h> +#include <bits/stl_heap.h> +#include <bits/stl_deque.h> +#include <bits/stl_function.h> +#include <bits/stl_queue.h> + +#endif /* _CPP_QUEUE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_set.h b/libstdc++-v3/include/bits/std_set.h new file mode 100644 index 00000000000..7a5f5c5b4ec --- /dev/null +++ b/libstdc++-v3/include/bits/std_set.h @@ -0,0 +1,40 @@ +/* + * + * 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 _CPP_SET +#define _CPP_SET 1 + +#ifndef _CPP_BITS_STL_TREE_H /* XXX is this guard needed? */ +#include <bits/stl_tree.h> +#endif +#include <bits/stl_set.h> +#include <bits/stl_multiset.h> + +#endif /* _CPP_SET */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_sstream.h b/libstdc++-v3/include/bits/std_sstream.h new file mode 100644 index 00000000000..f3207110d2d --- /dev/null +++ b/libstdc++-v3/include/bits/std_sstream.h @@ -0,0 +1,366 @@ +// String based streams -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.7 String-based streams +// + +#ifndef _CPP_SSTREAM +#define _CPP_SSTREAM 1 + +#include <bits/std_istream.h> +#include <bits/std_ostream.h> + +namespace std { + + template<typename _CharT, typename _Traits, typename _Alloc> + class basic_stringbuf : public basic_streambuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard Types: + typedef basic_streambuf<char_type, traits_type> __streambuf_type; + typedef basic_string<char_type, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + + private: + // Data Members: + __string_type _M_string; + + public: + // Constructors: + explicit + basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) + : __streambuf_type(), _M_string() + { _M_stringbuf_init(__mode); } + + explicit + basic_stringbuf(const __string_type& __str, + ios_base::openmode __mode = ios_base::in | ios_base::out) + : __streambuf_type(), _M_string(__str) + { _M_stringbuf_init(__mode); } + + // Get and set: + __string_type + str() const + { + if (_M_mode & ios_base::in && !(_M_mode & ios_base::out)) + return _M_string; + else + { + // This is the deal: _M_string.size() is value that + // represents the size of the intial string that makes + // _M_string, and may not be the correct size of the + // current stringbuf internal buffer. + __size_type __len = _M_string.size(); + if (_M_out_cur > _M_out_beg) + __len = max(__size_type(_M_out_end - _M_out_beg), __len); + return __string_type(_M_out_beg, _M_out_beg + __len); + } + } + + void + str(const __string_type& __s) + { + _M_string = __s; + _M_stringbuf_init(_M_mode); + } + + protected: + // Common initialization code for both ctors goes here. + void + _M_stringbuf_init(ios_base::openmode __mode) + { + // _M_buf_size is a convenient alias for "what the streambuf + // thinks the allocated size of the string really is." This is + // necessary as ostringstreams are implemented with the + // streambufs having control of the allocation and + // re-allocation of the internal string object, _M_string. + _M_buf_size = _M_string.size(); + + // NB: Start ostringstream buffers at 1024 bytes. This is an + // experimental value (pronounced "arbitrary" in some of the + // hipper english-speaking countries), and can be changed to + // suite particular needs. + _M_buf_size_opt = 512; + _M_mode = __mode; + if (_M_mode & ios_base::ate) + _M_really_sync(0, _M_buf_size); + else + _M_really_sync(0, 0); + } + + // Overridden virtual functions: + virtual int_type + underflow() + { + if (_M_in_cur && _M_in_cur < _M_in_end) + return traits_type::to_int_type(*gptr()); + else + return traits_type::eof(); + } + + virtual int_type + pbackfail(int_type __c = traits_type::eof()); + + virtual int_type + overflow(int_type __c = traits_type::eof()); + + virtual __streambuf_type* + setbuf(char_type* __s, streamsize __n) + { + if (__n) + { + _M_string = __string_type(__s, __n); + _M_really_sync(0, 0); + } + return this; + } + + virtual pos_type + seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + virtual pos_type + seekpos(pos_type __sp, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + // Internal function for correctly updating the internal buffer + // for a particular _M_string, due to initialization or + // re-sizing of an existing _M_string. + // Assumes: contents of _M_string and internal buffer match exactly. + // __i == _M_in_cur - _M_in_beg + // __o == _M_out_cur - _M_out_beg + virtual int + _M_really_sync(__size_type __i, __size_type __o) + { + char_type* __base = const_cast<char_type*>(_M_string.data()); + bool __testin = _M_mode & ios_base::in; + bool __testout = _M_mode & ios_base::out; + __size_type __len = _M_string.size(); + + _M_buf = __base; + if (__testin) + this->setg(__base, __base + __i, __base + __len); + if (__testout) + { + this->setp(__base, __base + __len); + _M_out_cur += __o; + } + return 0; + } + }; + + + // 27.7.2 Template class basic_istringstream + template<typename _CharT, typename _Traits, typename _Alloc> + class basic_istringstream : public basic_istream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; + typedef basic_istream<char_type, traits_type> __istream_type; + + // Constructors: + explicit + basic_istringstream(ios_base::openmode __mode = ios_base::in) + : __istream_type(new __stringbuf_type(__mode | ios_base::in)) + { } + + explicit + basic_istringstream(const __string_type& __str, + ios_base::openmode __mode = ios_base::in) + : __istream_type(new __stringbuf_type(__str, __mode | ios_base::in)) + { } + + ~basic_istringstream() + { + delete _M_streambuf; + _M_streambuf = NULL; + } + + // Members: + __stringbuf_type* + rdbuf() const + { return static_cast<__stringbuf_type*>(_M_streambuf); } + + __string_type + str() const + { return this->rdbuf()->str(); } + + void + str(const __string_type& __s) + { rdbuf()->str(__s); } + + }; + + + // 27.7.3 Template class basic_ostringstream + template <typename _CharT, typename _Traits, typename _Alloc> + class basic_ostringstream : public basic_ostream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; + typedef basic_ostream<char_type, traits_type> __ostream_type; + + // Constructors/destructor: + explicit + basic_ostringstream(ios_base::openmode __mode = ios_base::out) + : __ostream_type(new __stringbuf_type(__mode | ios_base::out)) + { } + + explicit + basic_ostringstream(const __string_type __str, + ios_base::openmode __mode = ios_base::out) + : __ostream_type(new __stringbuf_type(__str, __mode | ios_base::out)) + { } + + ~basic_ostringstream() + { + delete _M_streambuf; + _M_streambuf = NULL; + } + + // Members: + __stringbuf_type* + rdbuf() const + { return static_cast<__stringbuf_type*>(_M_streambuf); } + + __string_type + str() const + { return this->rdbuf()->str(); } + + void + str(const __string_type& __s) + { rdbuf()->str(__s); } + + }; + + + // 27.7.4 Template class basic_stringstream + template <typename _CharT, typename _Traits, typename _Alloc> + class basic_stringstream : public basic_iostream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard Types: + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; + typedef basic_iostream<char_type, traits_type> __iostream_type; + + // Constructors/destructors + explicit + basic_stringstream(ios_base::openmode __mode = + ios_base::out | ios_base::in) + : __iostream_type(new __stringbuf_type(__mode)) + { } + + explicit + basic_stringstream(const __string_type& __str, + ios_base::openmode __mode = + ios_base::out | ios_base::in) + : __iostream_type(new __stringbuf_type(__str, __mode)) + { } + + ~basic_stringstream() + { + delete _M_streambuf; + _M_streambuf = NULL; + } + + // Members: + __stringbuf_type* + rdbuf() const + { return static_cast<__stringbuf_type*>(_M_streambuf); } + + __string_type + str() const + { return rdbuf()->str(); } + + void + str(const __string_type& __s) + { rdbuf()->str(__s); } + }; + +} // namespace std + + + +#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT +# define export +#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS +# include <bits/sstream.tcc> +#endif +#endif + + +#endif /* _CPP_SSTREAM */ + + + + + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/std_stack.h b/libstdc++-v3/include/bits/std_stack.h new file mode 100644 index 00000000000..53e7e21f0ec --- /dev/null +++ b/libstdc++-v3/include/bits/std_stack.h @@ -0,0 +1,41 @@ +/* + * + * 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 _CPP_STACK +#define _CPP_STACK 1 + +#include <bits/stl_algobase.h> +#include <bits/stl_alloc.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_deque.h> +#include <bits/stl_stack.h> + +#endif /* _CPP_STACK */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_stdexcept.h b/libstdc++-v3/include/bits/std_stdexcept.h new file mode 100644 index 00000000000..691b9b5825e --- /dev/null +++ b/libstdc++-v3/include/bits/std_stdexcept.h @@ -0,0 +1,90 @@ +/* + * 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 _CPP_STDEXCEPT +#define _CPP_STDEXCEPT 1 + +#include <bits/std_exception.h> + +#if defined(__STL_USE_EXCEPTIONS) || \ + !(defined(_MIPS_SIM) && defined(_ABIO32) && _MIPS_SIM == _ABIO32) + +#include <bits/stl_string_fwd.h> + +__STL_BEGIN_NAMESPACE + +class __Named_exception : public exception { +public: + __Named_exception(const string& __str); + 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 + +#endif /* Not o32, and no exceptions */ + +#endif /* _CPP_STDEXCEPT */ + +// Local Variables: +// mode:C++ +// End: + diff --git a/libstdc++-v3/include/bits/std_streambuf.h b/libstdc++-v3/include/bits/std_streambuf.h new file mode 100644 index 00000000000..774046b6666 --- /dev/null +++ b/libstdc++-v3/include/bits/std_streambuf.h @@ -0,0 +1,528 @@ +// Stream buffer classes -*- C++ -*- + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.5 Stream buffers +// + +#ifndef _CPP_STREAMBUF +#define _CPP_STREAMBUF 1 + +#include <bits/c++config.h> +#include <bits/std_iosfwd.h> +#include <bits/std_cstdio.h> // For SEEK_SET, SEEK_CUR, SEEK_END +#include <bits/localefwd.h> +#include <bits/ios_base.h> + +namespace std { + + template<typename _CharT, typename _Traits> + static streamsize + _S_copy_streambufs(basic_ios<_CharT, _Traits>& __ios, + basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout); + + // 27.5.2 Template class basic_streambuf<_CharT, _Traits> + template<typename _CharT, typename _Traits> + class basic_streambuf + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard Types: + typedef ctype<char_type> __ctype_type; + typedef basic_streambuf<char_type, traits_type> __streambuf_type; + + friend class basic_ios<char_type, traits_type>; + friend class basic_istream<char_type, traits_type>; + friend class basic_ostream<char_type, traits_type>; + friend class istreambuf_iterator<char_type, traits_type>; + friend class ostreambuf_iterator<char_type, traits_type>; + + friend streamsize + _S_copy_streambufs<>(basic_ios<char_type, traits_type>& __ios, + __streambuf_type* __sbin,__streambuf_type* __sbout); + + protected: + + // Pointer to the beginning of internally-allocated + // space. Filebuf manually allocates/deallocates this, whereas + // stringstreams attempt to use the built-in intelligence of the + // string class. If you are managing memory, set this. If not, + // leave it NULL. + char_type* _M_buf; + + // Actual size of internal buffer, in bytes. + int_type _M_buf_size; + + // Optimal or preferred size of internal buffer, in bytes. + int_type _M_buf_size_opt; + + // True iff _M_in_* and _M_out_* buffers should always point to + // the same place. True for fstreams, false for sstreams. + bool _M_buf_unified; + + // This is based on _IO_FILE, just reordered to be more + // consistent, and is intended to be the most minimal abstraction + // for an internal buffer. + // get == input == read + // put == output == write + char_type* _M_in_beg; // Start of get area. + char_type* _M_in_cur; // Current read area. + char_type* _M_in_end; // End of get area. + char_type* _M_out_beg; // Start of put area. + char_type* _M_out_cur; // Current put area. + char_type* _M_out_end; // End of put area. + + // Place to stash in || out || in | out settings for current streambuf. + ios_base::openmode _M_mode; + + // Current locale setting. + locale _M_buf_locale; + + // True iff locale is initialized. + bool _M_buf_locale_init; + + // Cached use_facet<ctype>, which is based on the current locale info. + const __ctype_type* _M_buf_fctype; + + // Necessary bits for putback buffer management. Only used in + // the basic_filebuf class, as necessary for the standard + // requirements. The only basic_streambuf member function that + // needs access to these data members is in_avail... + // NB: pbacks of over one character are not currently supported. + int_type _M_pback_size; + char_type* _M_pback; + char_type* _M_pback_cur_save; + char_type* _M_pback_end_save; + bool _M_pback_init; + + // Initializes pback buffers, and moves normal buffers to safety. + // Assumptions: + // _M_in_cur has already been moved back + void + _M_pback_create() + { + if (!_M_pback_init) + { + int_type __dist = _M_in_end - _M_in_cur; + int_type __len = min(_M_pback_size, __dist); + traits_type::copy(_M_pback, _M_in_cur, __len); + _M_pback_cur_save = _M_in_cur; + _M_pback_end_save = _M_in_end; + this->setg(_M_pback, _M_pback, _M_pback + __len); + _M_pback_init = true; + } + } + + // Deactivates pback buffer contents, and restores normal buffer. + // Assumptions: + // The pback buffer has only moved forward. + void + _M_pback_destroy() + { + if (_M_pback_init) + { + // Length _M_in_cur moved in the pback buffer. + int_type __off_cur = _M_in_cur - _M_pback; + + // For in | out buffers, the end can be pushed back... + int_type __off_end = 0; + int_type __pback_len = _M_in_end - _M_pback; + int_type __save_len = _M_pback_end_save - _M_buf; + if (__pback_len > __save_len) + __off_end = __pback_len - __save_len; + + this->setg(_M_buf, _M_pback_cur_save + __off_cur, + _M_pback_end_save + __off_end); + _M_pback_cur_save = NULL; + _M_pback_end_save = NULL; + _M_pback_init = false; + } + } + + // Correctly sets the _M_out_cur pointer, and bumps the + // appropriate _M_*_end pointers as well. Necessary for the + // un-tied stringbufs, in in|out mode. + // Invariant: + // __n + _M_out_[cur, end] <= _M_buf + _M_buf_size + // Assuming all _M_*_[beg, cur, end] pointers are operating on + // the same range: + // _M_buf <= _M_*_ <= _M_buf + _M_buf_size + void + _M_out_cur_move(off_type __n) // argument needs to be +- + { + bool __testin = _M_mode & ios_base::in; + + _M_out_cur += __n; + if (__testin && _M_buf_unified) + _M_in_cur += __n; + if (_M_out_cur > _M_out_end) + { + _M_out_end = _M_out_cur; + // NB: in | out buffers drag the _M_in_end pointer along... + if (__testin) + _M_in_end += __n; + } + } + + // These three functions are used to clarify internal buffer + // maintenance. After an overflow, or after a seekoff call that + // started at beg or end, or possibly when the stream becomes + // unbuffered, and a myrid other obscure corner cases, the + // internal buffer does not truly reflect the contents of the + // external buffer. At this point, for whatever reason, it is in + // an indeterminate state. + void + _M_set_indeterminate(void) + { + if (_M_mode & ios_base::in) + this->setg(_M_buf, _M_buf, _M_buf); + if (_M_mode & ios_base::out) + this->setp(_M_buf, _M_buf); + } + + void + _M_set_determinate(off_type __off) + { + bool __testin = _M_mode & ios_base::in; + bool __testout = _M_mode & ios_base::out; + if (__testin) + { + this->setg(_M_buf, _M_buf, _M_buf + __off); + if (!__testout) + _M_buf_size = static_cast<int_type>(__off); + } + if (__testout) + this->setp(_M_buf, _M_buf + __off); + + } + + bool + _M_is_indeterminate(void) + { + bool __ret = false; + if (_M_mode & ios_base::in) + __ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end; + if (_M_mode & ios_base::out) + __ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end; + return __ret; + } + + public: + virtual + ~basic_streambuf() + { + _M_buf_unified = false; + _M_buf_size = 0; + _M_buf_size_opt = 0; + _M_mode = ios_base::openmode(0); + _M_buf_fctype = NULL; + _M_buf_locale_init = false; + + } + + // Locales: + locale + pubimbue(const locale &__loc) + { + locale __tmp(this->getloc()); + this->imbue(__loc); + return __tmp; + } + + locale + getloc() const + { + if (_M_buf_locale_init) + return _M_buf_locale; + else + return locale(); + } + + // Buffer and positioning: + __streambuf_type* + pubsetbuf(char_type* __s, streamsize __n) + { return this->setbuf(__s, __n); } + + pos_type + pubseekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { return this->seekoff(__off, __way, __mode); } + + pos_type + pubseekpos(pos_type __sp, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { return this->seekpos(__sp, __mode); } + + int + pubsync() { return this->sync(); } + + // Get and put areas: + // Get area: + streamsize + in_avail() + { + streamsize __ret; + if (_M_in_cur && _M_in_cur < _M_in_end) + { + if (_M_pback_init) + { + int_type __save_len = _M_pback_end_save - _M_pback_cur_save; + int_type __pback_len = _M_in_cur - _M_pback; + __ret = __save_len - __pback_len; + } + else + __ret = this->egptr() - this->gptr(); + } + else + __ret = this->showmanyc(); + return __ret; + } + + int_type + snextc() + { + int_type __eof = traits_type::eof(); + return (this->sbumpc() == __eof ? __eof : this->sgetc()); + } + + int_type + sbumpc(); + + int_type + sgetc() + { + int_type __ret; + if (_M_in_cur && _M_in_cur < _M_in_end) + __ret = traits_type::to_int_type(*gptr()); + else + __ret = this->underflow(); + return __ret; + } + + streamsize + sgetn(char_type* __s, streamsize __n) + { return this->xsgetn(__s, __n); } + + // Putback: + int_type + sputbackc(char_type __c); + + int_type + sungetc(); + + // Put area: + int_type + sputc(char_type __c); + + streamsize + sputn(const char_type* __s, streamsize __n) + { return this->xsputn(__s, __n); } + + protected: + basic_streambuf() + : _M_buf(NULL), _M_buf_size(0), + _M_buf_size_opt(static_cast<int_type>(BUFSIZ)), _M_buf_unified(false), + _M_in_beg(0), _M_in_cur(0), _M_in_end(0), _M_out_beg(0), _M_out_cur(0), + _M_out_end(0), _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), + _M_buf_locale_init(false), _M_pback_size(1), _M_pback(NULL), + _M_pback_cur_save(NULL), _M_pback_end_save(NULL), _M_pback_init(false) + { _M_buf_fctype = &use_facet<__ctype_type>(this->getloc()); } + + // Get area: + char_type* + eback() const { return _M_in_beg; } + + char_type* + gptr() const { return _M_in_cur; } + + char_type* + egptr() const { return _M_in_end; } + + void + gbump(int __n) { _M_in_cur += __n; } + + void + setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) + { + _M_in_beg = __gbeg; + _M_in_cur = __gnext; + _M_in_end = __gend; + if (!(_M_mode & ios_base::in) && __gbeg && __gnext && __gend) + _M_mode = _M_mode | ios_base::in; + } + + // Put area: + char_type* + pbase() const { return _M_out_beg; } + + char_type* + pptr() const { return _M_out_cur; } + + char_type* + epptr() const { return _M_out_end; } + + void + pbump(int __n) { _M_out_cur += __n; } + + void + setp(char_type* __pbeg, char_type* __pend) + { + _M_out_beg = _M_out_cur = __pbeg; + _M_out_end = __pend; + if (!(_M_mode & ios_base::out) && __pbeg && __pend) + _M_mode = _M_mode | ios_base::out; + // The output sequence is highly tied to _M_buf and + // _M_buf_size in addition to the actual pointers into the + // buffer. Because of this, (re)set _M_buf_size here, as + // sputc/xsputn need _M_buf_size to be accurate. (The + // corresponding input functions rely instead on _M_in_end.) + _M_buf_size = max(_M_buf_size, static_cast<int_type>(__pend - __pbeg)); + } + + // Virtual functions: + // Locales: + virtual void + imbue(const locale& __loc) + { + _M_buf_locale_init = true; + if (_M_buf_locale != __loc) + { + _M_buf_locale = __loc; + _M_buf_fctype = &use_facet<__ctype_type>(_M_buf_locale); + } + } + + // Buffer management and positioning: + virtual basic_streambuf<char_type,_Traits>* + setbuf(char_type*, streamsize) + { return this; } + + virtual pos_type + seekoff(off_type, ios_base::seekdir, + ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) + { return pos_type(off_type(-1)); } + + virtual pos_type + seekpos(pos_type, + ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) + { return pos_type(off_type(-1)); } + + virtual int + sync() { return 0; } + + // Get area: + virtual streamsize + showmanyc() { return 0; } + + virtual streamsize + xsgetn(char_type* __s, streamsize __n); + + virtual int_type + underflow() + { return traits_type::eof(); } + + virtual int_type + uflow() + { + int_type __ret = traits_type::eof(); + bool __testeof = this->underflow() == __ret; + bool __testpending = _M_in_cur && _M_in_cur < _M_in_end; + + if (!__testeof && __testpending) + { + __ret = traits_type::to_int_type(*_M_in_cur); + ++_M_in_cur; + if (_M_buf_unified && _M_mode & ios_base::out) + ++_M_out_cur; + } + return __ret; + } + + // Putback: + virtual int_type + pbackfail(int_type /* __c */ = traits_type::eof()) + { return traits_type::eof(); } + + // Put area: + virtual streamsize + xsputn(const char_type* __s, streamsize __n); + + virtual int_type + overflow(int_type /* __c */ = traits_type::eof()) + { return traits_type::eof(); } + +#ifdef _GLIBCPP_DEPRICATED + public: + void + stossc() + { + if (_M_in_cur < _M_in_end) + ++_M_in_cur; + else + this->uflow(); + } +#endif + +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + private: + basic_streambuf(const __streambuf_type&); + + __streambuf_type& + operator=(const __streambuf_type&); +#endif + }; + +} // namespace std + +#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT +# define export +#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS +#include <bits/streambuf.tcc> +#endif +#endif + +#endif /* _CPP_STREAMBUF */ + + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/std_string.h b/libstdc++-v3/include/bits/std_string.h new file mode 100644 index 00000000000..6008eca2862 --- /dev/null +++ b/libstdc++-v3/include/bits/std_string.h @@ -0,0 +1,63 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +#ifndef _CPP_STRING +#define _CPP_STRING 1 + +#include <bits/c++config.h> +#include <bits/stl_string_fwd.h> +#include <bits/std_iterator.h> +#include <bits/char_traits.h> +#include <bits/type_traits.h> +#include <bits/std_iosfwd.h> // for operators >>, <<, and getline decls +#include <bits/basic_string.h> + +#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT +# include <bits/std_algorithm.h> // for find_if +# include <bits/string.tcc> +#endif + +#endif /* _CPP_STRING */ + + + + + + + + + + + + + diff --git a/libstdc++-v3/include/bits/std_strstream.h b/libstdc++-v3/include/bits/std_strstream.h new file mode 100644 index 00000000000..2f784b36fce --- /dev/null +++ b/libstdc++-v3/include/bits/std_strstream.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +// WARNING: The classes defined in this header are DEPRECATED. This +// header is defined in section D.7.1 of the C++ standard, and it +// MAY BE REMOVED in a future standard revision. You should use the +// header <sstream> instead. + +#ifndef __SGI_STL_STRSTREAM +#define __SGI_STL_STRSTREAM + +#if defined(__sgi) && !defined(__GNUC__) && !defined(_STANDARD_C_PLUS_PLUS) +#error This header file requires the -LANG:std option +#endif + +#include <bits/std_iosfwd.h> +#include <bits/std_ios.h> +#include <bits/std_istream.h> +#include <bits/std_ostream.h> +#include <bits/std_string.h> + +__STL_BEGIN_NAMESPACE + +//---------------------------------------------------------------------- +// Class strstreambuf, a streambuf class that manages an array of char. +// Note that this class is not a template. + +class strstreambuf : public basic_streambuf<char, char_traits<char> > +{ +public: // Types. + typedef char_traits<char> _Traits; + typedef basic_streambuf<char, _Traits> _Base; + +public: // Constructor, destructor + explicit strstreambuf(streamsize __initial_capacity = 0); + strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*)); + + strstreambuf(char* __get, streamsize __n, char* __put = 0); + strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0); + strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0); + + strstreambuf(const char* __get, streamsize __n); + strstreambuf(const signed char* __get, streamsize __n); + strstreambuf(const unsigned char* __get, streamsize __n); + + virtual ~strstreambuf(); + +public: // strstreambuf operations. + void freeze(bool = true); + char* str(); + int pcount() const; + +protected: // Overridden virtual member functions. + virtual int_type overflow(int_type __c = _Traits::eof()); + virtual int_type pbackfail(int_type __c = _Traits::eof()); + virtual int_type underflow(); + virtual _Base* setbuf(char* __buf, streamsize __n); + virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir, + ios_base::openmode __mode + = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode + = ios_base::in | ios_base::out); + +private: // Helper functions. + // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun. + char* _M_alloc(size_t); + void _M_free(char*); + + // Helper function used in constructors. + void _M_setup(char* __get, char* __put, streamsize __n); + +private: // Data members. + void* (*_M_alloc_fun)(size_t); + void (*_M_free_fun)(void*); + + bool _M_dynamic : 1; + bool _M_frozen : 1; + bool _M_constant : 1; +}; + +//---------------------------------------------------------------------- +// Class istrstream, an istream that manages a strstreambuf. + +class istrstream : public basic_istream<char> +{ +public: + explicit istrstream(char*); + explicit istrstream(const char*); + istrstream(char* , streamsize); + istrstream(const char*, streamsize); + virtual ~istrstream(); + + strstreambuf* rdbuf() const; + char* str(); + +private: + strstreambuf _M_buf; +}; + +//---------------------------------------------------------------------- +// Class ostrstream + +class ostrstream : public basic_ostream<char> +{ +public: + ostrstream(); + ostrstream(char*, int, ios_base::openmode = ios_base::out); + virtual ~ostrstream(); + + strstreambuf* rdbuf() const; + void freeze(bool = true); + char* str(); + int pcount() const; + +private: + strstreambuf _M_buf; +}; + +//---------------------------------------------------------------------- +// Class strstream + +class strstream : public basic_iostream<char> +{ +public: + typedef char char_type; + typedef char_traits<char>::int_type int_type; + typedef char_traits<char>::pos_type pos_type; + typedef char_traits<char>::off_type off_type; + + strstream(); + strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out); + virtual ~strstream(); + + strstreambuf* rdbuf() const; + void freeze(bool = true); + int pcount() const; + char* str(); + +private: + strstreambuf _M_buf; +}; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_STRSTREAM */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_typeinfo.h b/libstdc++-v3/include/bits/std_typeinfo.h new file mode 100644 index 00000000000..b0590121631 --- /dev/null +++ b/libstdc++-v3/include/bits/std_typeinfo.h @@ -0,0 +1,81 @@ + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 _CPP_TYPEINFO +#define _CPP_TYPEINFO 1 + +#include <bits/c++config.h> +#include <bits/std_exception.h> + +#ifdef __GNUG__ +# pragma GCC system_header +# include_next <typeinfo> +#else + +__STL_BEGIN_NAMESPACE + + class type_info { + public: + virtual ~type_info(); + bool operator==(const type_info& rhs) const; + bool operator!=(const type_info& rhs) const; + bool before(const type_info& rhs) const; + const char* name() const; + private: + type_info(const type_info& rhs); + type_info& operator=(const type_info& rhs); + }; + + class bad_cast : public exception { + public: + bad_cast() throw(); + bad_cast(const bad_cast&) throw(); + bad_cast& operator=(const bad_cast&) throw(); + virtual ~bad_cast() throw(); + virtual const char* what() const throw(); + }; + + class bad_typeid : public exception { + public: + bad_typeid() throw(); + bad_typeid(const bad_typeid&) throw(); + bad_typeid& operator=(const bad_typeid&) throw(); + virtual ~bad_typeid() throw(); + virtual const char* what() const throw(); + }; + +__STL_END_NAMESPACE + +#endif + +#endif /* _CPP_TYPEINFO */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_utility.h b/libstdc++-v3/include/bits/std_utility.h new file mode 100644 index 00000000000..e10dae35b6a --- /dev/null +++ b/libstdc++-v3/include/bits/std_utility.h @@ -0,0 +1,38 @@ +/* + * + * 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 _CPP_UTILITY +#define _CPP_UTILITY 1 + +#include <bits/stl_config.h> +#include <bits/stl_relops.h> +#include <bits/stl_pair.h> + +#endif /* _CPP_UTILITY */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/std_valarray.h b/libstdc++-v3/include/bits/std_valarray.h new file mode 100644 index 00000000000..fa43c6dca0c --- /dev/null +++ b/libstdc++-v3/include/bits/std_valarray.h @@ -0,0 +1,728 @@ +// The template and inlines for the -*- C++ -*- valarray class. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _CPP_VALARRAY +#define _CPP_VALARRAY 1 + +#include <bits/c++config.h> +#include <bits/std_cstddef.h> +#include <bits/std_cmath.h> +#include <bits/std_cstdlib.h> +#include <bits/std_numeric.h> +#include <bits/std_functional.h> +#include <bits/std_algorithm.h> + +namespace std { + + template<class _Clos, typename _Tp> class _Expr; + + template<typename _Tp1, typename _Tp2> class _ValArray; + + template<template<class> class _Oper, + template<class, class> class _Meta, class _Dom> struct _UnClos; + + template<template<class> class _Oper, + template<class, class> class _Meta1, + template<class, class> class _Meta2, + class _Dom1, class _Dom2> class _BinClos; + + template<template<class, class> class _Meta, class _Dom> class _SClos; + + template<template<class, class> class _Meta, class _Dom> class _GClos; + + template<template<class, class> class _Meta, class _Dom> class _IClos; + + template<template<class, class> class _Meta, class _Dom> class _ValFunClos; + + template<template<class, class> class _Meta, class _Dom> class _RefFunClos; + + template<class _Tp> struct _Unary_plus; + template<class _Tp> struct _Bitwise_and; + template<class _Tp> struct _Bitwise_or; + template<class _Tp> struct _Bitwise_xor; + template<class _Tp> struct _Bitwise_not; + template<class _Tp> struct _Shift_left; + template<class _Tp> struct _Shift_right; + + template<class _Tp> class valarray; // An array of type _Tp + class slice; // BLAS-like slice out of an array + template<class _Tp> class slice_array; + class gslice; // generalized slice out of an array + template<class _Tp> class gslice_array; + template<class _Tp> class mask_array; // masked array + template<class _Tp> class indirect_array; // indirected array + +} + +#include <bits/valarray_array.h> +#include <bits/valarray_meta.h> + +namespace std { + + template<class _Tp> class valarray + { + public: + typedef _Tp value_type; + + // _lib.valarray.cons_ construct/destroy: + valarray(); + explicit valarray(size_t); + valarray(const _Tp&, size_t); + valarray(const _Tp* __restrict__, size_t); + valarray(const valarray&); + valarray(const slice_array<_Tp>&); + valarray(const gslice_array<_Tp>&); + valarray(const mask_array<_Tp>&); + valarray(const indirect_array<_Tp>&); + template<class _Dom> + valarray(const _Expr<_Dom,_Tp>& __e); + ~valarray(); + + // _lib.valarray.assign_ assignment: + valarray<_Tp>& operator=(const valarray<_Tp>&); + valarray<_Tp>& operator=(const _Tp&); + valarray<_Tp>& operator=(const slice_array<_Tp>&); + valarray<_Tp>& operator=(const gslice_array<_Tp>&); + valarray<_Tp>& operator=(const mask_array<_Tp>&); + valarray<_Tp>& operator=(const indirect_array<_Tp>&); + + template<class _Dom> valarray<_Tp>& + operator= (const _Expr<_Dom,_Tp>&); + + // _lib.valarray.access_ element access: + _Tp operator[](size_t) const; + _Tp& operator[](size_t); + // _lib.valarray.sub_ subset operations: + _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const; + slice_array<_Tp> operator[](slice); + _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const; + gslice_array<_Tp> operator[](const gslice&); + valarray<_Tp> operator[](const valarray<bool>&) const; + mask_array<_Tp> operator[](const valarray<bool>&); + _Expr<_IClos<_ValArray, _Tp>, _Tp> + operator[](const valarray<size_t>&) const; + indirect_array<_Tp> operator[](const valarray<size_t>&); + + // _lib.valarray.unary_ unary operators: + _Expr<_UnClos<_Unary_plus,_ValArray,_Tp>,_Tp> operator+ () const; + _Expr<_UnClos<negate,_ValArray,_Tp>,_Tp> operator- () const; + _Expr<_UnClos<_Bitwise_not,_ValArray,_Tp>,_Tp> operator~ () const; + _Expr<_UnClos<logical_not,_ValArray,_Tp>,bool> operator! () const; + + // _lib.valarray.cassign_ computed assignment: + valarray<_Tp>& operator*= (const _Tp&); + valarray<_Tp>& operator/= (const _Tp&); + valarray<_Tp>& operator%= (const _Tp&); + valarray<_Tp>& operator+= (const _Tp&); + valarray<_Tp>& operator-= (const _Tp&); + valarray<_Tp>& operator^= (const _Tp&); + valarray<_Tp>& operator&= (const _Tp&); + valarray<_Tp>& operator|= (const _Tp&); + valarray<_Tp>& operator<<=(const _Tp&); + valarray<_Tp>& operator>>=(const _Tp&); + valarray<_Tp>& operator*= (const valarray<_Tp>&); + valarray<_Tp>& operator/= (const valarray<_Tp>&); + valarray<_Tp>& operator%= (const valarray<_Tp>&); + valarray<_Tp>& operator+= (const valarray<_Tp>&); + valarray<_Tp>& operator-= (const valarray<_Tp>&); + valarray<_Tp>& operator^= (const valarray<_Tp>&); + valarray<_Tp>& operator|= (const valarray<_Tp>&); + valarray<_Tp>& operator&= (const valarray<_Tp>&); + valarray<_Tp>& operator<<=(const valarray<_Tp>&); + valarray<_Tp>& operator>>=(const valarray<_Tp>&); + + template<class _Dom> + valarray<_Tp>& operator*= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator/= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator%= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator+= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator-= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator^= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator|= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator&= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&); + + + // _lib.valarray.members_ member functions: + size_t size() const; + _Tp sum() const; + _Tp min() const; + _Tp max() const; + +// // FIXME: Extension +// _Tp product () const; + + valarray<_Tp> shift (int) const; + valarray<_Tp> cshift(int) const; + _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const; + _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const; + void resize(size_t __size, _Tp __c = _Tp()); + + private: + size_t _M_size; + _Tp* __restrict__ _M_data; + + friend class _Array<_Tp>; + }; + + + template<typename _Tp> struct _Unary_plus : unary_function<_Tp,_Tp> { + _Tp operator() (const _Tp& __t) const { return __t; } + }; + + template<typename _Tp> struct _Bitwise_and : binary_function<_Tp,_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x & __y; } + }; + + template<typename _Tp> struct _Bitwise_or : binary_function<_Tp,_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x | __y; } + }; + + template<typename _Tp> struct _Bitwise_xor : binary_function<_Tp,_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x ^ __y; } + }; + + template<typename _Tp> struct _Bitwise_not : unary_function<_Tp,_Tp> { + _Tp operator() (_Tp __t) const { return ~__t; } + }; + + template<typename _Tp> struct _Shift_left : unary_function<_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x << __y; } + }; + + template<typename _Tp> struct _Shift_right : unary_function<_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x >> __y; } + }; + + + template<typename _Tp> + inline _Tp + valarray<_Tp>::operator[] (size_t __i) const + { return _M_data[__i]; } + + template<typename _Tp> + _Tp& + valarray<_Tp>::operator[] (size_t __i) + { return _M_data[__i]; } + +} // std:: + +#include <bits/slice.h> +#include <bits/slice_array.h> +#include <bits/gslice.h> +#include <bits/gslice_array.h> +#include <bits/mask_array.h> +#include <bits/indirect_array.h> + +namespace std { + + template<typename _Tp> + inline valarray<_Tp>::valarray () : _M_size (0), _M_data (0) {} + + template<typename _Tp> + inline valarray<_Tp>::valarray (size_t __n) + : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) + { __valarray_default_construct(_M_data, _M_data + __n); } + + template<typename _Tp> + inline valarray<_Tp>::valarray (const _Tp& __t, size_t __n) + : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) + { __valarray_fill_construct (_M_data, _M_data + __n, __t); } + + template<typename _Tp> + inline valarray<_Tp>::valarray (const _Tp* __restrict__ __p, size_t __n) + : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) + { __valarray_copy_construct (__p, __p + __n, _M_data); } + + template<typename _Tp> + inline valarray<_Tp>::valarray (const valarray<_Tp>& __v) + : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size)) + { __valarray_copy_construct (__v._M_data, __v._M_data + _M_size, _M_data); } + + template<typename _Tp> + inline valarray<_Tp>::valarray (const slice_array<_Tp>& __sa) + : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz)) + { + __valarray_copy_construct + (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); + } + + template<typename _Tp> + inline valarray<_Tp>::valarray (const gslice_array<_Tp>& __ga) + : _M_size(__ga._M_index.size()), + _M_data(__valarray_get_storage<_Tp>(_M_size)) + { + __valarray_copy_construct + (__ga._M_array, _Array<size_t>(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); + } + + template<typename _Tp> + inline valarray<_Tp>::valarray (const mask_array<_Tp>& __ma) + : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) + { + __valarray_copy_construct + (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); + } + + template<typename _Tp> + inline valarray<_Tp>::valarray (const indirect_array<_Tp>& __ia) + : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) + { + __valarray_copy_construct + (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); + } + + template<typename _Tp> template<class _Dom> + inline valarray<_Tp>::valarray (const _Expr<_Dom, _Tp>& __e) + : _M_size(__e.size ()), _M_data(__valarray_get_storage<_Tp>(_M_size)) + { __valarray_copy_construct (__e, _M_size, _Array<_Tp>(_M_data)); } + + template<typename _Tp> + inline valarray<_Tp>::~valarray () + { + __valarray_destroy_elements(_M_data, _M_data + _M_size); + __valarray_release_memory(_M_data); + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator= (const valarray<_Tp>& __v) + { + __valarray_copy(__v._M_data, _M_size, _M_data); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator= (const _Tp& __t) + { + __valarray_fill (_M_data, _M_size, __t); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator= (const slice_array<_Tp>& __sa) + { + __valarray_copy (__sa._M_array, __sa._M_sz, + __sa._M_stride, _Array<_Tp>(_M_data)); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator= (const gslice_array<_Tp>& __ga) + { + __valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator= (const mask_array<_Tp>& __ma) + { + __valarray_copy (__ma._M_array, __ma._M_mask, + _Array<_Tp>(_M_data), _M_size); + return *this; + } + + template<typename _Tp> + inline valarray<_Tp>& + valarray<_Tp>::operator= (const indirect_array<_Tp>& __ia) + { + __valarray_copy (__ia._M_array, __ia._M_index, + _Array<_Tp>(_M_data), _M_size); + return *this; + } + + template<typename _Tp> template<class _Dom> + inline valarray<_Tp>& + valarray<_Tp>::operator= (const _Expr<_Dom, _Tp>& __e) + { + __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); + return *this; + } + + template<typename _Tp> + inline _Expr<_SClos<_ValArray,_Tp>, _Tp> + valarray<_Tp>::operator[] (slice __s) const + { + typedef _SClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> (_Closure (_Array<_Tp>(_M_data), __s)); + } + + template<typename _Tp> + inline slice_array<_Tp> + valarray<_Tp>::operator[] (slice __s) + { + return slice_array<_Tp> (_Array<_Tp>(_M_data), __s); + } + + template<typename _Tp> + inline _Expr<_GClos<_ValArray,_Tp>, _Tp> + valarray<_Tp>::operator[] (const gslice& __gs) const + { + typedef _GClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> + (_Closure (_Array<_Tp>(_M_data), __gs._M_index->_M_index)); + } + + template<typename _Tp> + inline gslice_array<_Tp> + valarray<_Tp>::operator[] (const gslice& __gs) + { + return gslice_array<_Tp> + (_Array<_Tp>(_M_data), __gs._M_index->_M_index); + } + + template<typename _Tp> + inline valarray<_Tp> + valarray<_Tp>::operator[] (const valarray<bool>& __m) const + { + size_t __s (0); + size_t __e (__m.size ()); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return valarray<_Tp> (mask_array<_Tp> (_Array<_Tp>(_M_data), __s, + _Array<bool> (__m))); + } + + template<typename _Tp> + inline mask_array<_Tp> + valarray<_Tp>::operator[] (const valarray<bool>& __m) + { + size_t __s (0); + size_t __e (__m.size ()); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return mask_array<_Tp> (_Array<_Tp>(_M_data), __s, _Array<bool> (__m)); + } + + template<typename _Tp> + inline _Expr<_IClos<_ValArray,_Tp>, _Tp> + valarray<_Tp>::operator[] (const valarray<size_t>& __i) const + { + typedef _IClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> (_Closure (*this, __i)); + } + + template<typename _Tp> + inline indirect_array<_Tp> + valarray<_Tp>::operator[] (const valarray<size_t>& __i) + { + return indirect_array<_Tp> (_Array<_Tp>(_M_data), __i.size(), + _Array<size_t> (__i)); + } + + template<class _Tp> + inline size_t valarray<_Tp>::size () const { return _M_size; } + + template<class _Tp> + inline _Tp + valarray<_Tp>::sum () const + { + return __valarray_sum(_M_data, _M_data + _M_size); + } + +// template<typename _Tp> +// inline _Tp +// valarray<_Tp>::product () const +// { +// return __valarray_product(_M_data, _M_data + _M_size); +// } + + template <class _Tp> + inline valarray<_Tp> + valarray<_Tp>::shift (int __n) const + { + _Tp* const __a = static_cast<_Tp*> + (__builtin_alloca (sizeof(_Tp) * _M_size)); + if (! __n) // __n == 0: no shift + __valarray_copy_construct(_M_data, _M_data + _M_size, __a); + else if (__n > 0) { // __n > 0: shift left + if (__n > _M_size) + __valarray_default_construct(__a, __a + __n); + else { + __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); + __valarray_default_construct(__a+_M_size-__n, __a + _M_size); + } + } + else { // __n < 0: shift right + __valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n); + __valarray_default_construct(__a, __a - __n); + } + return valarray<_Tp> (__a, _M_size); + } + + template <class _Tp> + inline valarray<_Tp> + valarray<_Tp>::cshift (int __n) const + { + _Tp* const __a = static_cast<_Tp*> + (__builtin_alloca (sizeof(_Tp) * _M_size)); + if (! __n) // __n == 0: no cshift + __valarray_copy_construct(_M_data, _M_data + _M_size, __a); + else if (__n > 0) { // __n > 0: cshift left + __valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n); + __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); + } + else { // __n < 0: cshift right + __valarray_copy_construct + (_M_data + _M_size+__n, _M_data + _M_size, __a); + __valarray_copy_construct + (_M_data, _M_data + _M_size+__n, __a - __n); + } + return valarray<_Tp> (__a, _M_size); + } + + template <class _Tp> + inline void + valarray<_Tp>::resize (size_t __n, _Tp __c) + { + // This complication is so to make valarray<valarray<T> > work + // even though it is not required by the standard. Nobody should + // be saying valarray<valarray<T> > anyway. See the specs. + __valarray_destroy_elements(_M_data, _M_data + _M_size); + if (_M_size != __n) + { + __valarray_release_memory(_M_data); + _M_size = __n; + _M_data = __valarray_get_storage<_Tp>(__n); + } + __valarray_fill_construct(_M_data, _M_data + __n, __c); + } + + template<typename _Tp> + inline _Tp + valarray<_Tp>::min() const + { + return *min_element (_M_data, _M_data+_M_size); + } + + template<typename _Tp> + inline _Tp + valarray<_Tp>::max() const + { + return *max_element (_M_data, _M_data+_M_size); + } + + template<class _Tp> + inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> + valarray<_Tp>::apply (_Tp func (_Tp)) const + { + typedef _ValFunClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure,_Tp> (_Closure (*this, func)); + } + + template<class _Tp> + inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> + valarray<_Tp>::apply (_Tp func (const _Tp &)) const + { + typedef _RefFunClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure,_Tp> (_Closure (*this, func)); + } + +#define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline _Expr<_UnClos<_Name,_ValArray,_Tp>, _Tp> \ + valarray<_Tp>::operator _Op() const \ + { \ + typedef _UnClos<_Name,_ValArray,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (*this)); \ + } + + _DEFINE_VALARRAY_UNARY_OPERATOR(+, _Unary_plus) + _DEFINE_VALARRAY_UNARY_OPERATOR(-, negate) + _DEFINE_VALARRAY_UNARY_OPERATOR(~, _Bitwise_not) + +#undef _DEFINE_VALARRAY_UNARY_OPERATOR + + template<typename _Tp> + inline _Expr<_UnClos<logical_not,_ValArray,_Tp>, bool> + valarray<_Tp>::operator!() const + { + typedef _UnClos<logical_not,_ValArray,_Tp> _Closure; + return _Expr<_Closure, bool> (_Closure (*this)); + } + +#define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template<class _Tp> \ + inline valarray<_Tp> & \ + valarray<_Tp>::operator _Op##= (const _Tp &__t) \ + { \ + _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, __t); \ + return *this; \ + } \ + \ + template<class _Tp> \ + inline valarray<_Tp> & \ + valarray<_Tp>::operator _Op##= (const valarray<_Tp> &__v) \ + { \ + _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, \ + _Array<_Tp>(__v._M_data)); \ + return *this; \ + } + +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, plus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, minus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, multiplies) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, divides) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, modulus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, xor) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, and) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, or) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, shift_left) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, shift_right) + +#undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT + + +} // std:: + + +namespace std { + +#define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template<class _Tp> template<class _Dom> \ + inline valarray<_Tp> & \ + valarray<_Tp>::operator _Op##= (const _Expr<_Dom,_Tp> &__e) \ + { \ + _Array_augmented_##_Name (_Array<_Tp>(_M_data), __e, _M_size); \ + return *this; \ + } + +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, plus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, minus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, multiplies) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, divides) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, modulus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, xor) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, and) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, or) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, shift_left) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, shift_right) + +#undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT + + +#define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ + operator _Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \ + { \ + typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (__v, __w)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ + operator _Op (const valarray<_Tp> &__v, const _Tp &__t) \ + { \ + typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (__v, __t)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ + operator _Op (const _Tp &__t, const valarray<_Tp> &__v) \ + { \ + typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (__t, __v)); \ + } + +_DEFINE_BINARY_OPERATOR(+, plus) +_DEFINE_BINARY_OPERATOR(-, minus) +_DEFINE_BINARY_OPERATOR(*, multiplies) +_DEFINE_BINARY_OPERATOR(/, divides) +_DEFINE_BINARY_OPERATOR(%, modulus) +_DEFINE_BINARY_OPERATOR(^, _Bitwise_xor) +_DEFINE_BINARY_OPERATOR(&, _Bitwise_and) +_DEFINE_BINARY_OPERATOR(|, _Bitwise_or) +_DEFINE_BINARY_OPERATOR(<<, _Shift_left) +_DEFINE_BINARY_OPERATOR(>>, _Shift_right) + +#undef _DEFINE_BINARY_OPERATOR + +#define _DEFINE_LOGICAL_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,bool> \ + operator _Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \ + { \ + typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, bool> (_Closure (__v, __w)); \ + } \ + \ + template<class _Tp> \ + inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,bool> \ + operator _Op (const valarray<_Tp> &__v, const _Tp &__t) \ + { \ + typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, bool> (_Closure (__v, __t)); \ + } \ + \ + template<class _Tp> \ + inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,bool> \ + operator _Op (const _Tp &__t, const valarray<_Tp> &__v) \ + { \ + typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, bool> (_Closure (__t, __v)); \ + } + +_DEFINE_LOGICAL_OPERATOR(&&, logical_and) +_DEFINE_LOGICAL_OPERATOR(||, logical_or) +_DEFINE_LOGICAL_OPERATOR(==, equal_to) +_DEFINE_LOGICAL_OPERATOR(!=, not_equal_to) +_DEFINE_LOGICAL_OPERATOR(<, less) +_DEFINE_LOGICAL_OPERATOR(>, greater) +_DEFINE_LOGICAL_OPERATOR(<=, less_equal) +_DEFINE_LOGICAL_OPERATOR(>=, greater_equal) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // namespace std + +#endif // _CPP_VALARRAY + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/std_vector.h b/libstdc++-v3/include/bits/std_vector.h new file mode 100644 index 00000000000..08ac4bd69de --- /dev/null +++ b/libstdc++-v3/include/bits/std_vector.h @@ -0,0 +1,42 @@ +/* + * + * 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 _CPP_VECTOR +#define _CPP_VECTOR 1 + +#include <bits/stl_range_errors.h> +#include <bits/stl_algobase.h> +#include <bits/stl_alloc.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_vector.h> +#include <ext/stl_bvector.h> + +#endif /* _CPP_VECTOR */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h new file mode 100644 index 00000000000..c432d3d3ebc --- /dev/null +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -0,0 +1,3297 @@ +/* + * + * 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 <bits/stl_heap.h> + +// 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 <class _Tp> +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 <class _Tp, class _Compare> +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 <class _InputIter, class _Function> +_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 <class _InputIter, class _Tp> +inline _InputIter find(_InputIter __first, _InputIter __last, + const _Tp& __val, + input_iterator_tag) +{ + while (__first != __last && !(*__first == __val)) + ++__first; + return __first; +} + +template <class _InputIter, class _Predicate> +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 <class _RandomAccessIter, class _Tp> +_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 <class _RandomAccessIter, class _Predicate> +_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 <class _InputIter, class _Tp> +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 <class _InputIter, class _Predicate> +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 <class _ForwardIter> +_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 <class _ForwardIter, class _BinaryPredicate> +_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 <class _InputIter, class _Tp, class _Size> +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 <class _InputIter, class _Predicate, class _Size> +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 <class _InputIter, class _Tp> +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 <class _InputIter, class _Predicate> +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 <class _ForwardIter1, class _ForwardIter2> +_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 <class _ForwardIter1, class _ForwardIter2, class _BinaryPred> +_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 <class _ForwardIter, class _Integer, class _Tp> +_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 <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred> +_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 <class _ForwardIter1, class _ForwardIter2> +_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 <class _InputIter, class _OutputIter, class _UnaryOperation> +_OutputIter transform(_InputIter __first, _InputIter __last, + _OutputIter __result, _UnaryOperation __unary_op) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + + for ( ; __first != __last; ++__first, ++__result) + *__result = __unary_op(*__first); + return __result; +} + +template <class _InputIter1, class _InputIter2, class _OutputIter, + class _BinaryOperation> +_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 <class _ForwardIter, class _Tp> +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 <class _ForwardIter, class _Predicate, class _Tp> +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 <class _InputIter, class _OutputIter, class _Tp> +_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 <class _InputIter, class _OutputIter, class _Predicate, class _Tp> +_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 <class _ForwardIter, class _Generator> +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 <class _OutputIter, class _Size, class _Generator> +_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 <class _InputIter, class _OutputIter, class _Tp> +_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 <class _InputIter, class _OutputIter, class _Predicate> +_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 <class _ForwardIter, class _Tp> +_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 <class _ForwardIter, class _Predicate> +_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 <class _InputIter, class _OutputIter, class _Tp> +_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 <class _InputIter, class _OutputIter> +inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + output_iterator_tag) { + return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first)); +} + +template <class _InputIter, class _ForwardIter> +_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 <class _InputIter, class _OutputIter> +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 <class _InputIter, class _OutputIter, class _BinaryPredicate, + class _Tp> +_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 <class _InputIter, class _OutputIter, class _BinaryPredicate> +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 <class _InputIter, class _ForwardIter, class _BinaryPredicate> +_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 <class _InputIter, class _OutputIter, class _BinaryPredicate> +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 <class _ForwardIter> +_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 <class _ForwardIter, class _BinaryPredicate> +_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 <class _BidirectionalIter> +void __reverse(_BidirectionalIter __first, _BidirectionalIter __last, + bidirectional_iterator_tag) { + while (true) + if (__first == __last || __first == --__last) + return; + else + iter_swap(__first++, __last); +} + +template <class _RandomAccessIter> +void __reverse(_RandomAccessIter __first, _RandomAccessIter __last, + random_access_iterator_tag) { + while (__first < __last) + iter_swap(__first++, --__last); +} + +template <class _BidirectionalIter> +inline void reverse(_BidirectionalIter __first, _BidirectionalIter __last) { + __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator); + __reverse(__first, __last, __ITERATOR_CATEGORY(__first)); +} + +template <class _BidirectionalIter, class _OutputIter> +_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 <class _EuclideanRingElement> +_EuclideanRingElement __gcd(_EuclideanRingElement __m, + _EuclideanRingElement __n) +{ + while (__n != 0) { + _EuclideanRingElement __t = __m % __n; + __m = __n; + __n = __t; + } + return __m; +} + +template <class _ForwardIter, class _Distance> +_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 <class _BidirectionalIter, class _Distance> +_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 <class _RandomAccessIter, class _Distance, class _Tp> +_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 <class _ForwardIter> +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 <class _ForwardIter, class _OutputIter> +_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 <class _Distance> +inline _Distance __random_number(_Distance __n) { +#ifdef __STL_NO_DRAND48 + return rand() % __n; +#else + return lrand48() % __n; +#endif +} + +// random_shuffle + +template <class _RandomAccessIter> +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 <class _RandomAccessIter, class _RandomNumberGenerator> +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 <class _ForwardIter, class _OutputIter, class _Distance> +_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 <class _ForwardIter, class _OutputIter, class _Distance, + class _RandomNumberGenerator> +_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 <class _InputIter, class _RandomAccessIter, class _Distance> +_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 <class _InputIter, class _RandomAccessIter, + class _RandomNumberGenerator, class _Distance> +_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 <class _InputIter, class _RandomAccessIter> +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 <class _InputIter, class _RandomAccessIter, + class _RandomNumberGenerator> +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 <class _ForwardIter, class _Predicate> +_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 <class _BidirectionalIter, class _Predicate> +_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 <class _ForwardIter, class _Predicate> +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 <class _ForwardIter, class _Predicate, class _Distance> +_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 <class _ForwardIter, class _Pointer, class _Predicate, + class _Distance> +_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 <class _ForwardIter, class _Predicate, class _Tp, class _Distance> +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 <class _ForwardIter, class _Predicate> +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 <class _RandomAccessIter, class _Tp> +_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 <class _RandomAccessIter, class _Tp, class _Compare> +_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 <class _RandomAccessIter, class _Tp> +void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) { + _RandomAccessIter __next = __last; + --__next; + while (__val < *__next) { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; +} + +template <class _RandomAccessIter, class _Tp, class _Compare> +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 <class _RandomAccessIter, class _Tp> +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 <class _RandomAccessIter, class _Tp, class _Compare> +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 <class _RandomAccessIter> +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 <class _RandomAccessIter, class _Compare> +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 <class _RandomAccessIter, class _Tp> +void __unguarded_insertion_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*) { + for (_RandomAccessIter __i = __first; __i != __last; ++__i) + __unguarded_linear_insert(__i, _Tp(*__i)); +} + +template <class _RandomAccessIter> +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first)); +} + +template <class _RandomAccessIter, class _Tp, class _Compare> +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 <class _RandomAccessIter, class _Compare> +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, + _Compare __comp) { + __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first), + __comp); +} + +template <class _RandomAccessIter> +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 <class _RandomAccessIter, class _Compare> +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 <class _Size> +inline _Size __lg(_Size __n) { + _Size __k; + for (__k = 0; __n != 1; __n >>= 1) ++__k; + return __k; +} + +template <class _RandomAccessIter, class _Tp, class _Size> +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 <class _RandomAccessIter, class _Tp, class _Size, class _Compare> +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 <class _RandomAccessIter> +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 <class _RandomAccessIter, class _Compare> +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 <class _RandomAccessIter> +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 <class _RandomAccessIter, class _Compare> +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 <class _RandomAccessIter1, class _RandomAccessIter2, + class _Distance> +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 <class _RandomAccessIter1, class _RandomAccessIter2, + class _Distance, class _Compare> +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 <class _RandomAccessIter, class _Distance> +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 <class _RandomAccessIter, class _Distance, class _Compare> +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 <class _RandomAccessIter, class _Pointer, class _Distance> +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 <class _RandomAccessIter, class _Pointer, class _Distance, + class _Compare> +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 <class _RandomAccessIter, class _Pointer, class _Distance> +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 <class _RandomAccessIter, class _Pointer, class _Distance, + class _Compare> +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 <class _RandomAccessIter, class _Tp, class _Distance> +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 <class _RandomAccessIter, class _Tp, class _Distance, class _Compare> +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 <class _RandomAccessIter> +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 <class _RandomAccessIter, class _Compare> +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 <class _RandomAccessIter, class _Tp> +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 <class _RandomAccessIter> +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 <class _RandomAccessIter, class _Tp, class _Compare> +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 <class _RandomAccessIter, class _Compare> +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 <class _InputIter, class _RandomAccessIter, class _Distance, + class _Tp> +_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 <class _InputIter, class _RandomAccessIter> +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 <class _InputIter, class _RandomAccessIter, class _Compare, + class _Distance, class _Tp> +_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 <class _InputIter, class _RandomAccessIter, class _Compare> +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 <class _RandomAccessIter, class _Tp> +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 <class _RandomAccessIter> +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 <class _RandomAccessIter, class _Tp, class _Compare> +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 <class _RandomAccessIter, class _Compare> +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 <class _ForwardIter, class _Tp, class _Distance> +_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 <class _ForwardIter, class _Tp> +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 <class _ForwardIter, class _Tp, class _Compare, class _Distance> +_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 <class _ForwardIter, class _Tp, class _Compare> +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 <class _ForwardIter, class _Tp, class _Distance> +_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 <class _ForwardIter, class _Tp> +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 <class _ForwardIter, class _Tp, class _Compare, class _Distance> +_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 <class _ForwardIter, class _Tp, class _Compare> +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 <class _ForwardIter, class _Tp, class _Distance> +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 <class _ForwardIter, class _Tp> +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 <class _ForwardIter, class _Tp, class _Compare, class _Distance> +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 <class _ForwardIter, class _Tp, class _Compare> +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 <class _ForwardIter, class _Tp> +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 <class _ForwardIter, class _Tp, class _Compare> +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 <class _InputIter1, class _InputIter2, class _OutputIter> +_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 <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_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 <class _BidirectionalIter, class _Distance> +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 <class _BidirectionalIter, class _Distance, class _Compare> +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 <class _BidirectionalIter1, class _BidirectionalIter2, + class _Distance> +_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 <class _BidirectionalIter1, class _BidirectionalIter2, + class _BidirectionalIter3> +_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 <class _BidirectionalIter1, class _BidirectionalIter2, + class _BidirectionalIter3, class _Compare> +_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 <class _BidirectionalIter, class _Distance, class _Pointer> +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 <class _BidirectionalIter, class _Distance, class _Pointer, + class _Compare> +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 <class _BidirectionalIter, class _Tp, class _Distance> +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 <class _BidirectionalIter, class _Tp, + class _Distance, class _Compare> +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 <class _BidirectionalIter> +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 <class _BidirectionalIter, class _Compare> +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 <class _InputIter1, class _InputIter2> +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 <class _InputIter1, class _InputIter2, class _Compare> +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 <class _InputIter1, class _InputIter2, class _OutputIter> +_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 <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_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 <class _InputIter1, class _InputIter2, class _OutputIter> +_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 <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_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 <class _InputIter1, class _InputIter2, class _OutputIter> +_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 <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_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 <class _InputIter1, class _InputIter2, class _OutputIter> +_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 <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_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 <class _ForwardIter> +_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 <class _ForwardIter, class _Compare> +_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 <class _ForwardIter> +_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 <class _ForwardIter, class _Compare> +_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 <class _BidirectionalIter> +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 <class _BidirectionalIter, class _Compare> +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 <class _BidirectionalIter> +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 <class _BidirectionalIter, class _Compare> +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 <class _InputIter, class _ForwardIter> +_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 <class _InputIter, class _ForwardIter, class _BinaryPredicate> +_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 <class _ForwardIter1, class _ForwardIter2> +_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 <class _ForwardIter1, class _ForwardIter2, + class _BinaryPredicate> +_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 <class _BidirectionalIter1, class _BidirectionalIter2> +_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 <class _BidirectionalIter1, class _BidirectionalIter2, + class _BinaryPredicate> +_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 <class _ForwardIter1, class _ForwardIter2> +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 <class _ForwardIter1, class _ForwardIter2, + class _BinaryPredicate> +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 <class _RandomAccessIter, class _Distance> +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 <class _RandomAccessIter, class _Distance, class _StrictWeakOrdering> +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 <class _RandomAccessIter> +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 <class _RandomAccessIter, class _StrictWeakOrdering> +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 <class _ForwardIter> +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 <class _ForwardIter, class _StrictWeakOrdering> +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: diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h new file mode 100644 index 00000000000..71889e0853f --- /dev/null +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -0,0 +1,756 @@ +/* + * + * 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 + +#include <bits/stl_config.h> +#include <bits/stl_relops.h> +#ifndef __SGI_STL_INTERNAL_PAIR_H +#include <bits/stl_pair.h> +#endif +#ifndef _CPP_BITS_TYPE_TRAITS_H +#include <bits/type_traits.h> +#endif +#include <bits/std_cstring.h> +#include <bits/std_climits.h> +#include <bits/std_cstdlib.h> +#include <bits/std_cstddef.h> +#include <bits/std_new.h> + +#ifdef __STL_USE_NEW_IOSTREAMS +#include <iosfwd> +#else /* __STL_USE_NEW_IOSTREAMS */ +#include <bits/std_iosfwd.h> +#endif /* __STL_USE_NEW_IOSTREAMS */ + +#include <bits/stl_iterator_base.h> +#include <bits/stl_iterator.h> + +// We pick up concept_checks.h from stl_iterator_base.h. + +__STL_BEGIN_NAMESPACE + +// swap and iter_swap + +template <class _ForwardIter1, class _ForwardIter2, class _Tp> +inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) { + _Tp __tmp = *__a; + *__a = *__b; + *__b = __tmp; +} + +template <class _ForwardIter1, class _ForwardIter2> +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 <class _Tp> +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 <class _Tp> +inline const _Tp& min(const _Tp& __a, const _Tp& __b) { + __STL_REQUIRES(_Tp, _LessThanComparable); + //return __b < __a ? __b : __a; + if (__b < __a) return __b; return __a; +} + +template <class _Tp> +inline const _Tp& max(const _Tp& __a, const _Tp& __b) { + __STL_REQUIRES(_Tp, _LessThanComparable); + //return __a < __b ? __b : __a; + if (__a < __b) return __b; return __a; +} + +#endif /* __BORLANDC__ */ + +template <class _Tp, class _Compare> +inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) { + //return __comp(__b, __a) ? __b : __a; + if (__comp(__b, __a)) return __b; return __a; +} + +template <class _Tp, class _Compare> +inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) { + //return __comp(__a, __b) ? __b : __a; + if (__comp(__a, __b)) return __b; return __a; +} + +//-------------------------------------------------- +// 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 <class _InputIter, class _OutputIter, class _Distance> +inline _OutputIter __copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + input_iterator_tag, _Distance*) +{ + for ( ; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; +} + +template <class _RandomAccessIter, class _OutputIter, class _Distance> +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 <class _Tp> +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 <class _InputIter, class _OutputIter> +inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last, + _OutputIter __result, __false_type) { + return __copy(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); +} + +template <class _InputIter, class _OutputIter> +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 <class _Tp> +inline _Tp* __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result, + __true_type) { + return __copy_trivial(__first, __last, __result); +} + +#endif /* __USLC__ */ + +template <class _Tp> +inline _Tp* __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result, + __true_type) { + return __copy_trivial(__first, __last, __result); +} + + +template <class _InputIter, class _OutputIter, class _Tp> +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<typename _InputIter, typename _OutputIter> +inline _OutputIter __copy_ni2(_InputIter __first, _InputIter __last, + _OutputIter __result, __true_type) { + return _OutputIter(__copy_aux(__first, __last, __result.base(), + __VALUE_TYPE(__first))); +} + +template<typename _InputIter, typename _OutputIter> +inline _OutputIter __copy_ni2(_InputIter __first, _InputIter __last, + _OutputIter __result, __false_type) { + return __copy_aux(__first, __last, __result, __VALUE_TYPE(__first)); +} + +template<typename _InputIter, typename _OutputIter> +inline _OutputIter __copy_ni1(_InputIter __first, _InputIter __last, + _OutputIter __result, __true_type) { + typedef typename _Is_normal_iterator<_OutputIter>::_Normal __Normal; + return __copy_ni2(__first.base(), __last.base(), __result, __Normal()); +} + +template<typename _InputIter, typename _OutputIter> +inline _OutputIter __copy_ni1(_InputIter __first, _InputIter __last, + _OutputIter __result, __false_type) { + typedef typename _Is_normal_iterator<_OutputIter>::_Normal __Normal; + return __copy_ni2(__first, __last, __result, __Normal()); +} + +template <class _InputIter, class _OutputIter> +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + __STL_REQUIRES(_InputIter, _InputIterator); + __STL_REQUIRES(_OutputIter, _OutputIterator); + typedef typename _Is_normal_iterator<_InputIter>::_Normal __Normal; + return __copy_ni1(__first, __last, __result, __Normal()); +} + +// 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 <class _InputIter, class _OutputIter, class _BoolType> +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 <class _Tp> +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 <class _Tp> +struct __copy_dispatch<const _Tp*, _Tp*, __true_type> +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_trivial(__first, __last, __result); + } +}; + +template <class _InputIter, class _OutputIter> +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 <class _InputIter, class _OutputIter> +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 <class _BidirectionalIter1, class _BidirectionalIter2, + class _Distance> +inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first, + _BidirectionalIter1 __last, + _BidirectionalIter2 __result, + bidirectional_iterator_tag, + _Distance*) +{ + while (__first != __last) + *--__result = *--__last; + return __result; +} + +template <class _RandomAccessIter, class _BidirectionalIter, class _Distance> +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 <class _BidirectionalIter1, class _BidirectionalIter2, + class _BoolType> +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 <class _Tp> +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 <class _Tp> +struct __copy_backward_dispatch<const _Tp*, _Tp*, __true_type> +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_backward_dispatch<_Tp*, _Tp*, __true_type> + ::copy(__first, __last, __result); + } +}; + +template <class _BI1, class _BI2> +inline _BI2 __copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result) { + typedef typename __type_traits<typename iterator_traits<_BI2>::value_type> + ::has_trivial_assignment_operator + _Trivial; + return __copy_backward_dispatch<_BI1, _BI2, _Trivial> + ::copy(__first, __last, __result); +} + +template <typename _BI1, typename _BI2> +inline _BI2 __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __true_type) { + return _BI2(__copy_backward_aux(__first, __last, __result.base())); +} + +template <typename _BI1, typename _BI2> +inline _BI2 __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __false_type){ + return __copy_backward_aux(__first, __last, __result); +} + +template <typename _BI1, typename _BI2> +inline _BI2 __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __true_type) { + typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal; + return __copy_backward_output_normal_iterator(__first.base(), __last.base(), + __result, __Normal()); +} + +template <typename _BI1, typename _BI2> +inline _BI2 __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __false_type) { + typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal; + return __copy_backward_output_normal_iterator(__first, __last, __result, + __Normal()); +} + +template <typename _BI1, typename _BI2> +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 _Is_normal_iterator<_BI1>::_Normal __Normal; + return __copy_backward_input_normal_iterator(__first, __last, __result, + __Normal()); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class _BI1, class _BI2> +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 <class _InputIter, class _Size, class _OutputIter> +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 <class _RAIter, class _Size, class _OutputIter> +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 <class _InputIter, class _Size, class _OutputIter> +inline pair<_InputIter, _OutputIter> +__copy_n(_InputIter __first, _Size __count, _OutputIter __result) { + return __copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +template <class _InputIter, class _Size, class _OutputIter> +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 <class _ForwardIter, class _Tp> +void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { + __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); + for ( ; __first != __last; ++__first) + *__first = __value; +} + +template <class _OutputIter, class _Size, class _Tp> +_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<unsigned char>(__tmp), __last - __first); +} + +inline void fill(char* __first, char* __last, const char& __c) { + char __tmp = __c; + memset(__first, static_cast<unsigned char>(__tmp), __last - __first); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Size> +inline unsigned char* fill_n(unsigned char* __first, _Size __n, + const unsigned char& __c) { + fill(__first, __first + __n, __c); + return __first + __n; +} + +template <class _Size> +inline signed char* fill_n(char* __first, _Size __n, + const signed char& __c) { + fill(__first, __first + __n, __c); + return __first + __n; +} + +template <class _Size> +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 <class _InputIter1, class _InputIter2> +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 <class _InputIter1, class _InputIter2, class _BinaryPredicate> +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 <class _InputIter1, class _InputIter2> +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 <class _InputIter1, class _InputIter2, class _BinaryPredicate> +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 <class _InputIter1, class _InputIter2> +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 <class _InputIter1, class _InputIter2, class _Compare> +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 <class _InputIter1, class _InputIter2> +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 <class _InputIter1, class _InputIter2> +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: diff --git a/libstdc++-v3/include/bits/stl_alloc.h b/libstdc++-v3/include/bits/stl_alloc.h new file mode 100644 index 00000000000..ca22b90699f --- /dev/null +++ b/libstdc++-v3/include/bits/stl_alloc.h @@ -0,0 +1,900 @@ +/* + * 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 <bits/std_cstdio.h> +# include <bits/std_cstdlib.h> +# define __THROW_BAD_ALLOC fprintf(stderr, "out of memory\n"); exit(1) +# else /* Standard conforming out-of-memory handling */ +# include <bits/std_new.h> +# define __THROW_BAD_ALLOC throw std::bad_alloc() +# endif +#endif + +#include <bits/std_cstddef.h> +#include <bits/std_cstdlib.h> +#include <bits/std_cstring.h> +#include <bits/std_cassert.h> +#ifndef __RESTRICT +# define __RESTRICT +#endif + +#ifdef __STL_THREADS +# include <bits/stl_threads.h> +# 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 <malloc.h> + // 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 <int __inst> +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 <int __inst> +void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0; +#endif + +template <int __inst> +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 <int __inst> +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 _Tp, class _Alloc> +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 _Alloc> +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 <bool threads, int inst> +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<false, 0> single_client_alloc; + +template <bool __threads, int __inst> +inline bool operator==(const __default_alloc_template<__threads, __inst>&, + const __default_alloc_template<__threads, __inst>&) +{ + return true; +} + +# ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template <bool __threads, int __inst> +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 <bool __threads, int __inst> +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 <bool __threads, int __inst> +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 <bool threads, int inst> +void* +__default_alloc_template<threads, inst>::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 <bool __threads, int __inst> + _STL_mutex_lock + __default_alloc_template<__threads, __inst>::_S_node_allocator_lock + __STL_MUTEX_INITIALIZER; +#endif + + +template <bool __threads, int __inst> +char* __default_alloc_template<__threads, __inst>::_S_start_free = 0; + +template <bool __threads, int __inst> +char* __default_alloc_template<__threads, __inst>::_S_end_free = 0; + +template <bool __threads, int __inst> +size_t __default_alloc_template<__threads, __inst>::_S_heap_size = 0; + +template <bool __threads, int __inst> +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 _Tp> +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 <class _Tp1> struct rebind { + typedef allocator<_Tp1> other; + }; + + allocator() __STL_NOTHROW {} + allocator(const allocator&) __STL_NOTHROW {} + template <class _Tp1> 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<void> { +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template <class _Tp1> struct rebind { + typedef allocator<_Tp1> other; + }; +}; + + +template <class _T1, class _T2> +inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) +{ + return true; +} + +template <class _T1, class _T2> +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 <class _Tp, class _Alloc> +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 <class _Tp1> struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; + + __allocator() __STL_NOTHROW {} + __allocator(const __allocator& __a) __STL_NOTHROW + : __underlying_alloc(__a.__underlying_alloc) {} + template <class _Tp1> + __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 _Alloc> +class __allocator<void, _Alloc> { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template <class _Tp1> struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; +}; + +template <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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<malloc_alloc> (for example) will +// work correctly. + +template <int inst> +inline bool operator==(const __malloc_alloc_template<inst>&, + const __malloc_alloc_template<inst>&) +{ + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template <int __inst> +inline bool operator!=(const __malloc_alloc_template<__inst>&, + const __malloc_alloc_template<__inst>&) +{ + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template <class _Alloc> +inline bool operator==(const debug_alloc<_Alloc>&, + const debug_alloc<_Alloc>&) { + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template <class _Alloc> +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 <class _Tp, class _Allocator> +struct _Alloc_traits +{ + static const bool _S_instanceless = false; + typedef typename _Allocator::__STL_TEMPLATE rebind<_Tp>::other + allocator_type; +}; + +template <class _Tp, class _Allocator> +const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; + +// The version for the default allocator. + +template <class _Tp, class _Tp1> +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 <class _Tp, int __inst> +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; +}; + +#ifndef __USE_MALLOC +template <class _Tp, bool __threads, int __inst> +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; +}; +#endif + +template <class _Tp, class _Alloc> +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 <class _Tp, class _Tp1, int __inst> +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; +}; + +#ifndef __USE_MALLOC +template <class _Tp, class _Tp1, bool __thr, int __inst> +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; +}; +#endif + +template <class _Tp, class _Tp1, class _Alloc> +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: diff --git a/libstdc++-v3/include/bits/stl_config.h b/libstdc++-v3/include/bits/stl_config.h new file mode 100644 index 00000000000..8a6e15c25de --- /dev/null +++ b/libstdc++-v3/include/bits/stl_config.h @@ -0,0 +1,568 @@ +/* + * + * 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 <exception>. +// * __STL_NO_BAD_ALLOC: defined if the compiler does not have a <new> +// header, or if <new> 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 <iosfwd> header). If not +// defined, the STL will use old cfront-style iostreams (e.g. the +// <iostream.h> 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 <standards.h> +# 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__ +# define __STL_HAS_WCHAR_T +# define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# define __STL_TEMPLATE_FRIENDS +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_PARTIAL_SPECIALIZATION_SYNTAX +# define __STL_FUNCTION_TMPL_PARTIAL_ORDER +# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS +# define __SGI_STL_USE_AUTO_PTR_CONVERSIONS +# define __STL_HAS_NAMESPACES +# define __STL_USE_NAMESPACES +# define __STL_USE_EXCEPTIONS +# define __STL_THROW_RANGE_ERRORS +# define __STL_CAN_THROW_RANGE_ERRORS +# define __STL_USE_STD_ALLOCATORS +# define __USE_MALLOC // As the "underlying allocator" +//# define __STL_USE_NEW_IOSTREAMS //990209 bkoz--use standard .h includes. +# ifdef _REENTRANT +# define __STL_THREADS +# endif +# ifdef _PTHREADS +# define __STL_PTHREADS +# endif +# ifndef __STRICT_ANSI__ +# define __STL_LONG_LONG +# 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 <yvals.h> +# 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 <stdio.h> +# 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: diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h new file mode 100644 index 00000000000..7841f8dc75e --- /dev/null +++ b/libstdc++-v3/include/bits/stl_construct.h @@ -0,0 +1,124 @@ +/* + * + * 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 _CPP_BITS_STL_CONSTRUCT_H +#define _CPP_BITS_STL_CONSTRUCT_H 1 + +#include <bits/std_new.h> + +__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 <class _T1, class _T2> +inline void _Construct(_T1* __p, const _T2& __value) { +new ((void*) __p) _T1(__value); +} + +template <class _T1> +inline void _Construct(_T1* __p) { + new ((void*) __p) _T1(); +} + +template <class _Tp> +inline void _Destroy(_Tp* __pointer) { + __pointer->~_Tp(); +} + +template <class _ForwardIterator> +void +__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type) +{ + for ( ; __first != __last; ++__first) + destroy(&*__first); +} + +template <class _ForwardIterator> +inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {} + +template <class _ForwardIterator, class _Tp> +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 <class _ForwardIterator> +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 <class _T1, class _T2> +inline void construct(_T1* __p, const _T2& __value) { + _Construct(__p, __value); +} + +template <class _T1> +inline void construct(_T1* __p) { + _Construct(__p); +} + +template <class _Tp> +inline void destroy(_Tp* __pointer) { + _Destroy(__pointer); +} + +template <class _ForwardIterator> +inline void destroy(_ForwardIterator __first, _ForwardIterator __last) { + _Destroy(__first, __last); +} + +__STL_END_NAMESPACE + +#endif /* _CPP_BITS_STL_CONSTRUCT_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h new file mode 100644 index 00000000000..0ad596eb3b9 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -0,0 +1,1652 @@ +/* + * + * 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 <bits/concept_checks.h> + +#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 <class _Tp, class _Ref, class _Ptr> +struct _Deque_iterator { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); } + + typedef 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 <class _Tp, class _Ref, class _Ptr> +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 <class _Tp, class _Ref, class _Ptr> +inline random_access_iterator_tag +iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr>&) +{ + return random_access_iterator_tag(); +} + +template <class _Tp, class _Ref, class _Ptr> +inline _Tp* value_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; } + +template <class _Tp, class _Ref, class _Ptr> +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 _Tp, class _Alloc, bool __is_static> +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 _Tp, class _Alloc> +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 _Tp, class _Alloc> +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 _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +_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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +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_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<const_iterator, value_type, const_reference, + difference_type> + const_reverse_iterator; + typedef reverse_iterator<iterator, value_type, reference, difference_type> + 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 <class _InputIterator> + 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 <class _Integer> + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_initialize_map(__n); + _M_fill_initialize(__x); + } + + template <class _InputIter> + 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 <class _InputIterator> + 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 <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template <class _InputIterator> + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); + } + + template <class _InputIterator> + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template <class _ForwardIterator> + 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 <class _InputIterator> + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + + template <class _Integer> + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + _M_fill_insert(__pos, (size_type) __n, (value_type) __x); + } + + template <class _InputIterator> + 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; + size_type __index = __pos - _M_start; + if (__index < (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 <class _InputIterator> + void _M_range_initialize(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template <class _ForwardIterator> + 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 <class _InputIterator> + void insert(iterator __pos, _InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template <class _ForwardIterator> + 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 <class _ForwardIterator> + 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 <class _Tp, class _Alloc> +template <class _InputIter> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 (static_cast<size_type>(__elems_before) < (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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> template <class _InputIterator> +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 <class _Tp, class _Alloc> template <class _ForwardIterator> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> template <class _InputIterator> +void deque<_Tp,_Alloc>::insert(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) +{ + copy(__first, __last, inserter(*this, __pos)); +} + +template <class _Tp, class _Alloc> template <class _ForwardIterator> +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 <class _Tp, class _Alloc> +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 (static_cast<size_type>(__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 = __x_copy; + return __pos; +} + +template <class _Tp, class _Alloc> +typename deque<_Tp,_Alloc>::iterator +deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos) +{ + difference_type __index = __pos - _M_start; + if (static_cast<size_type>(__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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> template <class _ForwardIterator> +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 (static_cast<size_type>(__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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +inline bool operator!=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return !(__x == __y); +} + +template <class _Tp, class _Alloc> +inline bool operator>(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return __y < __x; +} + +template <class _Tp, class _Alloc> +inline bool operator<=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return !(__y < __x); +} +template <class _Tp, class _Alloc> +inline bool operator>=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) { + return !(__x < __y); +} + +template <class _Tp, class _Alloc> +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: diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h new file mode 100644 index 00000000000..fcaafac5668 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_function.h @@ -0,0 +1,732 @@ +/* + * + * 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 <class _Arg, class _Result> +struct unary_function { + typedef _Arg argument_type; + typedef _Result result_type; +}; + +template <class _Arg1, class _Arg2, class _Result> +struct binary_function { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; +}; + +template <class _Tp> +struct plus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } +}; + +template <class _Tp> +struct minus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } +}; + +template <class _Tp> +struct multiplies : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } +}; + +template <class _Tp> +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 <class _Tp> inline _Tp identity_element(plus<_Tp>) { + return _Tp(0); +} +template <class _Tp> inline _Tp identity_element(multiplies<_Tp>) { + return _Tp(1); +} + +template <class _Tp> +struct modulus : public binary_function<_Tp,_Tp,_Tp> +{ + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } +}; + +template <class _Tp> +struct negate : public unary_function<_Tp,_Tp> +{ + _Tp operator()(const _Tp& __x) const { return -__x; } +}; + +template <class _Tp> +struct equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } +}; + +template <class _Tp> +struct not_equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } +}; + +template <class _Tp> +struct greater : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } +}; + +template <class _Tp> +struct less : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } +}; + +template <class _Tp> +struct greater_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } +}; + +template <class _Tp> +struct less_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } +}; + +template <class _Tp> +struct logical_and : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } +}; + +template <class _Tp> +struct logical_or : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } +}; + +template <class _Tp> +struct logical_not : public unary_function<_Tp,bool> +{ + bool operator()(const _Tp& __x) const { return !__x; } +}; + +template <class _Predicate> +class unary_negate + : public unary_function<typename _Predicate::argument_type, bool> { +protected: + _Predicate _M_pred; +public: + explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::argument_type& __x) const { + return !_M_pred(__x); + } +}; + +template <class _Predicate> +inline unary_negate<_Predicate> +not1(const _Predicate& __pred) +{ + return unary_negate<_Predicate>(__pred); +} + +template <class _Predicate> +class binary_negate + : public binary_function<typename _Predicate::first_argument_type, + typename _Predicate::second_argument_type, + bool> { +protected: + _Predicate _M_pred; +public: + explicit binary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { + return !_M_pred(__x, __y); + } +}; + +template <class _Predicate> +inline binary_negate<_Predicate> +not2(const _Predicate& __pred) +{ + return binary_negate<_Predicate>(__pred); +} + +template <class _Operation> +class binder1st + : public unary_function<typename _Operation::second_argument_type, + typename _Operation::result_type> { +protected: + _Operation op; + typename _Operation::first_argument_type value; +public: + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const { + return op(value, __x); + } +}; + +template <class _Operation, class _Tp> +inline binder1st<_Operation> +bind1st(const _Operation& __fn, const _Tp& __x) +{ + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__fn, _Arg1_type(__x)); +} + +template <class _Operation> +class binder2nd + : public unary_function<typename _Operation::first_argument_type, + typename _Operation::result_type> { +protected: + _Operation op; + typename _Operation::second_argument_type value; +public: + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const { + return op(__x, value); + } +}; + +template <class _Operation, class _Tp> +inline binder2nd<_Operation> +bind2nd(const _Operation& __fn, const _Tp& __x) +{ + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__fn, _Arg2_type(__x)); +} + +// unary_compose and binary_compose (extensions, not part of the standard). + +template <class _Operation1, class _Operation2> +class unary_compose + : public unary_function<typename _Operation2::argument_type, + typename _Operation1::result_type> +{ +protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; +public: + unary_compose(const _Operation1& __x, const _Operation2& __y) + : _M_fn1(__x), _M_fn2(__y) {} + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return _M_fn1(_M_fn2(__x)); + } +}; + +template <class _Operation1, class _Operation2> +inline unary_compose<_Operation1,_Operation2> +compose1(const _Operation1& __fn1, const _Operation2& __fn2) +{ + return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); +} + +template <class _Operation1, class _Operation2, class _Operation3> +class binary_compose + : public unary_function<typename _Operation2::argument_type, + typename _Operation1::result_type> { +protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; + _Operation3 _M_fn3; +public: + binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) + : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return _M_fn1(_M_fn2(__x), _M_fn3(__x)); + } +}; + +template <class _Operation1, class _Operation2, class _Operation3> +inline binary_compose<_Operation1, _Operation2, _Operation3> +compose2(const _Operation1& __fn1, const _Operation2& __fn2, + const _Operation3& __fn3) +{ + return binary_compose<_Operation1,_Operation2,_Operation3> + (__fn1, __fn2, __fn3); +} + +template <class _Arg, class _Result> +class pointer_to_unary_function : public unary_function<_Arg, _Result> { +protected: + _Result (*_M_ptr)(_Arg); +public: + pointer_to_unary_function() {} + explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {} + _Result operator()(_Arg __x) const { return _M_ptr(__x); } +}; + +template <class _Arg, class _Result> +inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) +{ + return pointer_to_unary_function<_Arg, _Result>(__x); +} + +template <class _Arg1, class _Arg2, class _Result> +class pointer_to_binary_function : + public binary_function<_Arg1,_Arg2,_Result> { +protected: + _Result (*_M_ptr)(_Arg1, _Arg2); +public: + pointer_to_binary_function() {} + explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) {} + _Result operator()(_Arg1 __x, _Arg2 __y) const { + return _M_ptr(__x, __y); + } +}; + +template <class _Arg1, class _Arg2, class _Result> +inline pointer_to_binary_function<_Arg1,_Arg2,_Result> +ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { + return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__x); +} + +// identity is an extensions: it is not part of the standard. +template <class _Tp> +struct _Identity : public unary_function<_Tp,_Tp> { + _Tp& operator()(_Tp& __x) const { return __x; } + const _Tp& operator()(const _Tp& __x) const { return __x; } +}; + +template <class _Tp> struct identity : public _Identity<_Tp> {}; + +// select1st and select2nd are extensions: they are not part of the standard. +template <class _Pair> +struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { + typename _Pair::first_type& operator()(_Pair& __x) const { + return __x.first; + } + const typename _Pair::first_type& operator()(const _Pair& __x) const { + return __x.first; + } +}; + +template <class _Pair> +struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> +{ + typename _Pair::second_type& operator()(_Pair& __x) const { + return __x.second; + } + const typename _Pair::second_type& operator()(const _Pair& __x) const { + return __x.second; + } +}; + +template <class _Pair> struct select1st : public _Select1st<_Pair> {}; +template <class _Pair> struct select2nd : public _Select2nd<_Pair> {}; + +// project1st and project2nd are extensions: they are not part of the standard +template <class _Arg1, class _Arg2> +struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { + _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } +}; + +template <class _Arg1, class _Arg2> +struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { + _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } +}; + +template <class _Arg1, class _Arg2> +struct project1st : public _Project1st<_Arg1, _Arg2> {}; + +template <class _Arg1, class _Arg2> +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 <class _Result> +struct _Constant_void_fun { + typedef _Result result_type; + result_type _M_val; + + _Constant_void_fun(const result_type& __v) : _M_val(__v) {} + const result_type& operator()() const { return _M_val; } +}; + +template <class _Result, class _Argument> +struct _Constant_unary_fun { + typedef _Argument argument_type; + typedef _Result result_type; + result_type _M_val; + + _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} + const result_type& operator()(const _Argument&) const { return _M_val; } +}; + +template <class _Result, class _Arg1, class _Arg2> +struct _Constant_binary_fun { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; + _Result _M_val; + + _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} + const result_type& operator()(const _Arg1&, const _Arg2&) const { + return _M_val; + } +}; + +template <class _Result> +struct constant_void_fun : public _Constant_void_fun<_Result> { + constant_void_fun(const _Result& __v) : _Constant_void_fun<_Result>(__v) {} +}; + + +template <class _Result, + class _Argument = _Result> +struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> +{ + constant_unary_fun(const _Result& __v) + : _Constant_unary_fun<_Result, _Argument>(__v) {} +}; + + +template <class _Result, + class _Arg1 = _Result, + class _Arg2 = _Arg1> +struct constant_binary_fun + : public _Constant_binary_fun<_Result, _Arg1, _Arg2> +{ + constant_binary_fun(const _Result& __v) + : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} +}; + +template <class _Result> +inline constant_void_fun<_Result> constant0(const _Result& __val) +{ + return constant_void_fun<_Result>(__val); +} + +template <class _Result> +inline constant_unary_fun<_Result,_Result> constant1(const _Result& __val) +{ + return constant_unary_fun<_Result,_Result>(__val); +} + +template <class _Result> +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<unsigned int, unsigned int> { +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 _Ret, class _Tp> +class mem_fun_t : public unary_function<_Tp*,_Ret> { +public: + explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } +private: + _Ret (_Tp::*_M_f)(); +}; + +template <class _Ret, class _Tp> +class const_mem_fun_t : public unary_function<const _Tp*,_Ret> { +public: + explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } +private: + _Ret (_Tp::*_M_f)() const; +}; + + +template <class _Ret, class _Tp> +class mem_fun_ref_t : public unary_function<_Tp,_Ret> { +public: + explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } +private: + _Ret (_Tp::*_M_f)(); +}; + +template <class _Ret, class _Tp> +class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> { +public: + explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } +private: + _Ret (_Tp::*_M_f)() const; +}; + +template <class _Ret, class _Tp, class _Arg> +class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> { +public: + explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg); +}; + +template <class _Ret, class _Tp, class _Arg> +class const_mem_fun1_t : public binary_function<const _Tp*,_Arg,_Ret> { +public: + explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg) const; +}; + +template <class _Ret, class _Tp, class _Arg> +class mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { +public: + explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg); +}; + +template <class _Ret, class _Tp, class _Arg> +class const_mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { +public: + explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg) const; +}; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class _Tp> +class mem_fun_t<void, _Tp> : 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 _Tp> +class const_mem_fun_t<void, _Tp> : public unary_function<const _Tp*,void> { +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 _Tp> +class mem_fun_ref_t<void, _Tp> : 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 _Tp> +class const_mem_fun_ref_t<void, _Tp> : 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 _Tp, class _Arg> +class mem_fun1_t<void, _Tp, _Arg> : 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 _Tp, class _Arg> +class const_mem_fun1_t<void, _Tp, _Arg> + : public binary_function<const _Tp*,_Arg,void> { +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 _Tp, class _Arg> +class mem_fun1_ref_t<void, _Tp, _Arg> + : 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 _Tp, class _Arg> +class const_mem_fun1_ref_t<void, _Tp, _Arg> + : 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 <class _Ret, class _Tp> +inline mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret,_Tp>(__f); } + +template <class _Ret, class _Tp> +inline const_mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret,_Tp>(__f); } + +template <class _Ret, class _Tp> +inline mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret,_Tp>(__f); } + +template <class _Ret, class _Tp> +inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret,_Tp>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h new file mode 100644 index 00000000000..3e7eaa456e5 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_heap.h @@ -0,0 +1,297 @@ +/* + * + * 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 _CPP_BITS_STL_HEAP_H +#define _CPP_BITS_STL_HEAP_H 1 + +__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 <class _RandomAccessIterator, class _Distance, class _Tp> +void +__push_heap(_RandomAccessIterator __first, + _Distance __holeIndex, _Distance __topIndex, _Tp __value) +{ + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && *(__first + __parent) < __value) { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; +} + +template <class _RandomAccessIterator, class _Distance, class _Tp> +inline void +__push_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Distance*, _Tp*) +{ + __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), + _Tp(*(__last - 1))); +} + +template <class _RandomAccessIterator> +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 <class _RandomAccessIterator, class _Distance, class _Tp, + class _Compare> +void +__push_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __topIndex, _Tp __value, _Compare __comp) +{ + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; +} + +template <class _RandomAccessIterator, class _Compare, + class _Distance, class _Tp> +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 <class _RandomAccessIterator, class _Compare> +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 <class _RandomAccessIterator, class _Distance, class _Tp> +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 <class _RandomAccessIterator, class _Tp, class _Distance> +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 <class _RandomAccessIterator, class _Tp> +inline void +__pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Tp*) +{ + __pop_heap(__first, __last - 1, __last - 1, + _Tp(*(__last - 1)), __DISTANCE_TYPE(__first)); +} + +template <class _RandomAccessIterator> +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 <class _RandomAccessIterator, class _Distance, + class _Tp, class _Compare> +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 <class _RandomAccessIterator, class _Tp, class _Compare, + class _Distance> +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 <class _RandomAccessIterator, class _Tp, class _Compare> +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 <class _RandomAccessIterator, class _Compare> +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 <class _RandomAccessIterator, class _Tp, class _Distance> +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 <class _RandomAccessIterator> +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 <class _RandomAccessIterator, class _Compare, + class _Tp, class _Distance> +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 <class _RandomAccessIterator, class _Compare> +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 <class _RandomAccessIterator> +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 <class _RandomAccessIterator, class _Compare> +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 /* _CPP_BITS_STL_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h new file mode 100644 index 00000000000..ae8b0886653 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -0,0 +1,1086 @@ +/* + * + * 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 _Container> +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 <class _Container> +inline output_iterator_tag +iterator_category(const back_insert_iterator<_Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class _Container> +inline back_insert_iterator<_Container> back_inserter(_Container& __x) { + return back_insert_iterator<_Container>(__x); +} + +template <class _Container> +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 <class _Container> +inline output_iterator_tag +iterator_category(const front_insert_iterator<_Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class _Container> +inline front_insert_iterator<_Container> front_inserter(_Container& __x) { + return front_insert_iterator<_Container>(__x); +} + +template <class _Container> +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 <class _Container> +inline output_iterator_tag +iterator_category(const insert_iterator<_Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class _Container, class _Iterator> +inline +insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) +{ + typedef typename _Container::iterator __iter; + return insert_iterator<_Container>(__x, __iter(__i)); +} + +template <class _BidirectionalIterator, class _Tp, class _Reference = _Tp&, + class _Distance = ptrdiff_t> +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 <class _BidirectionalIterator, class _Tp, class _Reference, + class _Distance> +inline bidirectional_iterator_tag +iterator_category(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, _Reference, + _Distance>&) +{ + return bidirectional_iterator_tag(); +} + +template <class _BidirectionalIterator, class _Tp, class _Reference, + class _Distance> +inline _Tp* +value_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 0; +} + +template <class _BidirectionalIterator, class _Tp, class _Reference, + class _Distance> +inline _Distance* +distance_type(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, + _Reference, _Distance>&) +{ + return (_Distance*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class _BiIter, class _Tp, class _Ref, class _Distance> +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 <class _BiIter, class _Tp, class _Ref, class _Distance> +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 _Iterator> +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 <class _Iter> + 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 <class _Iterator> +inline bool operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __x.base() == __y.base(); +} + +template <class _Iterator> +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 <class _Iterator> +inline bool operator!=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return !(__x == __y); +} + +template <class _Iterator> +inline bool operator>(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __y < __x; +} + +template <class _Iterator> +inline bool operator<=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return !(__y < __x); +} + +template <class _Iterator> +inline bool operator>=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template <class _Iterator> +inline typename reverse_iterator<_Iterator>::difference_type +operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __y.base() - __x.base(); +} + +template <class _Iterator> +inline reverse_iterator<_Iterator> +operator+(typename reverse_iterator<_Iterator>::difference_type __n, + const reverse_iterator<_Iterator>& __x) { + return reverse_iterator<_Iterator>(__x.base() - __n); +} + +#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. + +template <class _RandomAccessIterator, class _Tp, class _Reference = _Tp&, + class _Distance = ptrdiff_t> +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 <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +inline random_access_iterator_tag +iterator_category(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>&) +{ + return random_access_iterator_tag(); +} + +template <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +inline _Tp* value_type(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 0; +} + +template <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +inline _Distance* +distance_type(const reverse_iterator<_RandomAccessIterator, + _Tp, _Reference, _Distance>&) +{ + return (_Distance*) 0; +} + + +template <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +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 <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +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 <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +inline bool +operator!=(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) { + return !(__x == __y); +} + +template <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +inline bool +operator>(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) { + return __y < __x; +} + +template <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +inline bool +operator<=(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) { + return !(__y < __x); +} + +template <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +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 <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +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 <class _RandAccIter, class _Tp, class _Ref, class _Dist> +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 _Tp, + class _CharT = char, class _Traits = char_traits<_CharT>, + 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 <class _Tp, class _CharT, class _Traits, class _Dist> +inline bool +operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { + return __x._M_equal(__y); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Tp, class _CharT, class _Traits, class _Dist> +inline bool +operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { + return !__x._M_equal(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template <class _Tp, + class _CharT = char, class _Traits = char_traits<_CharT> > +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 _CharT, class _Traits> +class istreambuf_iterator + : public iterator<input_iterator_tag, _CharT, + typename _Traits::off_type, _CharT*, _CharT&> +{ +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<class _CharT, class _Traits> +_CharT istreambuf_iterator<_CharT, _Traits>::_M_dereference_aux() const +{ + this->_M_getc(); + return _M_c; +} + +template<class _CharT, class _Traits> +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<class _CharT, class _Traits> +void istreambuf_iterator<_CharT, _Traits>::_M_postincr_aux() +{ + this->_M_getc(); +} + +template<class _CharT, class _Traits> +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<class _CharT, class _Traits> +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 _CharT, class _Traits> +class ostreambuf_iterator + : public iterator<output_iterator_tag, void, void, void, void> +{ +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 _Tp, class _Dist = ptrdiff_t> class istream_iterator; + +template <class _Tp, class _Dist> +inline bool operator==(const istream_iterator<_Tp, _Dist>&, + const istream_iterator<_Tp, _Dist>&); + +template <class _Tp, class _Dist> +class istream_iterator { +#ifdef __STL_TEMPLATE_FRIENDS + template <class _T1, class _D1> + 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 <class _Tp, class _Dist> +inline input_iterator_tag +iterator_category(const istream_iterator<_Tp, _Dist>&) +{ + return input_iterator_tag(); +} + +template <class _Tp, class _Dist> +inline _Tp* +value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; } + +template <class _Tp, class _Dist> +inline _Dist* +distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)0; } + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class _Tp, class _Distance> +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 <class _Tp, class _Distance> +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 _Tp> +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 <class _Tp> +inline output_iterator_tag +iterator_category(const ostream_iterator<_Tp>&) { + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +#endif /* __STL_USE_NEW_IOSTREAMS */ + +// This iterator adapter is 'normal' in the sense that it does not +// change the semantics of any of the operators of its itererator +// parameter. Its primary purpose is to convert an iterator that is +// not a class, e.g. a pointer, into an iterator that is a class. +// The _Container parameter exists solely so that different containers +// using this template can instantiate different types, even if the +// _Iterator parameter is the same. +template<typename _Iterator, typename _Container> +class __normal_iterator + : public iterator<iterator_traits<_Iterator>::iterator_category, + iterator_traits<_Iterator>::value_type, + iterator_traits<_Iterator>::difference_type, + iterator_traits<_Iterator>::pointer, + iterator_traits<_Iterator>::reference> +{ + +protected: + _Iterator _M_current; + +public: + typedef __normal_iterator<_Iterator, _Container> normal_iterator_type; + typedef iterator_traits<_Iterator> __traits_type; + typedef typename __traits_type::iterator_category iterator_category; + typedef typename __traits_type::value_type value_type; + typedef typename __traits_type::difference_type difference_type; + typedef typename __traits_type::pointer pointer; + typedef typename __traits_type::reference reference; + + __normal_iterator() : _M_current(_Iterator()) { } + + explicit __normal_iterator(const _Iterator& __i) : _M_current(__i) { } + + // Allow iterator to const_iterator conversion + template<typename _Iter> + inline __normal_iterator(const __normal_iterator<_Iter, _Container>& __i) + : _M_current(__i.base()) { } + + // Forward iterator requirements + reference + operator*() const { return *_M_current; } + + pointer + operator->() const { return _M_current; } + + normal_iterator_type& + operator++() { ++_M_current; return *this; } + + normal_iterator_type + operator++(int) { return __normal_iterator(_M_current++); } + + // Bidirectional iterator requirements + normal_iterator_type& + operator--() { --_M_current; return *this; } + + normal_iterator_type + operator--(int) { return __normal_iterator(_M_current--); } + + // Random access iterator requirements + reference + operator[](const difference_type& __n) const + { return _M_current[__n]; } + + normal_iterator_type& + operator+=(const difference_type& __n) + { _M_current += __n; return *this; } + + normal_iterator_type + operator+(const difference_type& __n) const + { return __normal_iterator(_M_current + __n); } + + normal_iterator_type& + operator-=(const difference_type& __n) + { _M_current -= __n; return *this; } + + normal_iterator_type + operator-(const difference_type& __n) const + { return __normal_iterator(_M_current - __n); } + + difference_type + operator-(const normal_iterator_type& __i) const + { return _M_current - __i._M_current; } + + const _Iterator& + base() const { return _M_current; } +}; + +// forward iterator requirements + +template<typename _IteratorL, typename _IteratorR, typename _Container> +inline bool +operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) +{ return __lhs.base() == __rhs.base(); } + +template<typename _IteratorL, typename _IteratorR, typename _Container> +inline bool +operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) +{ return !(__lhs == __rhs); } + +// random access iterator requirements + +template<typename _IteratorL, typename _IteratorR, typename _Container> +inline bool +operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) +{ return __lhs.base() < __rhs.base(); } + +template<typename _IteratorL, typename _IteratorR, typename _Container> +inline bool +operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) +{ return __rhs < __lhs; } + +template<typename _IteratorL, typename _IteratorR, typename _Container> +inline bool +operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) +{ return !(__rhs < __lhs); } + +template<typename _IteratorL, typename _IteratorR, typename _Container> +inline bool +operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) +{ return !(__lhs < __rhs); } + +template<typename _Iterator, typename _Container> +inline __normal_iterator<_Iterator, _Container> +operator+(__normal_iterator<_Iterator, _Container>::difference_type __n, + const __normal_iterator<_Iterator, _Container>& __i) +{ return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_iterator_base.h b/libstdc++-v3/include/bits/stl_iterator_base.h new file mode 100644 index 00000000000..44a6f8fbfb0 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_iterator_base.h @@ -0,0 +1,367 @@ +/* + * + * 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 <bits/concept_checks.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 {}; + +// 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 <class _Tp, class _Distance> struct input_iterator { + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +struct output_iterator { + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; +}; + +template <class _Tp, class _Distance> struct forward_iterator { + typedef forward_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + + +template <class _Tp, class _Distance> struct bidirectional_iterator { + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +template <class _Tp, class _Distance> struct random_access_iterator { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +#ifdef __STL_USE_NAMESPACES +template <class _Category, class _Tp, class _Distance = ptrdiff_t, + class _Pointer = _Tp*, class _Reference = _Tp&> +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 <class _Iterator> +struct iterator_traits { + typedef typename _Iterator::iterator_category iterator_category; + typedef typename _Iterator::value_type value_type; + typedef typename _Iterator::difference_type difference_type; + typedef typename _Iterator::pointer pointer; + typedef typename _Iterator::reference reference; +}; + +template <class _Tp> +struct iterator_traits<_Tp*> { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +template <class _Tp> +struct iterator_traits<const _Tp*> { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; +}; + +// 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 <class _Iter> +inline typename iterator_traits<_Iter>::iterator_category +__iterator_category(const _Iter&) +{ + typedef typename iterator_traits<_Iter>::iterator_category _Category; + return _Category(); +} + +template <class _Iter> +inline typename iterator_traits<_Iter>::difference_type* +__distance_type(const _Iter&) +{ + return static_cast<typename iterator_traits<_Iter>::difference_type*>(0); +} + +template <class _Iter> +inline typename iterator_traits<_Iter>::value_type* +__value_type(const _Iter&) +{ + return static_cast<typename iterator_traits<_Iter>::value_type*>(0); +} + +template <class _Iter> +inline typename iterator_traits<_Iter>::iterator_category +iterator_category(const _Iter& __i) { return __iterator_category(__i); } + + +template <class _Iter> +inline typename iterator_traits<_Iter>::difference_type* +distance_type(const _Iter& __i) { return __distance_type(__i); } + +template <class _Iter> +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 <class _Tp, class _Distance> +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 <class _Tp, class _Distance> +inline forward_iterator_tag +iterator_category(const forward_iterator<_Tp, _Distance>&) + { return forward_iterator_tag(); } + +template <class _Tp, class _Distance> +inline bidirectional_iterator_tag +iterator_category(const bidirectional_iterator<_Tp, _Distance>&) + { return bidirectional_iterator_tag(); } + +template <class _Tp, class _Distance> +inline random_access_iterator_tag +iterator_category(const random_access_iterator<_Tp, _Distance>&) + { return random_access_iterator_tag(); } + +template <class _Tp> +inline random_access_iterator_tag iterator_category(const _Tp*) + { return random_access_iterator_tag(); } + +template <class _Tp, class _Distance> +inline _Tp* value_type(const input_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template <class _Tp, class _Distance> +inline _Tp* value_type(const forward_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template <class _Tp, class _Distance> +inline _Tp* value_type(const bidirectional_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template <class _Tp, class _Distance> +inline _Tp* value_type(const random_access_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template <class _Tp> +inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); } + +template <class _Tp, class _Distance> +inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template <class _Tp, class _Distance> +inline _Distance* distance_type(const forward_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template <class _Tp, class _Distance> +inline _Distance* +distance_type(const bidirectional_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template <class _Tp, class _Distance> +inline _Distance* +distance_type(const random_access_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template <class _Tp> +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 <class _InputIterator, class _Distance> +inline void __distance(_InputIterator __first, _InputIterator __last, + _Distance& __n, input_iterator_tag) +{ + while (__first != __last) { ++__first; ++__n; } +} + +template <class _RandomAccessIterator, class _Distance> +inline void __distance(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance& __n, random_access_iterator_tag) +{ + __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); + __n += __last - __first; +} + +template <class _InputIterator, class _Distance> +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 <class _InputIterator> +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 <class _RandomAccessIterator> +inline typename iterator_traits<_RandomAccessIterator>::difference_type +__distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) { + __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); + return __last - __first; +} + +template <class _InputIterator> +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 <class _InputIter, class _Distance> +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 <class _BidirectionalIterator, class _Distance> +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 <class _RandomAccessIterator, class _Distance> +inline void __advance(_RandomAccessIterator& __i, _Distance __n, + random_access_iterator_tag) { + __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); + __i += __n; +} + +template <class _InputIterator, class _Distance> +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: diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h new file mode 100644 index 00000000000..1967a7a933d --- /dev/null +++ b/libstdc++-v3/include/bits/stl_list.h @@ -0,0 +1,885 @@ +/* + * + * 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 <bits/concept_checks.h> + +__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 <class _Tp> +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<class _Tp, class _Ref, class _Ptr> +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 <class _Tp, class _Ref, class _Ptr> +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 _Tp, class _Allocator, bool _IsStatic> +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 _Tp, class _Allocator> +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 _Tp, class _Alloc> +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 _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 _Tp, class _Alloc = allocator<_Tp> > +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_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_bidirectional_iterator<const_iterator,value_type, + const_reference,difference_type> + const_reverse_iterator; + typedef reverse_bidirectional_iterator<iterator,value_type,reference, + difference_type> + 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<class _Integer> + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + _M_fill_insert(__pos, (size_type) __n, (_Tp) __x); + } + + template <class _InputIterator> + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type); + + template <class _InputIterator> + 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 <class _InputIterator> + 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 <class _InputIterator> + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template <class _InputIterator> + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + +#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 <class _Predicate> void remove_if(_Predicate); + template <class _BinaryPredicate> void unique(_BinaryPredicate); + template <class _StrictWeakOrdering> void merge(list&, _StrictWeakOrdering); + template <class _StrictWeakOrdering> void sort(_StrictWeakOrdering); +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template <class _Tp, class _Alloc> +inline bool +operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) +{ + typedef typename list<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = __x.end(); + const_iterator __end2 = __y.end(); + + const_iterator __i1 = __x.begin(); + const_iterator __i2 = __y.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; +} + +template <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +inline bool operator!=(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _Tp, class _Alloc> +inline bool operator>(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) { + return __y < __x; +} + +template <class _Tp, class _Alloc> +inline bool operator<=(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _Tp, class _Alloc> +inline bool operator>=(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) { + return !(__x < __y); +} + +template <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> template <class _InputIter> +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 <class _Tp, class _Alloc> +void +list<_Tp, _Alloc>::insert(iterator __position, + const _Tp* __first, const _Tp* __last) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); +} + +template <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +void +list<_Tp, _Alloc>::_M_fill_insert(iterator __position, + size_type __n, const _Tp& __x) +{ + for ( ; __n > 0; --__n) + insert(__position, __x); +} + +template <class _Tp, class _Alloc> +typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first, + iterator __last) +{ + while (__first != __last) + erase(__first++); + return __last; +} + +template <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> template <class _InputIter> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +void list<_Tp, _Alloc>::unique() +{ + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) { + if (*__first == *__next) + erase(__next); + else + __first = __next; + __next = __first; + } +} + +template <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +inline void list<_Tp, _Alloc>::reverse() +{ + __List_base_reverse(this->_M_node); +} + +template <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> template <class _Predicate> +void list<_Tp, _Alloc>::remove_if(_Predicate __pred) +{ + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) { + iterator __next = __first; + ++__next; + if (__pred(*__first)) erase(__first); + __first = __next; + } +} + +template <class _Tp, class _Alloc> template <class _BinaryPredicate> +void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) +{ + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) { + if (__binary_pred(*__first, *__next)) + erase(__next); + else + __first = __next; + __next = __first; + } +} + +template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> +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 <class _Tp, class _Alloc> template <class _StrictWeakOrdering> +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: diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h new file mode 100644 index 00000000000..0b7a06d4b8b --- /dev/null +++ b/libstdc++-v3/include/bits/stl_map.h @@ -0,0 +1,282 @@ +/* + * + * 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 _CPP_BITS_STL_MAP_H +#define _CPP_BITS_STL_MAP_H 1 + +#include <bits/concept_checks.h> + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +template <class _Key, class _Tp, class _Compare = less<_Key>, + class _Alloc = allocator<pair<const _Key, _Tp> > > +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<const _Key, _Tp> value_type; + typedef _Compare key_compare; + + class value_compare + : public binary_function<value_type, value_type, bool> { + friend class map<_Key,_Tp,_Compare,_Alloc>; + protected : + _Compare comp; + value_compare(_Compare __c) : comp(__c) {} + public: + bool operator()(const value_type& __x, const value_type& __y) const { + return comp(__x.first, __y.first); + } + }; + +private: + typedef _Rb_tree<key_type, value_type, + _Select1st<value_type>, 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 <class _InputIterator> + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template <class _InputIterator> + 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<iterator,bool> 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 <class _InputIterator> + 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<iterator,iterator> equal_range(const key_type& __x) { + return _M_t.equal_range(__x); + } + pair<const_iterator,const_iterator> equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + +#ifdef __STL_TEMPLATE_FRIENDS + template <class _K1, class _T1, class _C1, class _A1> + friend bool operator== (const map<_K1, _T1, _C1, _A1>&, + const map<_K1, _T1, _C1, _A1>&); + template <class _K1, class _T1, class _C1, class _A1> + 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 <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __y < __x; +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__x < __y); +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +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 /* _CPP_BITS_STL_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h new file mode 100644 index 00000000000..1c5401b378a --- /dev/null +++ b/libstdc++-v3/include/bits/stl_multimap.h @@ -0,0 +1,282 @@ +/* + * + * 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 <bits/concept_checks.h> + +__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 _Key, class _Tp, + class _Compare = less<_Key>, + class _Alloc = allocator<pair<const _Key, _Tp> > > +class multimap; + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + +template <class _Key, class _Tp, class _Compare, class _Alloc> +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<const _Key, _Tp> value_type; + typedef _Compare key_compare; + + class value_compare : public binary_function<value_type, value_type, bool> { + friend class multimap<_Key,_Tp,_Compare,_Alloc>; + protected: + _Compare comp; + value_compare(_Compare __c) : comp(__c) {} + public: + bool operator()(const value_type& __x, const value_type& __y) const { + return comp(__x.first, __y.first); + } + }; + +private: + typedef _Rb_tree<key_type, value_type, + _Select1st<value_type>, 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 <class _InputIterator> + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template <class _InputIterator> + 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 <class _InputIterator> + 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<iterator,iterator> equal_range(const key_type& __x) { + return _M_t.equal_range(__x); + } + pair<const_iterator,const_iterator> equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + +#ifdef __STL_TEMPLATE_FRIENDS + template <class _K1, class _T1, class _C1, class _A1> + friend bool operator== (const multimap<_K1, _T1, _C1, _A1>&, + const multimap<_K1, _T1, _C1, _A1>&); + template <class _K1, class _T1, class _C1, class _A1> + 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 <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __y < __x; +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline bool operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return !(__x < __y); +} + +template <class _Key, class _Tp, class _Compare, class _Alloc> +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: diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h new file mode 100644 index 00000000000..7e75ec3cd0a --- /dev/null +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -0,0 +1,274 @@ +/* + * + * 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 <bits/concept_checks.h> + +__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 _Key, class _Compare = less<_Key>, + class _Alloc = allocator<_Key> > +class multiset; + +template <class _Key, class _Compare, class _Alloc> +inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + +template <class _Key, class _Compare, class _Alloc> +inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + +template <class _Key, class _Compare, class _Alloc> +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_type, value_type, + _Identity<value_type>, 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 <class _InputIterator> + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template <class _InputIterator> + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.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 <class _InputIterator> + 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<iterator,iterator> equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + +#ifdef __STL_TEMPLATE_FRIENDS + template <class _K1, class _C1, class _A1> + friend bool operator== (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); + template <class _K1, class _C1, class _A1> + friend bool operator< (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); +#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 <class _Key, class _Compare, class _Alloc> +inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template <class _Key, class _Compare, class _Alloc> +inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Key, class _Compare, class _Alloc> +inline bool operator!=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _Key, class _Compare, class _Alloc> +inline bool operator>(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __y < __x; +} + +template <class _Key, class _Compare, class _Alloc> +inline bool operator<=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _Key, class _Compare, class _Alloc> +inline bool operator>=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return !(__x < __y); +} + +template <class _Key, class _Compare, class _Alloc> +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: diff --git a/libstdc++-v3/include/bits/stl_numeric.h b/libstdc++-v3/include/bits/stl_numeric.h new file mode 100644 index 00000000000..0b1742bc9d9 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_numeric.h @@ -0,0 +1,255 @@ +/* + * + * 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 _CPP_BITS_STL_NUMERIC_H +#define _CPP_BITS_STL_NUMERIC_H 1 + +__STL_BEGIN_NAMESPACE + +template <class _InputIterator, class _Tp> +_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) +{ + __STL_REQUIRES(_InputIterator, _InputIterator); + for ( ; __first != __last; ++__first) + __init = __init + *__first; + return __init; +} + +template <class _InputIterator, class _Tp, class _BinaryOperation> +_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 <class _InputIterator1, class _InputIterator2, class _Tp> +_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 <class _InputIterator1, class _InputIterator2, class _Tp, + class _BinaryOperation1, class _BinaryOperation2> +_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 <class _InputIterator, class _OutputIterator, class _Tp> +_OutputIterator +__partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*) +{ + _Tp __value = *__first; + while (++__first != __last) { + __value = __value + *__first; + *++__result = __value; + } + return ++__result; +} + +template <class _InputIterator, class _OutputIterator> +_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 <class _InputIterator, class _OutputIterator, class _Tp, + class _BinaryOperation> +_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 <class _InputIterator, class _OutputIterator, class _BinaryOperation> +_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 <class _InputIterator, class _OutputIterator, class _Tp> +_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 <class _InputIterator, class _OutputIterator> +_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 <class _InputIterator, class _OutputIterator, class _Tp, + class _BinaryOperation> +_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 <class _InputIterator, class _OutputIterator, class _BinaryOperation> +_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 <class _Tp, class _Integer, class _MonoidOperation> +_Tp __power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) +{ + if (__n == 0) + return identity_element(__monoid_op); + else { + while ((__n & 1) == 0) { + __n >>= 1; + __x = __monoid_op(__x, __x); + } + + _Tp __result = __x; + __n >>= 1; + while (__n != 0) { + __x = __monoid_op(__x, __x); + if ((__n & 1) != 0) + __result = __monoid_op(__result, __x); + __n >>= 1; + } + return __result; + } +} + +template <class _Tp, class _Integer> +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 <class _Tp, class _Integer, class _MonoidOperation> +inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) +{ + return __power(__x, __n, __monoid_op); +} + +template <class _Tp, class _Integer> +inline _Tp power(_Tp __x, _Integer __n) +{ + return __power(__x, __n); +} + +// iota is not part of the C++ standard. It is an extension. + +template <class _ForwardIter, class _Tp> +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 /* _CPP_BITS_STL_NUMERIC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h new file mode 100644 index 00000000000..a6155a698e1 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -0,0 +1,101 @@ +/* + * + * 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 <class _T1, class _T2> +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 <class _U1, class _U2> + pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} +#endif +}; + +template <class _T1, class _T2> +inline bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) +{ + return __x.first == __y.first && __x.second == __y.second; +} + +template <class _T1, class _T2> +inline bool operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) +{ + return __x.first < __y.first || + (!(__y.first < __x.first) && __x.second < __y.second); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _T1, class _T2> +inline bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return !(__x == __y); +} + +template <class _T1, class _T2> +inline bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return __y < __x; +} + +template <class _T1, class _T2> +inline bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return !(__y < __x); +} + +template <class _T1, class _T2> +inline bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template <class _T1, class _T2> +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: diff --git a/libstdc++-v3/include/bits/stl_pthread_alloc.h b/libstdc++-v3/include/bits/stl_pthread_alloc.h new file mode 100644 index 00000000000..c1488b1ef6a --- /dev/null +++ b/libstdc++-v3/include/bits/stl_pthread_alloc.h @@ -0,0 +1,31 @@ +/* + * 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 _CPP_BITS_STL_PTHREAD_ALLOC_H +#define _CPP_BITS_STL_PTHREAD_ALLOC_H 1 + +#include <bits/pthread_allocimpl.h> + +#ifdef __STL_USE_NAMESPACES + +using __STD::_Pthread_alloc_template; +using __STD::pthread_alloc; + +#endif /* __STL_USE_NAMESPACES */ + + +#endif /* _CPP_BITS_STL_PTHREAD_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h new file mode 100644 index 00000000000..e42666e5662 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_queue.h @@ -0,0 +1,242 @@ +/* + * + * 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 <bits/sequence_concepts.h> + +__STL_BEGIN_NAMESPACE + +// Forward declarations of operators < and ==, needed for friend declaration. + +template <class _Tp, + class _Sequence = deque<_Tp> > +class queue; + +template <class _Tp, class _Seq> +inline bool operator==(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&); + +template <class _Tp, class _Seq> +inline bool operator<(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&); + + +template <class _Tp, class _Sequence> +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 <class _Tp1, class _Seq1> + friend bool operator== (const queue<_Tp1, _Seq1>&, + const queue<_Tp1, _Seq1>&); + template <class _Tp1, class _Seq1> + 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 <class _Tp, class _Sequence> +bool +operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x.c == __y.c; +} + +template <class _Tp, class _Sequence> +bool +operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x.c < __y.c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Tp, class _Sequence> +bool +operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x == __y); +} + +template <class _Tp, class _Sequence> +bool +operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __y < __x; +} + +template <class _Tp, class _Sequence> +bool +operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__y < __x); +} + +template <class _Tp, class _Sequence> +bool +operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template <class _Tp, + class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(vector<_Tp>), + class _Compare + __STL_DEPENDENT_DEFAULT_TMPL(less<typename _Sequence::value_type>) > +class priority_queue { +public: + + // 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); + + 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 <class _InputIterator> + priority_queue(_InputIterator __first, _InputIterator __last) + : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } + + template <class _InputIterator> + priority_queue(_InputIterator __first, + _InputIterator __last, const _Compare& __x) + : c(__first, __last), comp(__x) + { make_heap(c.begin(), c.end(), comp); } + + template <class _InputIterator> + 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: diff --git a/libstdc++-v3/include/bits/stl_range_errors.h b/libstdc++-v3/include/bits/stl_range_errors.h new file mode 100644 index 00000000000..c5ddfe63cbb --- /dev/null +++ b/libstdc++-v3/include/bits/stl_range_errors.h @@ -0,0 +1,74 @@ +/* + * 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 <stdexcept>. 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 <bits/stl_config.h> + +#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) \ + || defined(__GNUC__) && defined(__STL_THROW_RANGE_ERRORS) + +__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 <bits/std_stdexcept.h> + +__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: + + diff --git a/libstdc++-v3/include/bits/stl_raw_storage_iter.h b/libstdc++-v3/include/bits/stl_raw_storage_iter.h new file mode 100644 index 00000000000..007acd032ed --- /dev/null +++ b/libstdc++-v3/include/bits/stl_raw_storage_iter.h @@ -0,0 +1,81 @@ +/* + * + * 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 _CPP_BITS_STL_RAW_STORAGE_ITERATOR_H +#define _CPP_BITS_STL_RAW_STORAGE_ITERATOR_H 1 + +__STL_BEGIN_NAMESPACE + +template <class _ForwardIterator, class _Tp> +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 <class _ForwardIterator, class _Tp> +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 /* _CPP_BITS_STL_RAW_STORAGE_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_relops.h b/libstdc++-v3/include/bits/stl_relops.h new file mode 100644 index 00000000000..f0cabdfd544 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_relops.h @@ -0,0 +1,62 @@ +/* + * + * 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 _CPP_BITS_STL_RELOPS_H +#define _CPP_BITS_STL_RELOPS_H 1 + +__STL_BEGIN_RELOPS_NAMESPACE + +template <class _Tp> +inline bool operator!=(const _Tp& __x, const _Tp& __y) { + return !(__x == __y); +} + +template <class _Tp> +inline bool operator>(const _Tp& __x, const _Tp& __y) { + return __y < __x; +} + +template <class _Tp> +inline bool operator<=(const _Tp& __x, const _Tp& __y) { + return !(__y < __x); +} + +template <class _Tp> +inline bool operator>=(const _Tp& __x, const _Tp& __y) { + return !(__x < __y); +} + +__STL_END_RELOPS_NAMESPACE + +#endif /* _CPP_BITS_STL_RELOPS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h new file mode 100644 index 00000000000..435ca38b16e --- /dev/null +++ b/libstdc++-v3/include/bits/stl_set.h @@ -0,0 +1,268 @@ +/* + * + * 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 <bits/concept_checks.h> + +__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 _Key, class _Compare = less<_Key>, + class _Alloc = allocator<_Key> > +class set; + +template <class _Key, class _Compare, class _Alloc> +inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + +template <class _Key, class _Compare, class _Alloc> +inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + +template <class _Key, class _Compare, class _Alloc> +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_type, value_type, + _Identity<value_type>, 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 <class _InputIterator> + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template <class _InputIterator> + set(_InputIterator __first, _InputIterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.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<iterator,bool> insert(const value_type& __x) { + pair<typename _Rep_type::iterator, bool> __p = _M_t.insert_unique(__x); + return pair<iterator, bool>(__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 <class _InputIterator> + 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<iterator,iterator> equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + +#ifdef __STL_TEMPLATE_FRIENDS + template <class _K1, class _C1, class _A1> + friend bool operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + template <class _K1, class _C1, class _A1> + friend bool operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); +#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 <class _Key, class _Compare, class _Alloc> +inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template <class _Key, class _Compare, class _Alloc> +inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Key, class _Compare, class _Alloc> +inline bool operator!=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _Key, class _Compare, class _Alloc> +inline bool operator>(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __y < __x; +} + +template <class _Key, class _Compare, class _Alloc> +inline bool operator<=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _Key, class _Compare, class _Alloc> +inline bool operator>=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return !(__x < __y); +} + +template <class _Key, class _Compare, class _Alloc> +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: diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h new file mode 100644 index 00000000000..aa80f8730ee --- /dev/null +++ b/libstdc++-v3/include/bits/stl_stack.h @@ -0,0 +1,143 @@ +/* + * + * 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 <bits/sequence_concepts.h> + +__STL_BEGIN_NAMESPACE + +// Forward declarations of operators == and <, needed for friend declaration. + +template <class _Tp, + class _Sequence = deque<_Tp> > +class stack; + +template <class _Tp, class _Seq> +bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + +template <class _Tp, class _Seq> +bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + + +template <class _Tp, class _Sequence> +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 <class _Tp1, class _Seq1> + friend bool operator== (const stack<_Tp1, _Seq1>&, + const stack<_Tp1, _Seq1>&); + template <class _Tp1, class _Seq1> + 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 <class _Tp, class _Seq> +bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x.c == __y.c; +} + +template <class _Tp, class _Seq> +bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x.c < __y.c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Tp, class _Seq> +bool operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__x == __y); +} + +template <class _Tp, class _Seq> +bool operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __y < __x; +} + +template <class _Tp, class _Seq> +bool operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__y < __x); +} + +template <class _Tp, class _Seq> +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: diff --git a/libstdc++-v3/include/bits/stl_string_fwd.h b/libstdc++-v3/include/bits/stl_string_fwd.h new file mode 100644 index 00000000000..46845b9870c --- /dev/null +++ b/libstdc++-v3/include/bits/stl_string_fwd.h @@ -0,0 +1,46 @@ +/* + * 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 <bits/stl_config.h> +#include <bits/stl_alloc.h> +#include <bits/char_traits.h> + +__STL_BEGIN_NAMESPACE + +template <class _CharT, + class _Traits = char_traits<_CharT>, + class _Alloc = allocator<_CharT> > +class basic_string; + +typedef basic_string<char> string; +#ifdef _GLIBCPP_USE_WCHAR_T +typedef basic_string<wchar_t> wstring; +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_STRING_FWD_H */ + +// Local Variables: +// mode:C++ +// End: + + + + + + + diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h new file mode 100644 index 00000000000..cdc0dd27df0 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_tempbuf.h @@ -0,0 +1,161 @@ +/* + * + * 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 <class _Tp> +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 <class _Tp> +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 <class _Tp> +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) { + return __get_temporary_buffer(__len, (_Tp*) 0); +} + +template <class _Tp> +void return_temporary_buffer(_Tp* __p) { + free(__p); +} + +template <class _ForwardIterator, class _Tp> +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 <class _ForwardIterator, + class _Tp +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + = typename iterator_traits<_ForwardIterator>::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: diff --git a/libstdc++-v3/include/bits/stl_threads.h b/libstdc++-v3/include/bits/stl_threads.h new file mode 100644 index 00000000000..5f5b451e3d1 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_threads.h @@ -0,0 +1,379 @@ +/* + * 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 <mutex.h> +#include <time.h> +#elif defined(__STL_PTHREADS) +#include <pthread.h> +#elif defined(__STL_UITHREADS) +#include <thread.h> +#include <synch.h> +#elif defined(__STL_WIN32THREADS) +#include <windows.h> +#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<int __dummy> + struct _Swap_lock_struct { + static pthread_mutex_t _S_swap_lock; + }; + + template<int __dummy> + 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<int __dummy> + struct _Swap_lock_struct { + static mutex_t _S_swap_lock; + }; + + template<int __dummy> + 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<int __dummy> + struct _Swap_lock_struct { + static mutex_t _S_swap_lock; + }; + +# if ( __STL_STATIC_TEMPLATE_DATA > 0 ) + template<int __dummy> + 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 <int __inst> +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 <int __inst> +unsigned _STL_mutex_spin<__inst>::__max = _STL_mutex_spin<__inst>::__low_max; + +template <int __inst> +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: + + + + + diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h new file mode 100644 index 00000000000..1c78fd2aa45 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -0,0 +1,1370 @@ +/* + * + * 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 <bits/stl_algobase.h> +#include <bits/stl_alloc.h> +#include <bits/stl_construct.h> +#include <bits/stl_function.h> + +__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 <class _Value> +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 <class _Value, class _Ref, class _Ptr> +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; + } +}; + +template <class _Value, class _Ref, class _Ptr> +inline bool operator==(const _Rb_tree_iterator<_Value, _Ref, _Ptr>& __x, + const _Rb_tree_iterator<_Value, _Ref, _Ptr>& __y) { + return __x._M_node == __y._M_node; +} + +template <class _Value, class _Ref, class _Ptr> +inline bool operator!=(const _Rb_tree_iterator<_Value, _Ref, _Ptr>& __x, + const _Rb_tree_iterator<_Value, _Ref, _Ptr>& __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 <class _Value, class _Ref, class _Ptr> +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 _Tp, class _Alloc, bool _S_instanceless> +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 _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 _Key, class _Value, class _KeyOfValue, class _Compare, + class _Alloc = allocator<_Value> > +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<value_type, reference, pointer> iterator; + typedef _Rb_tree_iterator<value_type, const_reference, const_pointer> + const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator<const_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_bidirectional_iterator<iterator, value_type, reference, + difference_type> + reverse_iterator; + typedef reverse_bidirectional_iterator<const_iterator, value_type, + const_reference, difference_type> + 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<iterator,bool> 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 <class _InputIterator> + void insert_unique(_InputIterator __first, _InputIterator __last); + template <class _InputIterator> + 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<iterator,iterator> equal_range(const key_type& __x); + pair<const_iterator, const_iterator> equal_range(const key_type& __x) const; + +public: + // Debugging. + bool __rb_verify() const; +}; + +template <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +_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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +pair<typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::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<iterator,bool>(_M_insert(__x, __y, __v), true); + else + --__j; + if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair<iterator,bool>(_M_insert(__x, __y, __v), true); + return pair<iterator,bool>(__j, false); +} + + +template <class _Key, class _Val, class _KeyOfValue, + class _Compare, class _Alloc> +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(_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_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 <class _Key, class _Val, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> + template<class _II> +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(_II __first, _II __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); +} + +template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> + template<class _II> +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 <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> +void +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); +} + +template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> +void +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); +} + +template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> +void +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_unique(*__first); +} + +template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) +{ + pair<iterator,iterator> __p = equal_range(__x); + size_type __n = 0; + distance(__p.first, __p.second, __n); + erase(__p.first, __p.second); + return __n; +} + +template <class _Key, class _Val, class _KoV, class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(const _Key* __first, const _Key* __last) +{ + while (__first != __last) erase(*__first++); +} + +template <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::count(const _Key& __k) const +{ + pair<const_iterator, const_iterator> __p = equal_range(__k); + size_type __n = 0; + distance(__p.first, __p.second, __n); + return __n; +} + +template <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +inline +pair<typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator, + typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator> +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::equal_range(const _Key& __k) +{ + return pair<iterator, iterator>(lower_bound(__k), upper_bound(__k)); +} + +template <class _Key, class _Value, class _KoV, class _Compare, class _Alloc> +inline +pair<typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::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<const_iterator,const_iterator>(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; + int __sum = 0; + do { + if (__node->_M_color == _S_rb_tree_black) + ++__sum; + if (__node == __root) + break; + __node = __node->_M_parent; + } while (1); + return __sum; +} + +template <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +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 <class _Key, class _Value, class _KeyOfValue, class _Compare, + class _Alloc = allocator<_Value> > +struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> +{ + typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + + rb_tree(const _Compare& __comp = _Compare(), + const allocator_type& __a = allocator_type()) + : _Base(__comp, __a) {} + + ~rb_tree() {} +}; + +#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: diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h new file mode 100644 index 00000000000..a9b196be347 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -0,0 +1,281 @@ +/* + * + * 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 _CPP_BITS_STL_UNINITIALIZED_H +#define _CPP_BITS_STL_UNINITIALIZED_H 1 + +#include <bits/std_cstring.h> + +__STL_BEGIN_NAMESPACE + +// uninitialized_copy + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template <class _InputIter, class _ForwardIter> +inline _ForwardIter +__uninitialized_copy_aux(_InputIter __first, _InputIter __last, + _ForwardIter __result, + __true_type) +{ + return copy(__first, __last, __result); +} + +template <class _InputIter, class _ForwardIter> +_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 <class _InputIter, class _ForwardIter, class _Tp> +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 <class _InputIter, class _ForwardIter> +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 <class _InputIter, class _Size, class _ForwardIter> +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 <class _RandomAccessIter, class _Size, class _ForwardIter> +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 <class _InputIter, class _Size, class _ForwardIter> +inline pair<_InputIter, _ForwardIter> +__uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) { + return __uninitialized_copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +template <class _InputIter, class _Size, class _ForwardIter> +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 <class _ForwardIter, class _Tp> +inline void +__uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + const _Tp& __x, __true_type) +{ + fill(__first, __last, __x); +} + +template <class _ForwardIter, class _Tp> +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 <class _ForwardIter, class _Tp, class _Tp1> +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 <class _ForwardIter, class _Tp> +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 <class _ForwardIter, class _Size, class _Tp> +inline _ForwardIter +__uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + const _Tp& __x, __true_type) +{ + return fill_n(__first, __n, __x); +} + +template <class _ForwardIter, class _Size, class _Tp> +_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 <class _ForwardIter, class _Size, class _Tp, class _Tp1> +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 <class _ForwardIter, class _Size, class _Tp> +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 <class _InputIter1, class _InputIter2, class _ForwardIter> +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 <class _ForwardIter, class _Tp, class _InputIter> +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 <class _InputIter, class _ForwardIter, class _Tp> +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 /* _CPP_BITS_STL_UNINITIALIZED_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h new file mode 100644 index 00000000000..0727df6fac1 --- /dev/null +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -0,0 +1,879 @@ +/* + * + * 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 <bits/exception_support.h> + +#include <bits/concept_checks.h> + +__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 _Tp, class _Allocator, bool _IsStatic> +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 _Tp, class _Allocator> +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 <class _Tp, class _Alloc> +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 _Tp, class _Alloc> +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 _Tp, class _Alloc = allocator<_Tp> > +class vector : protected _Vector_base<_Tp, _Alloc> +{ + // requirements: + + __STL_CLASS_REQUIRES(_Tp, _Assignable); + +private: + typedef _Vector_base<_Tp, _Alloc> _Base; + typedef vector<_Tp, _Alloc> vector_type; +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef __normal_iterator<pointer, vector_type> iterator; + typedef __normal_iterator<const_pointer, vector_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_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<const_iterator, value_type, const_reference, + difference_type> const_reverse_iterator; + typedef reverse_iterator<iterator, value_type, reference, difference_type> + 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 iterator (_M_start); } + const_iterator begin() const + { return const_iterator (_M_start); } + iterator end() { return iterator (_M_finish); } + const_iterator end() const { return const_iterator (_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(const_iterator(_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()) + __out_of_range("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 <class _InputIterator> + 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 <class _Integer> + 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 <class _InputIterator> + 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(); + pointer __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 <class _InputIterator> + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template <class _InputIter> + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template <class _InputIterator> + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template <class _ForwardIterator> + 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(iterator(__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(iterator(__position)); + return begin() + __n; + } +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InputIterator> + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + + template <class _Integer> + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) + { _M_fill_insert(__pos, (size_type) __n, (_Tp) __val); } + + template <class _InputIterator> + 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, end(), __position); + --_M_finish; + destroy(_M_finish); + return __position; + } + iterator erase(iterator __first, iterator __last) { + iterator __i(copy(__last, end(), __first)); + destroy(__i, end()); + _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 <class _ForwardIterator> + pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first, + _ForwardIterator __last) +{ + pointer __result = _M_allocate(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __result); + return __result; + } + __STL_UNWIND(_M_deallocate(__result, __n)); + } +#else /* __STL_MEMBER_TEMPLATES */ + pointer _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 <class _InputIterator> + 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 <class _ForwardIterator> + 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 <class _InputIterator> + void _M_range_insert(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template <class _ForwardIterator> + void _M_range_insert(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) +{ + __x.swap(__y); +} + +template <class _Tp, class _Alloc> +inline bool +operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { + return !(__x == __y); +} + +template <class _Tp, class _Alloc> +inline bool +operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { + return __y < __x; +} + +template <class _Tp, class _Alloc> +inline bool +operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { + return !(__y < __x); +} + +template <class _Tp, class _Alloc> +inline bool +operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template <class _Tp, class _Alloc> +vector<_Tp,_Alloc>& +vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x) +{ + if (&__x != this) { + const size_type __xlen = __x.size(); + if (__xlen > capacity()) { + pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); + 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, end()); + } + 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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> template <class _InputIter> +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 <class _Tp, class _Alloc> template <class _ForwardIter> +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()) { + pointer __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, end()); + _M_finish = __new_finish.base(); + } + 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 <class _Tp, class _Alloc> +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, iterator(_M_finish - 2), iterator(_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(iterator(_M_start), __position, + __new_start); + construct(__new_finish.base(), __x); + ++__new_finish; + __new_finish = uninitialized_copy(__position, iterator(_M_finish), + __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start.base(),__len))); + destroy(begin(), end()); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start.base(); + _M_finish = __new_finish.base(); + _M_end_of_storage = __new_start.base() + __len; + } +} + +template <class _Tp, class _Alloc> +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, iterator(_M_finish - 2), + iterator(_M_finish - 1)); + *__position = _Tp(); + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + pointer __new_start = _M_allocate(__len); + pointer __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(iterator(_M_start), __position, + __new_start); + construct(__new_finish); + ++__new_finish; + __new_finish = uninitialized_copy(__position, iterator(_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 <class _Tp, class _Alloc> +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 = end() - __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(begin(), __position, __new_start); + __new_finish = uninitialized_fill_n(__new_finish, __n, __x); + __new_finish + = uninitialized_copy(__position, end(), __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start.base(),__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start.base(); + _M_finish = __new_finish.base(); + _M_end_of_storage = __new_start.base() + __len; + } + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class _Tp, class _Alloc> template <class _InputIterator> +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 <class _Tp, class _Alloc> template <class _ForwardIterator> +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 = end() - __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(iterator(_M_start), + __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, iterator(_M_finish), __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start.base(),__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start.base(); + _M_finish = __new_finish.base(); + _M_end_of_storage = __new_start.base() + __len; + } + } +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template <class _Tp, class _Alloc> +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: diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc new file mode 100644 index 00000000000..d03b7bca104 --- /dev/null +++ b/libstdc++-v3/include/bits/streambuf.tcc @@ -0,0 +1,261 @@ +// Stream buffer classes -*- C++ -*- + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.5 Stream buffers +// + +#ifndef _CPP_BITS_STREAMBUF_TCC +#define _CPP_BITS_STREAMBUF_TCC 1 + +namespace std { + + template<typename _CharT, typename _Traits> + basic_streambuf<_CharT, _Traits>::int_type + basic_streambuf<_CharT, _Traits>:: + sbumpc() + { + int_type __ret; + if (_M_in_cur && _M_in_cur < _M_in_end) + { + char_type __c = *gptr(); + ++_M_in_cur; + if (_M_buf_unified && _M_mode & ios_base::out) + ++_M_out_cur; + __ret = traits_type::to_int_type(__c); + } + else + __ret = this->uflow(); + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_streambuf<_CharT, _Traits>::int_type + basic_streambuf<_CharT, _Traits>:: + sputbackc(char_type __c) + { + int_type __ret; + bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; + bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]); + if (!__testpos || __testne) + __ret = pbackfail(traits_type::to_int_type(__c)); + else + { + --_M_in_cur; + if (_M_buf_unified && _M_mode & ios_base::out) + --_M_out_cur; + __ret = traits_type::to_int_type(*this->gptr()); + } + return __ret; + } + + template<typename _CharT, typename _Traits> + basic_streambuf<_CharT, _Traits>::int_type + basic_streambuf<_CharT, _Traits>:: + sungetc() + { + int_type __ret; + if (_M_in_cur && _M_in_beg < _M_in_cur) + { + --_M_in_cur; + if (_M_buf_unified && _M_mode & ios_base::out) + --_M_out_cur; + __ret = traits_type::to_int_type(*_M_in_cur); + } + else + __ret = this->pbackfail(); + return __ret; + } + + // Don't test against _M_buf + _M_buf_size, because _M_buf reflects + // allocated space, and on certain (rare but entirely legal) + // situations, there will be no allocated space yet the internal + // buffers will still be valid. (This happens if setp is used to set + // the internal buffer to say some externally-allocated sequence.) + template<typename _CharT, typename _Traits> + basic_streambuf<_CharT, _Traits>::int_type + basic_streambuf<_CharT, _Traits>:: + sputc(char_type __c) + { + int_type __ret; + + if (_M_out_cur && _M_out_cur < _M_out_beg + _M_buf_size) + { + *_M_out_cur = __c; + _M_out_cur_move(1); + __ret = traits_type::to_int_type(__c); + } + else + __ret = this->overflow(traits_type::to_int_type(__c)); + return __ret; + } + + template<typename _CharT, typename _Traits> + streamsize + basic_streambuf<_CharT, _Traits>:: + xsgetn(char_type* __s, streamsize __n) + { + bool __testout = _M_mode & ios_base::out; + streamsize __ret = 0; + + if (__n) + { + while (__ret < __n) + { + if (_M_in_cur < _M_in_end) + { + size_t __len; + if (_M_in_cur + __n - __ret <= _M_in_end) + __len = __n - __ret; + else + __len = _M_in_end - _M_in_cur; + traits_type::copy(__s, _M_in_cur, __len); + __ret += __len; + __s += __len; + _M_in_cur += __len; + if (_M_buf_unified && __testout) + _M_out_cur += __len; + } + + if (__ret != __n) + { + int_type __c = this->uflow(); + if (traits_type::eq_int_type(__c, traits_type::eof())) + break; + + traits_type::assign(*__s++, traits_type::to_char_type(__c)); + ++__ret; + } + } + } + return __ret; + } + + // Don't test against _M_buf + _M_buf_size, because _M_buf reflects + // allocated space, and on certain (rare but entirely legal) + // situations, there will be no allocated space yet the internal + // buffers will still be valid. (This happens if setp is used to set + // the internal buffer to say some externally-allocated sequence.) + template<typename _CharT, typename _Traits> + streamsize + basic_streambuf<_CharT, _Traits>:: + xsputn(const char_type* __s, streamsize __n) + { + streamsize __ret = 0; + + if (__n) + { + while (__ret < __n) + { + bool __testput = _M_out_cur < _M_out_beg + _M_buf_size; + bool __testout = _M_mode & ios_base::out; + if (!(__testput && __testout)) + { + int_type __c = traits_type::to_int_type(*__s); + int_type __overfc = this->overflow(__c); + if (traits_type::eq_int_type(__c, __overfc)) + { + ++__ret; + ++__s; + } + else + break; + } + + if (__ret != __n) + { + size_t __len; + if (_M_out_cur + __n - __ret <= _M_out_beg + _M_buf_size) + __len = __n - __ret; + else + __len = _M_out_beg + _M_buf_size - _M_out_cur; + traits_type::copy(_M_out_cur, __s, __len); + __ret += __len; + __s += __len; + _M_out_cur_move(__len); + } + } + } + return __ret; + } + + + // Conceivably, this could be used to implement buffer-to-buffer + // copies, if this was ever desired in an un-ambiguous way by the + // standard. If so, then checks for __ios being zero would be + // necessary. + template<typename _CharT, typename _Traits> + streamsize + _S_copy_streambufs(basic_ios<_CharT, _Traits>& __ios, + basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout) + { + typedef typename _Traits::int_type int_type; + + streamsize __ret = 0; + streamsize __bufsize = __sbin->in_avail(); + streamsize __xtrct; + bool __testout = __sbin->_M_mode & ios_base::out; + bool __testput = __sbout->_M_mode & ios_base::out; + try { + while (__testput && __bufsize != -1) + { + __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize); + __ret += __xtrct; + __sbin->_M_in_cur += __xtrct; + if (__testout && __sbin->_M_buf_unified) + __sbin->_M_out_cur += __xtrct; + if (__xtrct == __bufsize) + { + int_type __c = __sbin->sgetc(); + if (__c == _Traits::eof()) + { + __ios.setstate(ios_base::eofbit); + break; + } + __bufsize = __sbin->in_avail(); + } + else + break; + } + } + catch(exception& __fail) { + if ((__ios.exceptions() & ios_base::failbit) != 0) + throw; + } + return __ret; + } + +} // namespace std + +#endif // _CPP_BITS_STREAMBUF_TCC + + + + diff --git a/libstdc++-v3/include/bits/string.tcc b/libstdc++-v3/include/bits/string.tcc new file mode 100644 index 00000000000..82a5a7af8ff --- /dev/null +++ b/libstdc++-v3/include/bits/string.tcc @@ -0,0 +1,856 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 2000, 1999, 1998, 1997 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +// This file is included by <string>. It is not meant to be included +// separately. + +// Written by Jason Merrill based upon the specification by Takanori Adachi +// in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. + +#ifndef _CPP_BITS_STRING_TCC +#define _CPP_BITS_STRING_TCC 1 + +namespace std +{ + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_terminal = _CharT(); + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4; + + template<typename _CharT, typename _Traits, typename _Alloc> + const basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::npos; + + // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) + // at static init time (before static ctors are run). + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[ + (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)]; + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIter> + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, + input_iterator_tag) + { + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refcopy(); + // Avoid reallocation for common case. + _CharT __buf[100]; + size_type __i = 0; + while (__beg != __end && __i < sizeof(__buf) / sizeof(_CharT)) + { + __buf[__i++] = *__beg; + ++__beg; + } + _Rep* __r = _Rep::_S_create(__i, __a); + traits_type::copy(__r->_M_refdata(), __buf, __i); + __r->_M_length = __i; + try { + // NB: this loop looks precisely this way because + // it avoids comparing __beg != __end any more + // than strictly necessary; != might be expensive! + for (;;) + { + _CharT* __p = __r->_M_refdata() + __r->_M_length; + _CharT* __last = __r->_M_refdata() + __r->_M_capacity; + for (;;) + { + if (__beg == __end) + { + __r->_M_length = __p - __r->_M_refdata(); + *__p = _Rep::_S_terminal; // grrr. + return __r->_M_refdata(); + } + if (__p == __last) + break; + *__p++ = *__beg; + ++__beg; + } + // Allocate more space. + size_type __len = __p - __r->_M_refdata(); + _Rep* __another = _Rep::_S_create(__len + 1, __a); + traits_type::copy(__another->_M_refdata(), + __r->_M_refdata(), __len); + __r->_M_destroy(__a); + __r = __another; + __r->_M_length = __len; + } + } + catch (...) { + __r->_M_destroy(__a); + throw; + } + return 0; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template <class _InIter> + _CharT* + basic_string<_CharT,_Traits,_Alloc>:: + _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, + forward_iterator_tag) + { + size_type __dnew = static_cast<size_type>(distance(__beg, __end)); + + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refcopy(); + + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__dnew, __a); + try { + _S_copy_chars(__r->_M_refdata(), __beg, __end); + } + catch (...) { + __r->_M_destroy(__a); + throw; + } + __r->_M_length = __dnew; + + __r->_M_refdata()[__dnew] = _Rep::_S_terminal; // grrr. + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + basic_string<_CharT,_Traits, _Alloc>:: + _S_construct(size_type __n, _CharT __c, const _Alloc& __a) + { + if (__n == 0 && __a == _Alloc()) + return _S_empty_rep()._M_refcopy(); + + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__n, __a); + try { + if (__n) + traits_type::assign(__r->_M_refdata(), __n, __c); + } + catch (...) { + __r->_M_destroy(__a); + throw; + } + __r->_M_length = __n; + __r->_M_refdata()[__n] = _Rep::_S_terminal; // grrr + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str) + : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(), __str.get_allocator()), + __str.get_allocator()) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _Alloc& __a) + : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, size_type __n) + : _M_dataplus(_S_construct(__str._M_check(__pos), + __str._M_fold(__pos, __n), _Alloc()), _Alloc()) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__str._M_check(__pos), + __str._M_fold(__pos, __n), __a), __a) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s + traits_type::length(__s), __a), __a) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(size_type __n, _CharT __c, const _Alloc& __a) + : _M_dataplus(_S_construct(__n, __c, __a), __a) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InputIter> + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(_InputIter __beg, _InputIter __end, const _Alloc& __a) + : _M_dataplus(_S_construct(__beg, __end, __a), __a) + { } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>::assign(const basic_string& __str) + { + if (_M_rep() != __str._M_rep()) + { + // XXX MT + allocator_type __a = this->get_allocator(); + _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_destroy(const _Alloc& __a) throw () + { + size_type __size = sizeof(_Rep) + (_M_capacity + 1) * sizeof(_CharT); + _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard() + { + if (_M_rep()->_M_is_shared()) + _M_mutate(0, 0, 0); + _M_rep()->_M_set_leaked(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, size_type __len2) + { + size_type __old_size = this->size(); + const size_type __new_size = __old_size + __len2 - __len1; + const _CharT* __src = _M_data() + __pos + __len1; + const size_type __how_much = __old_size - __pos - __len1; + + if (_M_rep()->_M_is_shared() || __new_size > capacity()) + { + // Must reallocate. + allocator_type __a = get_allocator(); + _Rep* __r = _Rep::_S_create(__new_size, __a); + try { + if (__pos) + traits_type::copy(__r->_M_refdata(), _M_data(), __pos); + if (__how_much) + traits_type::copy(__r->_M_refdata() + __pos + __len2, + __src, __how_much); + } + catch (...) { + __r->_M_dispose(get_allocator()); + throw; + } + _M_rep()->_M_dispose(__a); + _M_data(__r->_M_refdata()); + } + else if (__how_much && __len1 != __len2) + { + // Work in-place + traits_type::move(_M_data() + __pos + __len2, __src, __how_much); + } + _M_rep()->_M_set_sharable(); + _M_rep()->_M_length = __new_size; + _M_data()[__new_size] = _Rep::_S_terminal; // grrr. (per 21.3.4) + // You cannot leave those LWG people alone for a second. + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res) + { + if (__res > this->capacity() || _M_rep()->_M_is_shared()) + { + __LENGTHERROR(__res > this->max_size()); + allocator_type __a = get_allocator(); + _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s) + { + if (_M_rep()->_M_is_leaked()) + _M_rep()->_M_set_sharable(); + if (__s._M_rep()->_M_is_leaked()) + __s._M_rep()->_M_set_sharable(); + if (this->get_allocator() == __s.get_allocator()) + { + _CharT* __tmp = _M_data(); + _M_data(__s._M_data()); + __s._M_data(__tmp); + } + // The code below can usually be optimized away. + else + { + basic_string __tmp1(_M_ibegin(), _M_iend(), __s.get_allocator()); + basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), + this->get_allocator()); + *this = __tmp2; + __s = __tmp1; + } + } + +#ifdef _GLIBCPP_ALLOC_CONTROL + template<typename _CharT, typename _Traits, typename _Alloc> + bool (*basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_excess_slop) + (size_t, size_t) = + basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_default_excess; +#endif + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>::_Rep* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _S_create(size_t __capacity, const _Alloc& __alloc) + { +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + __LENGTHERROR(__capacity > _S_max_size); +#else + __LENGTHERROR(__capacity == npos); +#endif + + // NB: Need an array of char_type[__capacity], plus a + // terminating null char_type() element, plus enough for the + // _Rep data structure. Whew. Seemingly so needy, yet so elemental. + size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + // NB: Might throw, but no worries about a leak, mate: _Rep() + // does not throw. + void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); + _Rep *__p = new (__place) _Rep; + __p->_M_capacity = __capacity; + __p->_M_set_sharable(); // one reference + __p->_M_length = 0; + return __p; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_clone(const _Alloc& __alloc, size_type __res) + { + _Rep* __r = _Rep::_S_create(_M_length + __res, __alloc); + if (_M_length) + { + try { + traits_type::copy(__r->_M_refdata(), _M_refdata(), _M_length); + } + catch (...) { + __r->_M_destroy(__alloc); + throw; + } + } + __r->_M_length = _M_length; + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + inline bool +#ifdef _GLIBCPP_ALLOC_CONTROL + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _S_default_excess(size_t __s, size_t __r) +#else + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _S_excess_slop(size_t __s, size_t __r) +#endif + { + return 2 * (__s <= 16 ? 16 : __s) < __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c) + { + __LENGTHERROR(__n > max_size()); + size_type __size = this->size(); + if (__size < __n) + this->append(__n - __size, __c); + else if (__n < __size) + this->erase(__n); + // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InputIter> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace(iterator __i1, iterator __i2, _InputIter __k1, + _InputIter __k2, input_iterator_tag) + { + basic_string __s(__k1, __k2); + return this->replace(__i1, __i2, __s._M_ibegin(), __s._M_iend()); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _ForwardIter> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace(iterator __i1, iterator __i2, _ForwardIter __k1, + _ForwardIter __k2, forward_iterator_tag) + { + size_type __dold = __i2 - __i1; + size_type __dmax = this->max_size(); + size_type __dnew = static_cast<size_type>(distance(__k1, __k2)); + + __LENGTHERROR(__dmax <= __dnew); + size_type __off = __i1 - _M_ibegin(); + _M_mutate(__off, __dold, __dnew); + // Invalidated __i1, __i2 + if (__dnew) + _S_copy_chars(_M_data() + __off, __k1, __k2); + + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { + return this->replace(_M_check(__pos1), _M_fold(__pos1, __n1), + __str._M_check(__pos2), + __str._M_fold(__pos2, __n2)); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc>& + basic_string<_CharT,_Traits,_Alloc>:: + append(const basic_string& __str) + { + // Iff appending itself, string needs to pre-reserve the + // correct size so that _M_mutate does not clobber the + // iterators formed here. + size_type __size = __str.size(); + size_type __len = __size + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return this->replace(_M_iend(), _M_iend(), __str._M_ibegin(), + __str._M_iend()); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc>& + basic_string<_CharT,_Traits,_Alloc>:: + append(const basic_string& __str, size_type __pos, size_type __n) + { + // Iff appending itself, string needs to pre-reserve the + // correct size so that _M_mutate does not clobber the + // iterators formed here. + size_type __len = min(__str.size() - __pos, __n) + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return this->replace(_M_iend(), _M_iend(), __str._M_check(__pos), + __str._M_fold(__pos, __n)); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc>& + basic_string<_CharT,_Traits,_Alloc>:: + append(const _CharT* __s, size_type __n) + { + size_type __len = __n + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return this->replace(_M_iend(), _M_iend(), __s, __s + __n); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc>& + basic_string<_CharT,_Traits,_Alloc>:: + append(size_type __n, _CharT __c) + { + size_type __len = __n + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return this->replace(_M_iend(), _M_iend(), __n, __c); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Alloc>& __rhs) + { + typedef basic_string<_CharT,_Traits,_Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __size_type __len = _Traits::length(__lhs); + __string_type __str; + __str.reserve(__len + __rhs.size()); + __str.append(__lhs, __lhs + __len); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT,_Traits,_Alloc> + operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs) + { + typedef basic_string<_CharT,_Traits,_Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str; + __size_type __len = __rhs.size(); + __str.reserve(__len + 1); + __str.append(__string_type::size_type(1), __lhs); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + replace(iterator __i1, iterator __i2, size_type __n2, _CharT __c) + { + size_type __n1 = __i2 - __i1; + size_type __off1 = __i1 - _M_ibegin(); + __LENGTHERROR(max_size() - (this->size() - __n1) <= __n2); + _M_mutate (__off1, __n1, __n2); + // Invalidated __i1, __i2 + if (__n2) + traits_type::assign(_M_data() + __off1, __n2, __c); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + __OUTOFRANGE(__pos > this->size()); + + if (__n > this->size() - __pos) + __n = this->size() - __pos; + + traits_type::copy(__s, _M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } + + // String operations + // NB: This is specialized for the standard char_traits<char> + // specialization to use the same optimizations as strchr. + template<typename _CharT, typename _Traits, typename _Alloc> + const _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_find(const _CharT* __beg, const _CharT* __end, _CharT __c) + { + return find_if(__beg, __end, _Char_traits_match<_CharT, _Traits>(__c)); + } + + // Specialization for char, definitions in src/string-inst.cc. + template<> + const char* + string::_S_find(const char* __beg, const char* __end, char __c); + + // Specialization for wchar_t. +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + const wchar_t* + wstring::_S_find(const wchar_t* __beg, const wchar_t* __end, wchar_t __c); +#endif + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(const _CharT* __s, size_type __pos, size_type __n) const + { + size_t __xpos = __pos; + const _CharT* __data = _M_data(); + for (; __xpos + __n <= this->size(); ++__xpos) + if (traits_type::compare(__data + __xpos, __s, __n) == 0) + return __xpos; + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + size_type __ret = npos; + if (__pos < __size) + { + const _CharT* __data = _M_data(); + const _CharT* __end = __data + __size; + const _CharT* __p = _S_find(__data + __pos, __end, __c); + if (__p != __end) + __ret = __p - __data; + } + return __ret; + } + + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + size_type __size = this->size(); + if (__n <= __size) + { + __pos = std::min(__size - __n ,__pos); + const _CharT* __data = _M_data(); + do + { + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + size_t __xpos = __size - 1; + if (__xpos > __pos) + __xpos = __pos; + + for (++__xpos; __xpos-- > 0; ) + if (traits_type::eq(_M_data()[__xpos], __c)) + return __xpos; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + 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 + { + const _CharT* __end = __s + __n; + for (; __n && __pos < this->size(); ++__pos) + { + const _CharT* __p = _S_find(__s, __end, _M_data()[__pos]); + if (__p != __end) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + 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 + { + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + const _CharT* __p = _S_find(__s, __s + __n, _M_data()[__size]); + if (__p != __s + __n) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + 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 + { + size_t __xpos = __pos; + for (; __n && __xpos < this->size(); ++__xpos) + if (_S_find(__s, __s + __n, _M_data()[__xpos]) == __s + __n) + return __xpos; + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_not_of(_CharT __c, size_type __pos) const + { + size_t __xpos = __pos; + for (; __xpos < size(); ++__xpos) + if (!traits_type::eq(_M_data()[__xpos], __c)) + return __xpos; + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + 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 + { + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (_S_find(__s, __s + __n, _M_data()[__size]) == __s + __n) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_not_of(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(_M_data()[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n, const basic_string& __str) const + { + size_type __size = this->size(); + size_type __osize = __str.size(); + __OUTOFRANGE(__pos > __size); + + size_type __rsize= min(__size - __pos, __n); + size_type __len = min(__rsize, __osize); + int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); + if (!__r) + __r = __rsize - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { + size_type __size = this->size(); + size_type __osize = __str.size(); + __OUTOFRANGE(__pos1 > __size); + __OUTOFRANGE(__pos2 > __osize); + + size_type __rsize = min(__size - __pos1, __n1); + size_type __rosize = min(__osize - __pos2, __n2); + size_type __len = min(__rsize, __rosize); + int __r = traits_type::compare(_M_data() + __pos1, + __str.data() + __pos2, __len); + if (!__r) + __r = __rsize - __rosize; + return __r; + } + + + template<typename _CharT, typename _Traits, typename _Alloc> + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(const _CharT* __s) const + { + size_type __size = this->size(); + int __r = traits_type::compare(_M_data(), __s, __size); + if (!__r) + __r = __size - traits_type::length(__s); + return __r; + } + + + template<typename _CharT, typename _Traits, typename _Alloc> + int + basic_string <_CharT,_Traits,_Alloc>:: + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const + { + size_type __size = this->size(); + __OUTOFRANGE(__pos > __size); + + size_type __osize = min(traits_type::length(__s), __n2); + size_type __rsize = min(__size - __pos, __n1); + size_type __len = min(__rsize, __osize); + int __r = traits_type::compare(_M_data() + __pos, __s, __len); + if (!__r) + __r = __rsize - __osize; + return __r; + } + + template <class _CharT, class _Traits, class _Alloc> + void + _S_string_copy(const basic_string<_CharT, _Traits, _Alloc>& __str, + _CharT* __buf, typename _Alloc::size_type __bufsiz) + { + typedef typename _Alloc::size_type size_type; + size_type __strsize = __str.size(); + size_type __bytes = min(__strsize, __bufsiz - 1); + _Traits::copy(__buf, __str.data(), __bytes); + __buf[__bytes] = _CharT(); + } + +} // std:: + +#endif /* _CPP_BITS_STRING_TCC */ diff --git a/libstdc++-v3/include/bits/type_traits.h b/libstdc++-v3/include/bits/type_traits.h new file mode 100644 index 00000000000..dbcaa2a619f --- /dev/null +++ b/libstdc++-v3/include/bits/type_traits.h @@ -0,0 +1,387 @@ +/* + * + * 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 _CPP_BITS_TYPE_TRAITS_H +#define _CPP_BITS_TYPE_TRAITS_H 1 + +#ifndef _CPP_BITS_STL_CONFIG_H +#include <bits/stl_config.h> +#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 <class _Tp> void + copy(_Tp* __source,_Tp* __destination,int __n,__false_type); +//Copy an array of elements which have trivial copy constructors. Use memcpy. +template <class _Tp> void + copy(_Tp* __source,_Tp* __destination,int __n,__true_type); + +//Copy an array of any type by using the most efficient copy mechanism +template <class _Tp> inline void copy(_Tp* __source,_Tp* __destination,int __n) { + copy(__source,__destination,__n, + typename __type_traits<_Tp>::has_trivial_copy_constructor()); +} +*/ + + +template <bool _Truth> struct _Bool {}; +typedef _Bool<true> __true_type; +typedef _Bool<false> __false_type; + +template <class _Tp> +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<bool> { + 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<char> { + 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<signed char> { + 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<unsigned char> { + 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<wchar_t> { + 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<short> { + 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<unsigned short> { + 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<int> { + 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<unsigned int> { + 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<long> { + 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<unsigned long> { + 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<long long> { + 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<unsigned long long> { + 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<float> { + 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<double> { + 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<long double> { + 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 <class _Tp> +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<char*> { + 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<signed char*> { + 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<unsigned char*> { + 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<const char*> { + 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<const signed char*> { + 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<const unsigned char*> { + 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 <class _Tp> struct _Is_integer { + typedef __false_type _Integral; +}; + +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL struct _Is_integer<bool> { + typedef __true_type _Integral; +}; + +#endif /* __STL_NO_BOOL */ + +__STL_TEMPLATE_NULL struct _Is_integer<char> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<signed char> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned char> { + typedef __true_type _Integral; +}; + +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL struct _Is_integer<wchar_t> { + typedef __true_type _Integral; +}; + +#endif /* __STL_HAS_WCHAR_T */ + +__STL_TEMPLATE_NULL struct _Is_integer<short> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned short> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<int> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned int> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<long> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned long> { + typedef __true_type _Integral; +}; + +#ifdef __STL_LONG_LONG + +__STL_TEMPLATE_NULL struct _Is_integer<long long> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned long long> { + typedef __true_type _Integral; +}; + +#endif /* __STL_LONG_LONG */ + +template<typename _Tp> struct _Is_normal_iterator { + typedef __false_type _Normal; +}; + +// Forward declaration hack, should really include this from somewhere. +namespace std { + template<typename _Iterator, typename _Container> class __normal_iterator; +}; + +template<typename _Iterator, typename _Container> +struct _Is_normal_iterator< std::__normal_iterator<_Iterator, _Container> > { + typedef __true_type _Normal; +}; + +#endif /* _CPP_BITS_TYPE_TRAITS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/bits/valarray_array.h b/libstdc++-v3/include/bits/valarray_array.h new file mode 100644 index 00000000000..2c88877bd28 --- /dev/null +++ b/libstdc++-v3/include/bits/valarray_array.h @@ -0,0 +1,575 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997-2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _CPP_BITS_ARRAY_H +#define _CPP_BITS_ARRAY_H 1 + +#include <bits/c++config.h> +#include <bits/cpp_type_traits.h> +#include <bits/std_cstdlib.h> +#include <bits/std_cstring.h> +#include <bits/std_new.h> + +namespace std +{ + + // + // Helper functions on raw pointers + // + + // We get memory by the old fashion way + inline void* + __valarray_get_memory(size_t __n) + { return operator new(__n); } + + template<typename _Tp> + inline _Tp*__restrict__ + __valarray_get_storage(size_t __n) + { + return static_cast<_Tp*__restrict__> + (__valarray_get_memory(__n * sizeof(_Tp))); + } + + // Return memory to the system + inline void + __valarray_release_memory(void* __p) + { operator delete(__p); } + + // Turn a raw-memory into an array of _Tp filled with _Tp() + // This is required in 'valarray<T> v(n);' + template<typename _Tp, bool> + struct _Array_default_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { while (__b != __e) new(__b++) _Tp(); } + }; + + template<typename _Tp> + struct _Array_default_ctor<_Tp, true> + { + // For fundamental types, it suffices to say 'memset()' + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { memset(__b, 0, (__e - __b)*sizeof(_Tp)); } + }; + + template<typename _Tp> + inline void + __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { + _Array_default_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__b, __e); + } + + // Turn a raw-memory into an array of _Tp filled with __t + // This is the required in valarray<T> v(n, t). Also + // used in valarray<>::resize(). + template<typename _Tp, bool> + struct _Array_init_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) + { while (__b != __e) new(__b++) _Tp(__t); } + }; + + template<typename _Tp> + struct _Array_init_ctor<_Tp, true> + { + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) + { while (__b != __e) *__b++ = __t; } + }; + + template<typename _Tp> + inline void + __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e, + const _Tp __t) + { + _Array_init_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__b, __e, __t); + } + + // + // copy-construct raw array [__o, *) from plain array [__b, __e) + // We can't just say 'memcpy()' + // + template<typename _Tp, bool> + struct _Array_copy_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { while (__b != __e) new(__o++) _Tp(*__b++); } + }; + + template<typename _Tp> + struct _Array_copy_ctor<_Tp, true> + { + inline static void + _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); } + }; + + template<typename _Tp> + inline void + __valarray_copy_construct(const _Tp* __restrict__ __b, + const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { + _Array_copy_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__b, __e, __o); + } + + // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] + template<typename _Tp> + inline void + __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, + size_t __s, _Tp* __restrict__ __o) + { + if (__is_fundamental<_Tp>::_M_type) + while (__n--) { *__o++ = *__a; __a += __s; } + else + while (__n--) { new(__o++) _Tp(*__a); __a += __s; } + } + + // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] + template<typename _Tp> + inline void + __valarray_copy_construct (const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __o, size_t __n) + { + if (__is_fundamental<_Tp>::_M_type) + while (__n--) *__o++ = __a[*__i++]; + else + while (__n--) new (__o++) _Tp(__a[*__i++]); + } + + // Do the necessary cleanup when we're done with arrays. + template<typename _Tp> + inline void + __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { + if (!__is_fundamental<_Tp>::_M_type) + while (__b != __e) { __b->~_Tp(); ++__b; } + } + + // fill plain array __a[<__n>] with __t + template<typename _Tp> + void + __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t) + { while (__n--) *__a++ = __t; } + + // fill strided array __a[<__n-1 : __s>] with __t + template<typename _Tp> + inline void + __valarray_fill (_Tp* __restrict__ __a, size_t __n, + size_t __s, const _Tp& __t) + { for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; } + + // fill indir ect array __a[__i[<__n>]] with __i + template<typename _Tp> + inline void + __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, + size_t __n, const _Tp& __t) + { for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; } + + // copy plain array __a[<__n>] in __b[<__n>] + // For non-fundamental types, it is wrong to say 'memcpy()' + template<typename _Tp, bool> + struct _Array_copier + { + inline static void + _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) + { while (__n--) *__b++ = *__a++; } + }; + + template<typename _Tp> + struct _Array_copier<_Tp, true> + { + inline static void + _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) + { memcpy (__b, __a, __n * sizeof (_Tp)); } + }; + + template<typename _Tp> + inline void + __valarray_copy (const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b) + { + _Array_copier<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__a, __n, __b); + } + + // copy strided array __a[<__n : __s>] in plain __b[<__n>] + template<typename _Tp> + inline void + __valarray_copy (const _Tp* __restrict__ __a, size_t __n, size_t __s, + _Tp* __restrict__ __b) + { for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; } + + // copy plain __a[<__n>] in strided __b[<__n : __s>] + template<typename _Tp> + inline void + __valarray_copy (const _Tp* __restrict__ __a, _Tp* __restrict__ __b, + size_t __n, size_t __s) + { for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; } + + // copy indexed __a[__i[<__n>]] in plain __b[<__n>] + template<typename _Tp> + inline void + __valarray_copy (const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __b, size_t __n) + { for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; } + + // copy plain __a[<__n>] in indexed __b[__i[<__n>]] + template<typename _Tp> + inline void + __valarray_copy (const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b, const size_t* __restrict__ __i) + { for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; } + + + // + // Compute the sum of elements in range [__f, __l) + // This is a naive algorithm. It suffers from cancelling. + // In the future try to specialize + // for _Tp = float, double, long double using a more accurate + // algorithm. + // + template<typename _Tp> + inline _Tp + __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l) + { + _Tp __r = _Tp(); + while (__f != __l) __r += *__f++; + return __r; + } + + // Compute the product of all elements in range [__f, __l) + template<typename _Tp> + inline _Tp + __valarray_product(const _Tp* __restrict__ __f, + const _Tp* __restrict__ __l) + { + _Tp __r = _Tp(1); + while (__f != __l) __r = __r * *__f++; + return __r; + } + + // Compute the min/max of an array-expression + template<typename _Ta> + inline typename _Ta::value_type + __valarray_min(const _Ta& __a) + { + size_t __s = __a.size(); + typedef typename _Ta::value_type _Value_type; + _Value_type __r = __s == 0 ? _Value_type() : __a[0]; + for (size_t __i = 1; __i < __s; ++__i) + { + _Value_type __t = __a[__i]; + if (__t < __r) + __r = __t; + } + return __r; + } + + template<typename _Ta> + inline typename _Ta::value_type + __valarray_max(const _Ta& __a) + { + size_t __s = __a.size(); + typedef typename _Ta::value_type _Value_type; + _Value_type __r = __s == 0 ? _Value_type() : __a[0]; + for (size_t __i = 1; __i < __s; ++__i) + { + _Value_type __t = __a[__i]; + if (__t > __r) + __r = __t; + } + return __r; + } + + // + // Helper class _Array, first layer of valarray abstraction. + // All operations on valarray should be forwarded to this class + // whenever possible. -- gdr + // + + template<typename _Tp> + struct _Array + { + explicit _Array (size_t); + explicit _Array (_Tp* const __restrict__); + explicit _Array (const valarray<_Tp>&); + _Array (const _Tp* __restrict__, size_t); + + _Tp* begin () const; + + _Tp* const __restrict__ _M_data; + }; + + template<typename _Tp> + inline void + __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) + { __valarray_fill (__a._M_data, __n, __t); } + + template<typename _Tp> + inline void + __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) + { __valarray_fill (__a._M_data, __n, __s, __t); } + + template<typename _Tp> + inline void + __valarray_fill (_Array<_Tp> __a, _Array<size_t> __i, + size_t __n, const _Tp& __t) + { __valarray_fill (__a._M_data, __i._M_data, __n, __t); } + + template<typename _Tp> + inline void + __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) + { __valarray_copy (__a._M_data, __n, __b._M_data); } + + template<typename _Tp> + inline void + __valarray_copy (_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) + { __valarray_copy(__a._M_data, __n, __s, __b._M_data); } + + template<typename _Tp> + inline void + __valarray_copy (_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) + { __valarray_copy (__a._M_data, __b._M_data, __n, __s); } + + template<typename _Tp> + inline void + __valarray_copy (_Array<_Tp> __a, _Array<size_t> __i, + _Array<_Tp> __b, size_t __n) + { __valarray_copy (__a._M_data, __i._M_data, __b._M_data, __n); } + + template<typename _Tp> + inline void + __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + _Array<size_t> __i) + { __valarray_copy (__a._M_data, __n, __b._M_data, __i._M_data); } + + template<typename _Tp> + inline + _Array<_Tp>::_Array (size_t __n) + : _M_data(__valarray_get_storage<_Tp>(__n)) + { __valarray_default_construct(_M_data, _M_data + __n); } + + template<typename _Tp> + inline + _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {} + + template<typename _Tp> + inline _Array<_Tp>::_Array (const valarray<_Tp>& __v) + : _M_data (__v._M_data) {} + + template<typename _Tp> + inline + _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) + : _M_data(__valarray_get_storage<_Tp>(__s)) + { __valarray_copy_construct(__b, __s, _M_data); } + + template<typename _Tp> + inline _Tp* + _Array<_Tp>::begin () const + { return _M_data; } + +#define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \ +{ \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \ + *__p _Op##= __t; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ +{ \ + _Tp* __p = __a._M_data; \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template<typename _Tp, class _Dom> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ + _Array<_Tp> __b) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ + size_t __n, size_t __s) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \ + *__p _Op##= *__q; \ +} \ + \ +template<typename _Tp, class _Dom> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + _Tp* __q (__b._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \ + __a._M_data[*__j] _Op##= *__q; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array<size_t> __i) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \ + *__p _Op##= __b._M_data[*__j]; \ +} \ + \ +template<typename _Tp, class _Dom> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + size_t* __j (__i._M_data); \ + for (size_t __k=0; __k<__n; ++__k, ++__j) \ + __a._M_data[*__j] _Op##= __e[__k]; \ +} \ + \ +template<typename _Tp> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template<typename _Tp> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array<bool> __m) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \ + while (! *ok) { \ + ++ok; \ + ++__q; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template<typename _Tp, class _Dom> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + bool* ok(__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= __e[__i]; \ + } \ +} + +_DEFINE_ARRAY_FUNCTION(+, plus) +_DEFINE_ARRAY_FUNCTION(-, minus) +_DEFINE_ARRAY_FUNCTION(*, multiplies) +_DEFINE_ARRAY_FUNCTION(/, divides) +_DEFINE_ARRAY_FUNCTION(%, modulus) +_DEFINE_ARRAY_FUNCTION(^, xor) +_DEFINE_ARRAY_FUNCTION(|, or) +_DEFINE_ARRAY_FUNCTION(&, and) +_DEFINE_ARRAY_FUNCTION(<<, shift_left) +_DEFINE_ARRAY_FUNCTION(>>, shift_right) + +#undef _DEFINE_VALARRAY_FUNCTION + +} // std:: + +#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT +# define export +# include <bits/valarray_array.tcc> +#endif + +#endif /* _CPP_BITS_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/valarray_array.tcc b/libstdc++-v3/include/bits/valarray_array.tcc new file mode 100644 index 00000000000..ab77f4aca1e --- /dev/null +++ b/libstdc++-v3/include/bits/valarray_array.tcc @@ -0,0 +1,161 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef _CPP_BITS_VALARRAY_ARRAY_TCC +#define _CPP_BITS_VALARRAY_ARRAY_TCC 1 + +namespace std +{ + +export template<typename _Tp> +void +__valarray_fill (_Array<_Tp> __a, size_t __n, _Array<bool> __m, const _Tp& __t) +{ + _Tp* __p = __a._M_data; + bool* __ok (__m._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + *__p = __t; + } +} + +export template<typename _Tp> +void +__valarray_copy (_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b, size_t __n) +{ + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + *__q = *__p; + } +} + +export template<typename _Tp> +void +__valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, _Array<bool> __m) +{ + _Tp* __q (__b._M_data); + bool* __ok (__m._M_data); + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++__ok, ++__q) { + while (! *__ok) { + ++__ok; + ++__q; + } + *__q = *__p; + } +} + +export template<typename _Tp, class _Dom> +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a) +{ + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__p) *__p = __e[__i]; +} + +export template<typename _Tp, class _Dom> +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, size_t __s) +{ + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p = __e[__i]; +} + +export template<typename _Tp, class _Dom> +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array<size_t> __i) +{ + size_t* __j (__i._M_data); + for (size_t __k=0; __k<__n; ++__k, ++__j) __a._M_data[*__j] = __e[__k]; +} + +export template<typename _Tp, class _Dom> +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array<bool> __m) +{ + bool* __ok (__m._M_data); + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + *__p = __e[__i]; + } +} + + +export template<typename _Tp, class _Dom> +void +__valarray_copy_construct (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a) +{ + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__p) new (__p) _Tp(__e[__i]); +} + + +export template<typename _Tp> +void +__valarray_copy_construct (_Array<_Tp> __a, _Array<bool> __m, + _Array<_Tp> __b, size_t __n) +{ + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + new (__q) _Tp(*__p); + } +} + + + + +} // std:: + +#endif /* _CPP_BITS_VALARRAY_ARRAY_TCC */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/bits/valarray_meta.h b/libstdc++-v3/include/bits/valarray_meta.h new file mode 100644 index 00000000000..e2e65de9c67 --- /dev/null +++ b/libstdc++-v3/include/bits/valarray_meta.h @@ -0,0 +1,1067 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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 Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> + +#ifndef _CPP_VALARRAY_META_H +#define _CPP_VALARRAY_META_H 1 + +namespace std { + + // + // Implementing a loosened valarray return value is tricky. + // First we need to meet 26.3.1/3: we should not add more than + // two levels of template nesting. Therefore we resort to template + // template to "flatten" loosened return value types. + // At some point we use partial specialization to remove one level + // template nesting due to _Expr<> + // + + + // This class is NOT defined. It doesn't need to. + template<typename _Tp1, typename _Tp2> class _Constant; + + // + // Unary function application closure. + // + template<class _Dom> class _UnFunBase { + public: + typedef typename _Dom::value_type value_type; + typedef value_type _Vt; + + _UnFunBase (const _Dom& __e, _Vt __f(_Vt)) + : _M_expr(__e), _M_func(__f) {} + + _Vt operator[] (size_t __i) const { return _M_func(_M_expr[__i]); } + size_t size () const { return _M_expr.size(); } + + private: + const _Dom& _M_expr; + _Vt (*_M_func)(_Vt); + }; + + template<template<class, class> class _Meta, class _Dom> + class _UnFunClos; + + template<class _Dom> + struct _UnFunClos<_Expr,_Dom> : _UnFunBase<_Dom> { + typedef _UnFunBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnFunClos (const _Dom& __e, value_type __f(value_type)) + : _Base (__e, __f) {} + }; + + template<typename _Tp> + struct _UnFunClos<_ValArray,_Tp> : _UnFunBase<valarray<_Tp> > { + typedef _UnFunBase<valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _UnFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp)) + : _Base (__v, __f) {} + }; + + // + // Binary function application closure. + // + template<template<class, class> class _Meta1, + template<class, class> class Meta2, + class _Dom1, class _Dom2> class _BinFunClos; + + template<class _Dom1, class _Dom2> class _BinFunBase { + public: + typedef typename _Dom1::value_type value_type; + typedef value_type _Vt; + + _BinFunBase (const _Dom1& __e1, const _Dom2& __e2, + _Vt __f (_Vt, _Vt)) + : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr1[__i], _M_expr2[__i]); } + size_t size () const { return _M_expr1.size (); } + + private: + const _Dom1& _M_expr1; + const _Dom2& _M_expr2; + _Vt (*_M_func)(_Vt, _Vt); + }; + + template<class _Dom> class _BinFunBase1 { + public: + typedef typename _Dom::value_type value_type ; + typedef value_type _Vt; + + _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt)) + : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr1, _M_expr2[__i]); } + size_t size () const { return _M_expr2.size (); } + + private: + const _Vt& _M_expr1; + const _Dom& _M_expr2; + _Vt (*_M_func)(_Vt, _Vt); + }; + + template<class _Dom> class _BinFunBase2 { + public: + typedef typename _Dom::value_type value_type; + typedef value_type _Vt; + + _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt)) + : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr1[__i], _M_expr2); } + size_t size () const { return _M_expr1.size (); } + + private: + const _Dom& _M_expr1; + const _Vt& _M_expr2; + _Vt (*_M_func)(_Vt, _Vt); + }; + + template<class _Dom1, class _Dom2> + struct _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> : _BinFunBase<_Dom1,_Dom2> { + typedef _BinFunBase<_Dom1,_Dom2> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _BinFunClos (const _Dom1& __e1, const _Dom2& __e2, + _Tp __f(_Tp, _Tp)) + : _Base (__e1, __e2, __f) {} + }; + + template<typename _Tp> + struct _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> + : _BinFunBase<valarray<_Tp>, valarray<_Tp> > { + typedef _BinFunBase<valarray<_Tp>, valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w, + _Tp __f(_Tp, _Tp)) + : _Base (__v, __w, __f) {} + }; + + template<class _Dom> + struct _BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type> + : _BinFunBase<_Dom,valarray<typename _Dom::value_type> > { + typedef typename _Dom::value_type _Tp; + typedef _BinFunBase<_Dom,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v, + _Tp __f(_Tp, _Tp)) + : _Base (__e, __v, __f) {} + }; + + template<class _Dom> + struct _BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom> + : _BinFunBase<valarray<typename _Dom::value_type>,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinFunBase<_Dom,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e, + _Tp __f(_Tp, _Tp)) + : _Base (__v, __e, __f) {} + }; + + template<class _Dom> + struct _BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type> + : _BinFunBase2<_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _Tp value_type; + typedef _BinFunBase2<_Dom> _Base; + + _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp)) + : _Base (__e, __t, __f) {} + }; + + template<class _Dom> + struct _BinFunClos<_Constant,_Expr,_Dom,typename _Dom::value_type> + : _BinFunBase1<_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _Tp value_type; + typedef _BinFunBase1<_Dom> _Base; + + _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp)) + : _Base (__t, __e, __f) {} + }; + + template<typename _Tp> + struct _BinFunClos<_ValArray,_Constant,_Tp,_Tp> + : _BinFunBase2<valarray<_Tp> > { + typedef _BinFunBase2<valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t, + _Tp __f(_Tp, _Tp)) + : _Base (__v, __t, __f) {} + }; + + template<typename _Tp> + struct _BinFunClos<_Constant,_ValArray,_Tp,_Tp> + : _BinFunBase1<valarray<_Tp> > { + typedef _BinFunBase1<valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v, + _Tp __f (_Tp, _Tp)) + : _Base (__t, __v, __f) {} + }; + + // + // Apply function taking a value/const reference closure + // + + template<typename _Dom, typename _Arg> class _FunBase { + public: + typedef typename _Dom::value_type value_type; + + _FunBase (const _Dom& __e, value_type __f(_Arg)) + : _M_expr (__e), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr[__i]); } + size_t size() const { return _M_expr.size ();} + + private: + const _Dom& _M_expr; + value_type (*_M_func)(_Arg); + }; + + template<class _Dom> + struct _ValFunClos<_Expr,_Dom> + : _FunBase<_Dom, typename _Dom::value_type> { + typedef _FunBase<_Dom, typename _Dom::value_type> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {} + }; + + template<typename _Tp> + struct _ValFunClos<_ValArray,_Tp> + : _FunBase<valarray<_Tp>, _Tp> { + typedef _FunBase<valarray<_Tp>, _Tp> _Base; + typedef _Tp value_type; + + _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp)) + : _Base (__v, __f) {} + }; + + template<class _Dom> + struct _RefFunClos<_Expr,_Dom> : + _FunBase<_Dom, const typename _Dom::value_type&> { + typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&)) + : _Base (__e, __f) {} + }; + + template<typename _Tp> + struct _RefFunClos<_ValArray,_Tp> + : _FunBase<valarray<_Tp>, const _Tp&> { + typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; + typedef _Tp value_type; + + _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&)) + : _Base (__e, __f) {} + }; + + // + // Unary expression closure. + // + + template<template<class> class _Oper, typename _Arg> + class _UnBase { + public: + typedef _Oper<typename _Arg::value_type> _Op; + typedef typename _Op::result_type value_type; + + _UnBase (const _Arg& __e) : _M_expr(__e) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr.size (); } + + private: + const _Arg& _M_expr; + }; + + template<template<class> class _Oper, typename _Arg> + inline typename _UnBase<_Oper, _Arg>::value_type + _UnBase<_Oper, _Arg>::operator[] (size_t __i) const + { return _Op() (_M_expr[__i]); } + + template<template<class> class _Oper, class _Dom> + struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> { + typedef _Dom _Arg; + typedef _UnBase<_Oper, _Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnClos (const _Arg& __e) : _Base(__e) {} + }; + + template<template<class> class _Oper, typename _Tp> + struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > { + typedef valarray<_Tp> _Arg; + typedef _UnBase<_Oper, valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _UnClos (const _Arg& __e) : _Base(__e) {} + }; + + + // + // Binary expression closure. + // + + template<template<class> class _Oper, + typename _FirstArg, typename _SecondArg> + class _BinBase { + public: + typedef _Oper<typename _FirstArg::value_type> _Op; + typedef typename _Op::result_type value_type; + + _BinBase (const _FirstArg& __e1, const _SecondArg& __e2) + : _M_expr1 (__e1), _M_expr2 (__e2) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr1.size (); } + + private: + const _FirstArg& _M_expr1; + const _SecondArg& _M_expr2; + }; + + template<template<class> class _Oper, + typename _FirstArg, typename _SecondArg> + inline typename _BinBase<_Oper,_FirstArg,_SecondArg>::value_type + _BinBase<_Oper,_FirstArg,_SecondArg>::operator[] (size_t __i) const + { return _Op() (_M_expr1[__i], _M_expr2[__i]); } + + + template<template<class> class _Oper, class _Clos> + class _BinBase2 { + public: + typedef typename _Clos::value_type _Vt; + typedef _Oper<_Vt> _Op; + typedef typename _Op::result_type value_type; + + _BinBase2 (const _Clos& __e, const _Vt& __t) + : _M_expr1 (__e), _M_expr2 (__t) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr1.size (); } + + private: + const _Clos& _M_expr1; + const _Vt& _M_expr2; + }; + + template<template<class> class _Oper, class _Clos> + inline typename _BinBase2<_Oper,_Clos>::value_type + _BinBase2<_Oper,_Clos>::operator[] (size_t __i) const + { return _Op() (_M_expr1[__i], _M_expr2); } + + + template<template<class> class _Oper, class _Clos> + class _BinBase1 { + public: + typedef typename _Clos::value_type _Vt; + typedef _Oper<_Vt> _Op; + typedef typename _Op::result_type value_type; + + _BinBase1 (const _Vt& __t, const _Clos& __e) + : _M_expr1 (__t), _M_expr2 (__e) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr2.size (); } + + private: + const _Vt& _M_expr1; + const _Clos& _M_expr2; + }; + + template<template<class> class _Oper, class _Clos> + inline typename + _BinBase1<_Oper,_Clos>::value_type + _BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const + { return _Op() (_M_expr1, _M_expr2[__i]); } + + + template<template<class> class _Oper, class _Dom1, class _Dom2> + struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> + : _BinBase<_Oper,_Dom1,_Dom2> { + typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} + }; + + template<template<class> class _Oper, typename _Tp> + struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> + : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > { + typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w) + : _Base (__v, __w) {} + }; + + template<template<class> class _Oper, class _Dom> + struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> + : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) + : _Base (__e1, __e2) {} + }; + + template<template<class> class _Oper, class _Dom> + struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom> + : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const valarray<_Tp>& __e1, const _Dom& __e2) + : _Base (__e1, __e2) {} + }; + + template<template<class> class _Oper, class _Dom> + struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> + : _BinBase2<_Oper,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinBase2<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {} + }; + + template<template<class> class _Oper, class _Dom> + struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> + : _BinBase1<_Oper,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinBase1<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {} + }; + + template<template<class> class _Oper, typename _Tp> + struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> + : _BinBase2<_Oper,valarray<_Tp> > { + typedef _BinBase2<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const valarray<_Tp>& __v, const _Tp& __t) + : _Base (__v, __t) {} + }; + + template<template<class> class _Oper, typename _Tp> + struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> + : _BinBase1<_Oper,valarray<_Tp> > { + typedef _BinBase1<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const _Tp& __t, const valarray<_Tp>& __v) + : _Base (__t, __v) {} + }; + + + // + // slice_array closure. + // + template<typename _Dom> class _SBase { + public: + typedef typename _Dom::value_type value_type; + + _SBase (const _Dom& __e, const slice& __s) + : _M_expr (__e), _M_slice (__s) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } + size_t size() const { return _M_slice.size (); } + + private: + const _Dom& _M_expr; + const slice& _M_slice; + }; + + template<typename _Tp> class _SBase<_Array<_Tp> > { + public: + typedef _Tp value_type; + + _SBase (_Array<_Tp> __a, const slice& __s) + : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), + _M_stride (__s.stride()) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[__i * _M_stride]; } + size_t size() const { return _M_size; } + + private: + const _Array<_Tp> _M_array; + const size_t _M_size; + const size_t _M_stride; + }; + + template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> { + typedef _SBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} + }; + + template<typename _Tp> + struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > { + typedef _SBase<_Array<_Tp> > _Base; + typedef _Tp value_type; + + _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} + }; + + // + // gslice_array closure. + // + template<class _Dom> class _GBase { + public: + typedef typename _Dom::value_type value_type; + + _GBase (const _Dom& __e, const valarray<size_t>& __i) + : _M_expr (__e), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + + private: + const _Dom& _M_expr; + const valarray<size_t>& _M_index; + }; + + template<typename _Tp> class _GBase<_Array<_Tp> > { + public: + typedef _Tp value_type; + + _GBase (_Array<_Tp> __a, const valarray<size_t>& __i) + : _M_array (__a), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + + private: + const _Array<_Tp> _M_array; + const valarray<size_t>& _M_index; + }; + + template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> { + typedef _GBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _GClos (const _Dom& __e, const valarray<size_t>& __i) + : _Base (__e, __i) {} + }; + + template<typename _Tp> + struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > { + typedef _GBase<_Array<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _GClos (_Array<_Tp> __a, const valarray<size_t>& __i) + : _Base (__a, __i) {} + }; + + // + // indirect_array closure + // + + template<class _Dom> class _IBase { + public: + typedef typename _Dom::value_type value_type; + + _IBase (const _Dom& __e, const valarray<size_t>& __i) + : _M_expr (__e), _M_index (__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size() const { return _M_index.size(); } + + private: + const _Dom& _M_expr; + const valarray<size_t>& _M_index; + }; + + template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> { + typedef _IBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _IClos (const _Dom& __e, const valarray<size_t>& __i) + : _Base (__e, __i) {} + }; + + template<typename _Tp> + struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > { + typedef _IBase<valarray<_Tp> > _Base; + typedef _Tp value_type; + + _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i) + : _Base (__a, __i) {} + }; + + // + // class _Expr + // + template<class _Clos, typename _Tp> class _Expr { + public: + typedef _Tp value_type; + + _Expr (const _Clos&); + + const _Clos& operator() () const; + + value_type operator[] (size_t) const; + valarray<value_type> operator[] (slice) const; + valarray<value_type> operator[] (const gslice&) const; + valarray<value_type> operator[] (const valarray<bool>&) const; + valarray<value_type> operator[] (const valarray<size_t>&) const; + + _Expr<_UnClos<_Unary_plus,_Expr,_Clos>, value_type> + operator+ () const; + + _Expr<_UnClos<negate,_Expr,_Clos>, value_type> + operator- () const; + + _Expr<_UnClos<_Bitwise_not,_Expr,_Clos>, value_type> + operator~ () const; + + _Expr<_UnClos<logical_not,_Expr,_Clos>, bool> + operator! () const; + + size_t size () const; + value_type sum () const; + + valarray<value_type> shift (int) const; + valarray<value_type> cshift (int) const; + + value_type min() const; + value_type max() const; + + valarray<value_type> apply(value_type (*) (const value_type&)) const; + valarray<value_type> apply(value_type (*) (value_type)) const; + + private: + const _Clos _M_closure; + }; + + template<class _Clos, typename _Tp> + inline + _Expr<_Clos,_Tp>::_Expr (const _Clos& __c) : _M_closure(__c) {} + + template<class _Clos, typename _Tp> + inline const _Clos& + _Expr<_Clos,_Tp>::operator() () const + { return _M_closure; } + + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos,_Tp>::operator[] (size_t __i) const + { return _M_closure[__i]; } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[] (slice __s) const + { return _M_closure[__s]; } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[] (const gslice& __gs) const + { return _M_closure[__gs]; } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[] (const valarray<bool>& __m) const + { return _M_closure[__m]; } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[] (const valarray<size_t>& __i) const + { return _M_closure[__i]; } + + template<class _Clos, typename _Tp> + inline size_t + _Expr<_Clos,_Tp>::size () const { return _M_closure.size (); } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::shift(int __n) const + { return valarray<_Tp>(_M_closure).shift(__n); } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::cshift(int __n) const + { return valarray<_Tp>(_M_closure).cshift(__n); } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const + { return valarray<_Tp>(_M_closure).apply(__f); } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const + { return valarray<_Tp>(_M_closure).apply(__f); } + + // XXX: replace this with a more robust summation algorithm. + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos,_Tp>::sum () const + { + size_t __n = _M_closure.size(); + if (__n == 0) return _Tp(); + else { + _Tp __s = _M_closure[--__n]; + while (__n != 0) __s += _M_closure[--__n]; + return __s; + } + } + + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos, _Tp>::min() const + { return __valarray_min(_M_closure); } + + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos, _Tp>::max() const + { return __valarray_max(_M_closure); } + + template<class _Dom, typename _Tp> + inline _Expr<_UnClos<logical_not,_Expr,_Dom>, bool> + _Expr<_Dom,_Tp>::operator! () const + { + typedef _UnClos<logical_not,_Expr,_Dom> _Closure; + return _Expr<_Closure,_Tp> (_Closure(this->_M_closure)); + } + +#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ +template<class _Dom, typename _Tp> \ +inline _Expr<_UnClos<_Name,_Expr,_Dom>,_Tp> \ +_Expr<_Dom,_Tp>::operator _Op () const \ +{ \ + typedef _UnClos<_Name,_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> (_Closure (this->_M_closure)); \ +} + + _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus) + _DEFINE_EXPR_UNARY_OPERATOR(-, negate) + _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not) + +#undef _DEFINE_EXPR_UNARY_OPERATOR + + +#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ +template<class _Dom1, class _Dom2> \ +inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \ + typename _Name<typename _Dom1::value_type>::result_type> \ +operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ +{ \ + typedef typename _Dom1::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v (), __w ())); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \ + typename _Name<typename _Dom::value_type>::result_type> \ +operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v (), __t)); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Name<typename _Dom::value_type>::result_type> \ +operator _Op (const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__t, __v ())); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \ + typename _Name<typename _Dom::value_type>::result_type> \ +operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray<typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__e (), __v)); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Name<typename _Dom::value_type>::result_type> \ +operator _Op (const valarray<typename _Dom::value_type>& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef typename _Name<_Tp>::result_type _Value; \ + typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \ +} + + _DEFINE_EXPR_BINARY_OPERATOR(+, plus) + _DEFINE_EXPR_BINARY_OPERATOR(-, minus) + _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies) + _DEFINE_EXPR_BINARY_OPERATOR(/, divides) + _DEFINE_EXPR_BINARY_OPERATOR(%, modulus) + _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor) + _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and) + _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or) + _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left) + _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right) + +#undef _DEFINE_EXPR_BINARY_OPERATOR + +#define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name) \ +template<class _Dom1, class _Dom2> \ +inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool> \ +operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ +{ \ + typedef typename _Dom1::value_type _Arg; \ + typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__v (), __w ())); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \ + bool> \ +operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__v (), __t)); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \ + bool> \ +operator _Op (const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__t, __v ())); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \ + bool> \ +operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray<typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__e (), __v)); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \ + bool> \ +operator _Op (const valarray<typename _Dom::value_type>& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__v, __e ())); \ +} + + _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and) + _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or) + _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to) + _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to) + _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less) + _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater) + _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal) + _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal) + +#undef _DEFINE_EXPR_RELATIONAL_OPERATOR + + + +#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ +template<class _Dom> \ +inline _Expr<_UnFunClos<_Expr,_Dom>,typename _Dom::value_type> \ +_Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _UnFunClos<_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e(), (_Tp(*)(_Tp))(&_Name))); \ +} \ + \ +template<typename _Tp> \ +inline _Expr<_UnFunClos<_ValArray,_Tp>,_Tp> \ +_Name(const valarray<_Tp>& __v) \ +{ \ + typedef _UnFunClos<_ValArray,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> (_Closure (__v, (_Tp(*)(_Tp))(&_Name))); \ +} + + + _DEFINE_EXPR_UNARY_FUNCTION(abs) + _DEFINE_EXPR_UNARY_FUNCTION(cos) + _DEFINE_EXPR_UNARY_FUNCTION(acos) + _DEFINE_EXPR_UNARY_FUNCTION(cosh) + _DEFINE_EXPR_UNARY_FUNCTION(sin) + _DEFINE_EXPR_UNARY_FUNCTION(asin) + _DEFINE_EXPR_UNARY_FUNCTION(sinh) + _DEFINE_EXPR_UNARY_FUNCTION(tan) + _DEFINE_EXPR_UNARY_FUNCTION(tanh) + _DEFINE_EXPR_UNARY_FUNCTION(atan) + _DEFINE_EXPR_UNARY_FUNCTION(exp) + _DEFINE_EXPR_UNARY_FUNCTION(log) + _DEFINE_EXPR_UNARY_FUNCTION(log10) + _DEFINE_EXPR_UNARY_FUNCTION(sqrt) + +#undef _DEFINE_EXPR_UNARY_FUNCTION + + +#define _DEFINE_EXPR_BINARY_FUNCTION(_Name) \ +template<class _Dom1, class _Dom2> \ +inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\ +_Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \ +{ \ + typedef typename _Dom1::value_type _Tp; \ + typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \ + typename _Dom::value_type> \ +_Name (const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray<typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ +_Name (const valarray<typename _Dom::valarray>& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \ + typename _Dom::value_type> \ +_Name (const _Expr<_Dom, typename _Dom::value_type>& __e, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ +_Name (const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<typename _Tp> \ +inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ +_Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ +{ \ + typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name))); \ +} \ + \ +template<typename _Tp> \ +inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp> \ +_Name (const valarray<_Tp>& __v, const _Tp& __t) \ +{ \ + typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name))); \ +} \ + \ +template<typename _Tp> \ +inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp> \ +_Name (const _Tp& __t, const valarray<_Tp>& __v) \ +{ \ + typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name))); \ +} + +_DEFINE_EXPR_BINARY_FUNCTION(atan2) +_DEFINE_EXPR_BINARY_FUNCTION(pow) + +#undef _DEFINE_EXPR_BINARY_FUNCTION + +} // std:: + + +#endif /* _CPP_VALARRAY_META_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/libstdc++-v3/include/ext/bvector b/libstdc++-v3/include/ext/bvector new file mode 100644 index 00000000000..2ece99c7160 --- /dev/null +++ b/libstdc++-v3/include/ext/bvector @@ -0,0 +1,52 @@ +/* + * + * 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 <bits/stl_range_errors.h> +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +#include <bits/std_vector.h> +#else +#include <bits/std_algobase.h> +#include <bits/atl_alloc.h> +#endif + +#include <ext/stl_bvector.h> + +#ifdef __STL_USE_NAMESPACES + +using __STD::bit_vector; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_BVECTOR_H */ + +// Local Variables: +// mode:C++ +// End: + + diff --git a/libstdc++-v3/include/ext/hash_map b/libstdc++-v3/include/ext/hash_map new file mode 100644 index 00000000000..ae3cf2672bc --- /dev/null +++ b/libstdc++-v3/include/ext/hash_map @@ -0,0 +1,524 @@ +/* + * 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 <ext/stl_hashtable.h> + +__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 _Key, class _Tp, + class _HashFcn = hash<_Key>, + class _EqualKey = equal_to<_Key>, + class _Alloc = allocator<_Tp> > +class hash_map; + +template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> +inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&, + const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&); + +template <class _Key, class _Tp, class _HashFcn, class _EqualKey, + class _Alloc> +class hash_map +{ +private: + typedef hashtable<pair<const _Key,_Tp>,_Key,_HashFcn, + _Select1st<pair<const _Key,_Tp> >,_EqualKey,_Alloc> _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_map(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + +#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 <class _K1, class _T1, class _HF, class _EqK, class _Al> + friend bool operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, + const hash_map<_K1, _T1, _HF, _EqK, _Al>&); +#else /* __STL_MEMBER_TEMPLATES */ + friend bool __STD_QUALIFIER + operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); +#endif /* __STL_MEMBER_TEMPLATES */ + +#include <bits/concept_checks.h> + + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } + +public: + pair<iterator,bool> insert(const value_type& __obj) + { return _M_ht.insert_unique(__obj); } +#ifdef __STL_MEMBER_TEMPLATES + template <class _InputIterator> + 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<iterator,bool> insert_noresize(const value_type& __obj) + { return _M_ht.insert_unique_noresize(__obj); } + + iterator find(const key_type& __key) { return _M_ht.find(__key); } + const_iterator find(const key_type& __key) const + { return _M_ht.find(__key); } + + _Tp& operator[](const key_type& __key) { + return _M_ht.find_or_insert(value_type(__key, _Tp())).second; + } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair<iterator, iterator> equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> +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 <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> +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 <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> +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 _Key, class _Tp, + class _HashFcn = hash<_Key>, + class _EqualKey = equal_to<_Key>, + class _Alloc = allocator<_Tp> > +class hash_multimap; + +template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> +inline bool +operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2); + +template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc> +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<pair<const _Key, _Tp>, _Key, _HashFcn, + _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> + _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_multimap(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + +#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 <class _K1, class _T1, class _HF, class _EqK, class _Al> + friend bool operator== (const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, + const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); +#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 <class _InputIterator> + 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<iterator, iterator> equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +public: + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> +inline bool +operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) +{ + return __hm1._M_ht == __hm2._M_ht; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> +inline bool +operator!=(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { + return !(__hm1 == __hm2); +} + +template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> +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 _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> +class insert_iterator<hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { +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 _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> +class insert_iterator<hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { +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: diff --git a/libstdc++-v3/include/ext/hash_set b/libstdc++-v3/include/ext/hash_set new file mode 100644 index 00000000000..24869cd030c --- /dev/null +++ b/libstdc++-v3/include/ext/hash_set @@ -0,0 +1,516 @@ +/* + * 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 <ext/stl_hashtable.h> + +#include <bits/concept_checks.h> + +__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 _Value, + class _HashFcn = hash<_Value>, + class _EqualKey = equal_to<_Value>, + class _Alloc = allocator<_Value> > +class hash_set; + +template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> +inline bool +operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2); + +template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> +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 <class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } +#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 <class _Val, class _HF, class _EqK, class _Al> + friend bool operator== (const hash_set<_Val, _HF, _EqK, _Al>&, + const hash_set<_Val, _HF, _EqK, _Al>&); +#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<iterator, bool> insert(const value_type& __obj) + { + pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj); + return pair<iterator,bool>(__p.first, __p.second); + } +#ifdef __STL_MEMBER_TEMPLATES + template <class _InputIterator> + 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<iterator, bool> insert_noresize(const value_type& __obj) + { + pair<typename _Ht::iterator, bool> __p = + _M_ht.insert_unique_noresize(__obj); + return pair<iterator, bool>(__p.first, __p.second); + } + + iterator find(const key_type& __key) const { return _M_ht.find(__key); } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair<iterator, iterator> equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +public: + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> +inline bool +operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + return __hs1._M_ht == __hs2._M_ht; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> +inline bool +operator!=(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { + return !(__hs1 == __hs2); +} + +template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> +inline void +swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + __hs1.swap(__hs2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template <class _Value, + class _HashFcn = hash<_Value>, + class _EqualKey = equal_to<_Value>, + class _Alloc = allocator<_Value> > +class hash_multiset; + +template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> +inline bool +operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2); + + +template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> +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 <class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } +#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 <class _Val, class _HF, class _EqK, class _Al> + friend bool operator== (const hash_multiset<_Val, _HF, _EqK, _Al>&, + const hash_multiset<_Val, _HF, _EqK, _Al>&); +#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 <class _InputIterator> + 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<iterator, iterator> equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +public: + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> +inline bool +operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + return __hs1._M_ht == __hs2._M_ht; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> +inline bool +operator!=(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { + return !(__hs1 == __hs2); +} + +template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> +inline void +swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { + __hs1.swap(__hs2); +} + +#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 _Value, class _HashFcn, class _EqualKey, class _Alloc> +class insert_iterator<hash_set<_Value, _HashFcn, _EqualKey, _Alloc> > { +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 _Value, class _HashFcn, class _EqualKey, class _Alloc> +class insert_iterator<hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> > { +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: diff --git a/libstdc++-v3/include/ext/rope b/libstdc++-v3/include/ext/rope new file mode 100644 index 00000000000..3779defea2b --- /dev/null +++ b/libstdc++-v3/include/ext/rope @@ -0,0 +1,32 @@ +/* + * 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 <bits/stl_algobase.h> +#include <bits/stl_tempbuf.h> +#include <bits/stl_algo.h> +#include <bits/stl_function.h> +#include <bits/stl_numeric.h> +#include <bits/stl_alloc.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> +#include <ext/stl_hash_fun.h> +#include <ext/stl_rope.h> + +#endif /* __SGI_STL_ROPE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/ext/ropeimpl.h b/libstdc++-v3/include/ext/ropeimpl.h new file mode 100644 index 00000000000..cc4d7bc679e --- /dev/null +++ b/libstdc++-v3/include/ext/ropeimpl.h @@ -0,0 +1,1587 @@ +/* + * 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 <bits/std_cstdio.h> + +#ifdef __STL_USE_NEW_IOSTREAMS +# include <iostream> +#else /* __STL_USE_NEW_IOSTREAMS */ +# include <bits/std_iostream.h> +#endif /* __STL_USE_NEW_IOSTREAMS */ + +#ifdef __STL_USE_EXCEPTIONS +# include <bits/std_stdexcept.h> +#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 <class _CharT, class _Alloc> +void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( + _Rope_iterator_base<_CharT,_Alloc>& __x) +{ + const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index]; + size_t __leaf_pos = __x._M_leaf_pos; + size_t __pos = __x._M_current_pos; + + switch(__leaf->_M_tag) { + case _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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr +(_Rope_iterator_base<_CharT,_Alloc>& __x) +{ + int __current_index = __x._M_leaf_index; + const _RopeRep* __current_node = __x._M_path_end[__current_index]; + size_t __len = __current_node->_M_size; + size_t __node_start_pos = __x._M_leaf_pos; + unsigned char __dirns = __x._M_path_directions; + _Rope_RopeConcatenation<_CharT,_Alloc>* __c; + + __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 <class _CharT, class _Alloc> +void _Rope_iterator_base<_CharT,_Alloc>::_M_incr(size_t __n) { + _M_current_pos += __n; + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_end - _M_buf_ptr; + if (__chars_left > __n) { + _M_buf_ptr += __n; + } else if (__chars_left == __n) { + _M_buf_ptr += __n; + _S_setcache_for_incr(*this); + } else { + _M_buf_ptr = 0; + } + } +} + +template <class _CharT, class _Alloc> +void _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) { + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_ptr - _M_buf_start; + if (__chars_left >= __n) { + _M_buf_ptr -= __n; + } else { + _M_buf_ptr = 0; + } + } + _M_current_pos -= __n; +} + +template <class _CharT, class _Alloc> +void _Rope_iterator<_CharT,_Alloc>::_M_check() { + if (_M_root_rope->_M_tree_ptr != _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 <class _CharT, class _Alloc> +inline +_Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator( + const _Rope_iterator<_CharT,_Alloc>& __x) +: _Rope_iterator_base<_CharT,_Alloc>(__x) +{ } + +template <class _CharT, class _Alloc> +inline _Rope_iterator<_CharT,_Alloc>::_Rope_iterator( + rope<_CharT,_Alloc>& __r, size_t __pos) +: _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos), + _M_root_rope(&__r) +{ + _RopeRep::_S_ref(_M_root); +} + +template <class _CharT, class _Alloc> +inline size_t +rope<_CharT,_Alloc>::_S_char_ptr_len(const _CharT* __s) +{ + const _CharT* __p = __s; + + while (!_S_is0(*__p)) { ++__p; } + return (__p - __s); +} + + +#ifndef __GC + +template <class _CharT, class _Alloc> +inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string() +{ + _CharT* __cstr = _M_c_string; + if (0 != __cstr) { + size_t __size = _M_size + 1; + destroy(__cstr, __cstr + __size); + _Data_deallocate(__cstr, __size); + } +} + + +template <class _CharT, class _Alloc> +#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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +#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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +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 _CharT> +class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> { + private: + _CharT* _M_buf_ptr; + public: + + _Rope_flatten_char_consumer(_CharT* __buffer) { + _M_buf_ptr = __buffer; + }; + ~_Rope_flatten_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + uninitialized_copy_n(__leaf, __n, _M_buf_ptr); + _M_buf_ptr += __n; + return true; + } +}; + +template<class _CharT> +class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { + private: + _CharT _M_pattern; + public: + size_t _M_count; // Number of nonmatching characters + _Rope_find_char_char_consumer(_CharT __p) + : _M_pattern(__p), _M_count(0) {} + ~_Rope_find_char_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + size_t __i; + for (__i = 0; __i < __n; __i++) { + if (__leaf[__i] == _M_pattern) { + _M_count += __i; return false; + } + } + _M_count += __n; return true; + } +}; + +#ifdef __STL_USE_NEW_IOSTREAMS + template<class _CharT, class _Traits> + // Here _CharT is both the stream and rope character type. +#else + template<class _CharT> + // 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<class _CharT, class _Traits> + bool _Rope_insert_char_consumer<_CharT, _Traits>::operator() + (const _CharT* __leaf, size_t __n) + { + size_t __i; + // We assume that formatting is set up correctly for each element. + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); + return true; + } + +#else + template<class _CharT> + 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<char>::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 <class _CharT, class _Alloc> +bool rope<_CharT, _Alloc>::_S_apply_to_pieces( + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end) +{ + if (0 == __r) return true; + switch(__r->_M_tag) { + case _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<class _CharT, class _Traits> + 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 <class _CharT> inline bool _Rope_is_simple(_CharT*) { return false; } +inline bool _Rope_is_simple(char*) { return true; } +inline bool _Rope_is_simple(wchar_t*) { return true; } + +#ifdef __STL_USE_NEW_IOSTREAMS + template<class _CharT, class _Traits, class _Alloc> + basic_ostream<_CharT, _Traits>& operator<< + (basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r) +#else + template<class _CharT, class _Alloc> + 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 <class _CharT, class _Alloc> +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer) +{ + _Rope_flatten_char_consumer<_CharT> __c(__buffer); + _S_apply_to_pieces(__c, __r, __start, __start + __len); + return(__buffer + __len); +} + +template <class _CharT, class _Alloc> +size_t +rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const +{ + _Rope_find_char_char_consumer<_CharT> __c(__pattern); + _S_apply_to_pieces(__c, _M_tree_ptr, __start, size()); + size_type __result_pos = __start + __c._M_count; +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; +} + +template <class _CharT, class _Alloc> +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) +{ + if (0 == __r) return __buffer; + switch(__r->_M_tag) { + case _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 <class _CharT, class _Alloc> +void +rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) +{ + for (int __i = 0; __i < __indent; __i++) putchar(' '); + if (0 == __r) { + printf("NULL\n"); return; + } + if (_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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +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 <class _CharT, class _Alloc> +void +rope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) +{ + if (__r->_M_is_balanced) { + _S_add_leaf_to_forest(__r, __forest); + return; + } + __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 <class _CharT, class _Alloc> +void +rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) +{ + _RopeRep* __insertee; // included in refcount + _RopeRep* __too_tiny = 0; // included in refcount + int __i; // forest[0..__i-1] is empty + size_t __s = __r->_M_size; + + for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) { + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +# endif + __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + } + } + { +# ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +# endif + __insertee = _S_concat_and_set_balanced(__too_tiny, __r); + } + // Too_tiny dead, and no longer included in refcount. + // Insertee is live and included. + __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 <class _CharT, class _Alloc> +_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 <class _CharT, class _Alloc> +_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 <class _CharT, class _Alloc> +int +rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, + const _RopeRep* __right) +{ + size_t __left_len; + size_t __right_len; + + if (0 == __right) return 0 != __left; + if (0 == __left) return -1; + __left_len = __left->_M_size; + __right_len = __right->_M_size; + if (_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 <class _CharT, class _Alloc> +_Rope_char_ref_proxy<_CharT, _Alloc>& +_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) { + _RopeRep* __old = _M_root->_M_tree_ptr; +# ifndef __GC + // First check for the case in which everything is uniquely + // referenced. In that case we can do this destructively. + _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); + if (0 != __ptr) { + *__ptr = __c; + return *this; + } +# endif + _Self_destruct_ptr __left( + _My_rope::_S_substring(__old, 0, _M_pos)); + _Self_destruct_ptr __right( + _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size)); + _Self_destruct_ptr __result_left( + _My_rope::_S_destr_concat_char_iter(__left, &__c, 1)); + +# 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 <class _CharT, class _Alloc> +inline _Rope_char_ref_proxy<_CharT, _Alloc>::operator _CharT () const +{ + if (_M_current_valid) { + return _M_current; + } else { + return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); + } +} +template <class _CharT, class _Alloc> +_Rope_char_ptr_proxy<_CharT, _Alloc> +_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const { + return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); +} + +template <class _CharT, class _Alloc> +rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, + const allocator_type& __a) +: _Base(__a) +{ + rope<_CharT,_Alloc> __result; + const size_t __exponentiate_threshold = 32; + size_t __exponent; + size_t __rest; + _CharT* __rest_buffer; + _RopeRep* __remainder; + rope<_CharT,_Alloc> __remainder_rope; + + if (0 == __n) + return; + + __exponent = __n / __exponentiate_threshold; + __rest = __n % __exponentiate_threshold; + if (0 == __rest) { + __remainder = 0; + } else { + __rest_buffer = _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<class _CharT, class _Alloc> + _CharT rope<_CharT,_Alloc>::_S_empty_c_str[1]; + +template<class _CharT, class _Alloc> +const _CharT* rope<_CharT,_Alloc>::c_str() const { + if (0 == _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<class _CharT, class _Alloc> +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<class _Rope_iterator> // was templated on CharT and Alloc +void // VC++ workaround +_Rope_rotate(_Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) +{ + typedef typename _Rope_iterator::value_type _CharT; + typedef typename _Rope_iterator::_allocator_type _Alloc; + + __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<char,__STL_DEFAULT_ALLOCATOR(char)> __first, + _Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __middle, + _Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __last) { + _Rope_rotate(__first, __middle, __last); +} +#endif + +# if 0 +// Probably not useful for several reasons: +// - for SGIs 7.1 compiler and probably some others, +// this forces lots of rope<wchar_t, ...> instantiations, creating a +// code bloat and compile time problem. (Fixed in 7.2.) +// - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive +// for unicode strings. Unsigned short may be a better character +// type. +inline void rotate( + _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __first, + _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __middle, + _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __last) { + _Rope_rotate(__first, __middle, __last); +} +# endif + + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/ext/slist b/libstdc++-v3/include/ext/slist new file mode 100644 index 00000000000..ef0906279a9 --- /dev/null +++ b/libstdc++-v3/include/ext/slist @@ -0,0 +1,1048 @@ +/* + * 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 <bits/concept_checks.h> + +__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 <class _Tp> +struct _Slist_node : public _Slist_node_base +{ + _Tp _M_data; +}; + +struct _Slist_iterator_base +{ + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef forward_iterator_tag iterator_category; + + _Slist_node_base* _M_node; + + _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {} + void _M_incr() { _M_node = _M_node->_M_next; } + + bool operator==(const _Slist_iterator_base& __x) const { + return _M_node == __x._M_node; + } + bool operator!=(const _Slist_iterator_base& __x) const { + return _M_node != __x._M_node; + } +}; + +template <class _Tp, class _Ref, class _Ptr> +struct _Slist_iterator : public _Slist_iterator_base +{ + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + typedef _Slist_iterator<_Tp, _Ref, _Ptr> _Self; + + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _Slist_node<_Tp> _Node; + + _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 <class _Tp, class _Ref, class _Ptr> +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 _Tp, class _Allocator, bool _IsStatic> +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 _Tp, class _Allocator> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +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 <class _Tp, class _Alloc> +_Slist_node_base* +_Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first, + _Slist_node_base* __last_node) { + _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next); + while (__cur != __last_node) { + _Slist_node<_Tp>* __tmp = __cur; + __cur = (_Slist_node<_Tp>*) __cur->_M_next; + destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + __before_first->_M_next = __last_node; + return __last_node; +} + +template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +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 <class _InputIterator> + 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 <class _InputIterator> + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template <class _InputIterator> + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + +#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 <class _InIter> + 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 <class _Integer> + void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + __true_type) { + _M_insert_after_fill(__pos, __n, __x); + } + + template <class _InIter> + 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 <class _InIter> + 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 <class _InIter> + 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 <class _Predicate> + void remove_if(_Predicate __pred); + + template <class _BinaryPredicate> + void unique(_BinaryPredicate __pred); + + template <class _StrictWeakOrdering> + void merge(slist&, _StrictWeakOrdering); + + template <class _StrictWeakOrdering> + void sort(_StrictWeakOrdering __comp); +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template <class _Tp, class _Alloc> +slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x) +{ + if (&__x != this) { + _Node_base* __p1 = &this->_M_head; + _Node* __n1 = (_Node*) this->_M_head._M_next; + const _Node* __n2 = (const _Node*) __x._M_head._M_next; + while (__n1 && __n2) { + __n1->_M_data = __n2->_M_data; + __p1 = __n1; + __n1 = (_Node*) __n1->_M_next; + __n2 = (const _Node*) __n2->_M_next; + } + if (__n2 == 0) + this->_M_erase_after(__p1, 0); + else + _M_insert_after_range(__p1, const_iterator((_Node*)__n2), + const_iterator(0)); + } + return *this; +} + +template <class _Tp, class _Alloc> +void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { + _Node_base* __prev = &this->_M_head; + _Node* __node = (_Node*) this->_M_head._M_next; + for ( ; __node != 0 && __n > 0 ; --__n) { + __node->_M_data = __val; + __prev = __node; + __node = (_Node*) __node->_M_next; + } + if (__n > 0) + _M_insert_after_fill(__prev, __n, __val); + else + this->_M_erase_after(__prev, 0); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class _Tp, class _Alloc> template <class _InputIter> +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 <class _Tp, class _Alloc> +inline bool +operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) +{ + typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = _SL1.end(); + const_iterator __end2 = _SL2.end(); + + const_iterator __i1 = _SL1.begin(); + const_iterator __i2 = _SL2.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; +} + + +template <class _Tp, class _Alloc> +inline bool +operator<(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) +{ + return lexicographical_compare(_SL1.begin(), _SL1.end(), + _SL2.begin(), _SL2.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Tp, class _Alloc> +inline bool +operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return !(_SL1 == _SL2); +} + +template <class _Tp, class _Alloc> +inline bool +operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return _SL2 < _SL1; +} + +template <class _Tp, class _Alloc> +inline bool +operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return !(_SL2 < _SL1); +} + +template <class _Tp, class _Alloc> +inline bool +operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return !(_SL1 < _SL2); +} + +template <class _Tp, class _Alloc> +inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x) +{ + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next != 0 && __len > 0) { + --__len; + __cur = __cur->_M_next; + } + if (__cur->_M_next) + this->_M_erase_after(__cur, 0); + else + _M_insert_after_fill(__cur, __len, __x); +} + +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::remove(const _Tp& __val) +{ + _Node_base* __cur = &this->_M_head; + while (__cur && __cur->_M_next) { + if (((_Node*) __cur->_M_next)->_M_data == __val) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } +} + +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::unique() +{ + _Node_base* __cur = this->_M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (((_Node*)__cur)->_M_data == + ((_Node*)(__cur->_M_next))->_M_data) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } +} + +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x) +{ + _Node_base* __n1 = &this->_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (((_Node*) __x._M_head._M_next)->_M_data < + ((_Node*) __n1->_M_next)->_M_data) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } +} + +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::sort() +{ + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + this->swap(__counter[__fill-1]); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class _Tp, class _Alloc> +template <class _Predicate> +void slist<_Tp,_Alloc>::remove_if(_Predicate __pred) +{ + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next) { + if (__pred(((_Node*) __cur->_M_next)->_M_data)) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } +} + +template <class _Tp, class _Alloc> template <class _BinaryPredicate> +void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred) +{ + _Node* __cur = (_Node*) this->_M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (__pred(((_Node*)__cur)->_M_data, + ((_Node*)(__cur->_M_next))->_M_data)) + this->_M_erase_after(__cur); + else + __cur = (_Node*) __cur->_M_next; + } + } +} + +template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x, + _StrictWeakOrdering __comp) +{ + _Node_base* __n1 = &this->_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (__comp(((_Node*) __x._M_head._M_next)->_M_data, + ((_Node*) __n1->_M_next)->_M_data)) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } +} + +template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> +void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp) +{ + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + this->swap(__counter[__fill-1]); + } +} + +#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 _Tp, class _Alloc> +class insert_iterator<slist<_Tp, _Alloc> > { +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: diff --git a/libstdc++-v3/include/ext/stl_bvector.h b/libstdc++-v3/include/ext/stl_bvector.h new file mode 100644 index 00000000000..5e64f3889c8 --- /dev/null +++ b/libstdc++-v3/include/ext/stl_bvector.h @@ -0,0 +1,896 @@ +/* + * + * 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<bool, ptrdiff_t> +{ + 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 _Allocator, bool __is_static> +class _Bvector_alloc_base { +public: + typedef typename _Alloc_traits<bool, _Allocator>::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<unsigned int, _Allocator>::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 _Allocator> +class _Bvector_alloc_base<_Allocator, true> { +public: + typedef typename _Alloc_traits<bool, _Allocator>::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<unsigned int, _Allocator>::_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 _Alloc> +class _Bvector_base + : public _Bvector_alloc_base<_Alloc, + _Alloc_traits<bool, _Alloc>::_S_instanceless> +{ + typedef _Bvector_alloc_base<_Alloc, + _Alloc_traits<bool, _Alloc>::_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 _Alloc> +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<unsigned int, _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<T, Alloc> 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<bool, _Alloc> +# define __VECTOR vector +# define __BVECTOR_BASE _Bvector_base<_Alloc> +# define __BVECTOR_TMPL_LIST template <class _Alloc> + __STL_END_NAMESPACE +# include <bits/stl_vector.h> + __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_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<const_iterator, value_type, const_reference, + difference_type> const_reverse_iterator; + typedef reverse_iterator<iterator, value_type, reference, difference_type> + 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 <class _InputIterator> + 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 <class _ForwardIterator> + 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 <class _InputIterator> + void _M_insert_range(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) { + for ( ; __first != __last; ++__first) { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template <class _ForwardIterator> + void _M_insert_range(iterator __position, + _ForwardIterator __first, _ForwardIterator __last, + 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<bool>"); + } + + 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 <class _Integer> + 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 <class _InputIterator> + void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_initialize_range(__first, __last, __ITERATOR_CATEGORY(__first)); + } + + template <class _InputIterator> + __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 <class _InputIterator> + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_t) __n, (bool) __val); } + + template <class _InputIter> + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template <class _InputIterator> + 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 <class _ForwardIterator> + 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 <class _Integer> + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + _M_fill_insert(__pos, __n, __x); + } + + template <class _InputIterator> + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + _M_insert_range(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); + } + + template <class _InputIterator> + 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<bool, alloc> 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: diff --git a/libstdc++-v3/include/ext/stl_hash_fun.h b/libstdc++-v3/include/ext/stl_hash_fun.h new file mode 100644 index 00000000000..3144e6a07f1 --- /dev/null +++ b/libstdc++-v3/include/ext/stl_hash_fun.h @@ -0,0 +1,93 @@ +/* + * 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 _CPP_BITS_STL_HASH_FUN_H +#define _CPP_BITS_STL_HASH_FUN_H 1 + +#include <bits/std_cstddef.h> + +__STL_BEGIN_NAMESPACE + +template <class _Key> struct hash { }; + +inline size_t __stl_hash_string(const char* __s) +{ + unsigned long __h = 0; + for ( ; *__s; ++__s) + __h = 5*__h + *__s; + + return size_t(__h); +} + +__STL_TEMPLATE_NULL struct hash<char*> +{ + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } +}; + +__STL_TEMPLATE_NULL struct hash<const char*> +{ + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } +}; + +__STL_TEMPLATE_NULL struct hash<char> { + size_t operator()(char __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash<unsigned char> { + size_t operator()(unsigned char __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash<signed char> { + size_t operator()(unsigned char __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash<short> { + size_t operator()(short __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash<unsigned short> { + size_t operator()(unsigned short __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash<int> { + size_t operator()(int __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash<unsigned int> { + size_t operator()(unsigned int __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash<long> { + size_t operator()(long __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash<unsigned long> { + size_t operator()(unsigned long __x) const { return __x; } +}; + +__STL_END_NAMESPACE + +#endif /* _CPP_BITS_STL_HASH_FUN_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/ext/stl_hashtable.h b/libstdc++-v3/include/ext/stl_hashtable.h new file mode 100644 index 00000000000..ab5cf5203b1 --- /dev/null +++ b/libstdc++-v3/include/ext/stl_hashtable.h @@ -0,0 +1,1054 @@ +/* + * 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 <bits/stl_algobase.h> +#include <bits/stl_alloc.h> +#include <bits/stl_construct.h> +#include <bits/stl_tempbuf.h> +#include <bits/stl_algo.h> +#include <bits/stl_uninitialized.h> +#include <bits/stl_function.h> +#include <bits/stl_vector.h> +#include <ext/stl_hash_fun.h> + +__STL_BEGIN_NAMESPACE + +template <class _Val> +struct _Hashtable_node +{ + _Hashtable_node* _M_next; + _Val _M_val; +}; + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc = alloc> +class hashtable; + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_iterator; + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_const_iterator; + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _Val& reference; + typedef _Val* pointer; + + _Node* _M_cur; + _Hashtable* _M_ht; + + _Hashtable_iterator(_Node* __n, _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_iterator() {} + reference operator*() const { return _M_cur->_M_val; } +#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 <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_const_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn, + _ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef const _Val& reference; + typedef const _Val* pointer; + + const _Node* _M_cur; + const _Hashtable* _M_ht; + + _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_const_iterator() {} + _Hashtable_const_iterator(const iterator& __it) + : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {} + reference operator*() const { return _M_cur->_M_val; } +#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 _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +class hashtable; + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2); + + +// Hashtables handle allocators a bit differently than other containers +// do. If we're using standard-conforming allocators, then a hashtable +// unconditionally has a member variable to hold its allocator, even if +// it so happens that all instances of the allocator type are identical. +// This is because, for hashtables, this extra storage is negligible. +// Additionally, a base class wouldn't serve any other purposes; it +// wouldn't, for example, simplify the exception-handling code. + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +class hashtable { +public: + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + hasher hash_funct() const { return _M_hash; } + key_equal key_eq() const { return _M_equals; } + +private: + typedef _Hashtable_node<_Val> _Node; + +#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 <class _Vl, class _Ky, class _HF, class _Ex, class _Eq, class _Al> + friend bool operator== (const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, + const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); +#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<iterator, bool> insert_unique(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_unique_noresize(__obj); + } + + iterator insert_equal(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_equal_noresize(__obj); + } + + pair<iterator, bool> insert_unique_noresize(const value_type& __obj); + iterator insert_equal_noresize(const value_type& __obj); + +#ifdef __STL_MEMBER_TEMPLATES + template <class _InputIterator> + void insert_unique(_InputIterator __f, _InputIterator __l) + { + insert_unique(__f, __l, __ITERATOR_CATEGORY(__f)); + } + + template <class _InputIterator> + void insert_equal(_InputIterator __f, _InputIterator __l) + { + insert_equal(__f, __l, __ITERATOR_CATEGORY(__f)); + } + + template <class _InputIterator> + void insert_unique(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_unique(*__f); + } + + template <class _InputIterator> + void insert_equal(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_equal(*__f); + } + + template <class _ForwardIterator> + void insert_unique(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + template <class _ForwardIterator> + void insert_equal(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = 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<iterator, iterator> + equal_range(const key_type& __key); + + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const; + + size_type erase(const key_type& __key); + void erase(const iterator& __it); + void erase(iterator __first, iterator __last); + + void erase(const const_iterator& __it); + void erase(const_iterator __first, const_iterator __last); + + void resize(size_type __num_elements_hint); + void clear(); + +private: + size_type _M_next_size(size_type __n) const + { return __stl_next_prime(__n); } + + void _M_initialize_buckets(size_type __n) + { + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + _M_num_elements = 0; + } + + size_type _M_bkt_num_key(const key_type& __key) const + { + return _M_bkt_num_key(__key, _M_buckets.size()); + } + + size_type _M_bkt_num(const value_type& __obj) const + { + return _M_bkt_num_key(_M_get_key(__obj)); + } + + size_type _M_bkt_num_key(const key_type& __key, size_t __n) const + { + return _M_hash(__key) % __n; + } + + size_type _M_bkt_num(const value_type& __obj, size_t __n) const + { + return _M_bkt_num_key(_M_get_key(__obj), __n); + } + + _Node* _M_new_node(const value_type& __obj) + { + _Node* __n = _M_get_node(); + __n->_M_next = 0; + __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 <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() +{ + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) +{ + iterator __tmp = *this; + ++*this; + return __tmp; +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() +{ + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) +{ + const_iterator __tmp = *this; + ++*this; + return __tmp; +} + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline forward_iterator_tag +iterator_category(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return forward_iterator_tag(); +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Val* +value_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (_Val*) 0; +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +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 <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline forward_iterator_tag +iterator_category(const _Hashtable_const_iterator<_Val,_Key,_HF, + _ExK,_EqK,_All>&) +{ + return forward_iterator_tag(); +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Val* +value_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (_Val*) 0; +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +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 <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) +{ + typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; + if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) + return false; + for (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 <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { + return !(__ht1 == __ht2); +} + +template <class _Val, class _Key, class _HF, class _Extract, class _EqKey, + class _All> +inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { + __ht1.swap(__ht2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_unique_noresize(const value_type& __obj) +{ + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return pair<iterator, bool>(iterator(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return pair<iterator, bool>(iterator(__tmp, this), true); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_equal_noresize(const value_type& __obj) +{ + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __cur->_M_next; + __cur->_M_next = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); + } + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj) +{ + resize(_M_num_elements + 1); + + size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return __cur->_M_val; + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return __tmp->_M_val; +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key) +{ + typedef pair<iterator, iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(iterator(__first, this), iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(iterator(__first, this), + iterator(_M_buckets[__m], this)); + return _Pii(iterator(__first, this), end()); + } + return _Pii(end(), end()); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::equal_range(const key_type& __key) const +{ + typedef pair<const_iterator, const_iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (const _Node* __first = _M_buckets[__n] ; + __first; + __first = __first->_M_next) { + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (const _Node* __cur = __first->_M_next; + __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(const_iterator(__first, this), + const_iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(const_iterator(__first, this), + const_iterator(_M_buckets[__m], this)); + return _Pii(const_iterator(__first, this), end()); + } + } + return _Pii(end(), end()); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key) +{ + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + size_type __erased = 0; + + if (__first) { + _Node* __cur = __first; + _Node* __next = __cur->_M_next; + while (__next) { + if (_M_equals(_M_get_key(__next->_M_val), __key)) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + ++__erased; + --_M_num_elements; + } + else { + __cur = __next; + __next = __cur->_M_next; + } + } + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + _M_buckets[__n] = __first->_M_next; + _M_delete_node(__first); + ++__erased; + --_M_num_elements; + } + } + return __erased; +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it) +{ + _Node* __p = __it._M_cur; + if (__p) { + const size_type __n = _M_bkt_num(__p->_M_val); + _Node* __cur = _M_buckets[__n]; + + if (__cur == __p) { + _M_buckets[__n] = __cur->_M_next; + _M_delete_node(__cur); + --_M_num_elements; + } + else { + _Node* __next = __cur->_M_next; + while (__next) { + if (__next == __p) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + --_M_num_elements; + break; + } + else { + __cur = __next; + __next = __cur->_M_next; + } + } + } + } +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::erase(iterator __first, iterator __last) +{ + size_type __f_bucket = __first._M_cur ? + _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); + size_type __l_bucket = __last._M_cur ? + _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); + + if (__first._M_cur == __last._M_cur) + return; + else if (__f_bucket == __l_bucket) + _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); + else { + _M_erase_bucket(__f_bucket, __first._M_cur, 0); + for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) + _M_erase_bucket(__n, 0); + if (__l_bucket != _M_buckets.size()) + _M_erase_bucket(__l_bucket, __last._M_cur); + } +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +inline void +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first, + const_iterator __last) +{ + erase(iterator(const_cast<_Node*>(__first._M_cur), + const_cast<hashtable*>(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast<hashtable*>(__last._M_ht))); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +inline void +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) +{ + erase(iterator(const_cast<_Node*>(__it._M_cur), + const_cast<hashtable*>(__it._M_ht))); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::resize(size_type __num_elements_hint) +{ + const size_type __old_n = _M_buckets.size(); + if (__num_elements_hint > __old_n) { + const size_type __n = _M_next_size(__num_elements_hint); + if (__n > __old_n) { + vector<_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 <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) +{ + _Node* __cur = _M_buckets[__n]; + if (__cur == __first) + _M_erase_bucket(__n, __last); + else { + _Node* __next; + for (__next = __cur->_M_next; + __next != __first; + __cur = __next, __next = __cur->_M_next) + ; + while (__next != __last) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; + } + } +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __last) +{ + _Node* __cur = _M_buckets[__n]; + while (__cur != __last) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + _M_buckets[__n] = __cur; + --_M_num_elements; + } +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear() +{ + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + } + _M_buckets[__i] = 0; + } + _M_num_elements = 0; +} + + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_copy_from(const hashtable& __ht) +{ + _M_buckets.clear(); + _M_buckets.reserve(__ht._M_buckets.size()); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); + __STL_TRY { + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + const _Node* __cur = __ht._M_buckets[__i]; + if (__cur) { + _Node* __local_copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = __local_copy; + + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) { + __local_copy->_M_next = _M_new_node(__next->_M_val); + __local_copy = __local_copy->_M_next; + } + } + } + _M_num_elements = __ht._M_num_elements; + } + __STL_UNWIND(clear()); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASHTABLE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/ext/stl_rope.h b/libstdc++-v3/include/ext/stl_rope.h new file mode 100644 index 00000000000..f317f3a6fbc --- /dev/null +++ b/libstdc++-v3/include/ext/stl_rope.h @@ -0,0 +1,2714 @@ +/* + * 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 <bits/stl_threads.h> +# define __GC_CONST // constant except for deallocation +# endif +# ifdef __STL_SGI_THREADS +# include <mutex.h> +# 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 <class _CharT> +inline _CharT _S_eos(_CharT*) { return _CharT(); } + +// Test for basic character types. +// For basic character types leaves having a trailing eos. +template <class _CharT> +inline bool _S_is_basic_char_type(_CharT*) { return false; } +template <class _CharT> +inline bool _S_is_one_byte_char_type(_CharT*) { return false; } + +inline bool _S_is_basic_char_type(char*) { return true; } +inline bool _S_is_one_byte_char_type(char*) { return true; } +inline bool _S_is_basic_char_type(wchar_t*) { return true; } + +// Store an eos iff _CharT is a basic character type. +// Do not reference _S_eos if it isn't. +template <class _CharT> +inline void _S_cond_store_eos(_CharT&) {} + +inline void _S_cond_store_eos(char& __c) { __c = 0; } +inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; } + +// char_producers are logically functions that generate a section of +// a string. These can be convereted to ropes. The resulting rope +// invokes the char_producer on demand. This allows, for example, +// files to be viewed as ropes without reading the entire file. +template <class _CharT> +class char_producer { + public: + virtual ~char_producer() {}; + virtual void operator()(size_t __start_pos, size_t __len, + _CharT* __buffer) = 0; + // Buffer should really be an arbitrary output iterator. + // That way we could flatten directly into an ostream, etc. + // This is thoroughly impossible, since iterator types don't + // have runtime descriptions. +}; + +// Sequence buffers: +// +// Sequence must provide an append operation that appends an +// array to the sequence. Sequence buffers are useful only if +// appending an entire array is cheaper than appending element by element. +// This is true for many string representations. +// This should perhaps inherit from ostream<sequence::value_type> +// and be implemented correspondingly, so that they can be used +// for formatted. For the sake of portability, we don't do this yet. +// +// For now, sequence buffers behave as output iterators. But they also +// behave a little like basic_ostringstream<sequence::value_type> and a +// little like containers. + +template<class _Sequence, size_t _Buf_sz = 100 +# if defined(__sgi) && !defined(__GNUC__) +# define __TYPEDEF_WORKAROUND + ,class _V = typename _Sequence::value_type +# endif + > +// 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 _CharT> +class _Rope_char_consumer { + public: + // If we had member templates, these should not be virtual. + // For now we need to use run-time parametrization where + // compile-time would do. Hence this should all be private + // for now. + // The symmetry with char_producer is accidental and temporary. + virtual ~_Rope_char_consumer() {}; + virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; +}; + +// First a lot of forward declarations. The standard seems to require +// much stricter "declaration before use" than many of the implementations +// that preceded it. +template<class _CharT, class _Alloc=__STL_DEFAULT_ALLOCATOR(_CharT)> class rope; +template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation; +template<class _CharT, class _Alloc> struct _Rope_RopeLeaf; +template<class _CharT, class _Alloc> struct _Rope_RopeFunction; +template<class _CharT, class _Alloc> struct _Rope_RopeSubstring; +template<class _CharT, class _Alloc> class _Rope_iterator; +template<class _CharT, class _Alloc> class _Rope_const_iterator; +template<class _CharT, class _Alloc> class _Rope_char_ref_proxy; +template<class _CharT, class _Alloc> class _Rope_char_ptr_proxy; + +template<class _CharT, class _Alloc> +bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +_Rope_const_iterator<_CharT,_Alloc> operator- + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template<class _CharT, class _Alloc> +_Rope_const_iterator<_CharT,_Alloc> operator+ + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template<class _CharT, class _Alloc> +_Rope_const_iterator<_CharT,_Alloc> operator+ + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT,_Alloc>& __x); + +template<class _CharT, class _Alloc> +bool operator== + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +bool operator< + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +ptrdiff_t operator- + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +_Rope_iterator<_CharT,_Alloc> operator- + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template<class _CharT, class _Alloc> +_Rope_iterator<_CharT,_Alloc> operator+ + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template<class _CharT, class _Alloc> +_Rope_iterator<_CharT,_Alloc> operator+ + (ptrdiff_t __n, + const _Rope_iterator<_CharT,_Alloc>& __x); + +template<class _CharT, class _Alloc> +bool operator== + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +bool operator< + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +ptrdiff_t operator- + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right); + +template<class _CharT, class _Alloc> +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right); + +template<class _CharT, class _Alloc> +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + _CharT __right); + +// Some helpers, so we can use power on ropes. +// See below for why this isn't local to the implementation. + +// This uses a nonstandard refcount convention. +// The result has refcount 0. +template<class _CharT, class _Alloc> +struct _Rope_Concat_fn + : public binary_function<rope<_CharT,_Alloc>, rope<_CharT,_Alloc>, + rope<_CharT,_Alloc> > { + rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x, + const rope<_CharT,_Alloc>& __y) { + return __x + __y; + } +}; + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc> +identity_element(_Rope_Concat_fn<_CharT, _Alloc>) +{ + return rope<_CharT,_Alloc>(); +} + + +// +// 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 _CharT, class _Allocator, bool _IsStatic> +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 _CharT, class _Allocator> +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 <class _CharT, class _Alloc> +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 _CharT, class _Alloc> +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<class _CharT, class _Alloc> +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<class _CharT, class _Alloc> +struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT,_Alloc> { + public: + // Apparently needed by VC++ + // The data fields of leaves are allocated with some + // extra space, to 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<class _CharT, class _Alloc> +struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> { + public: + _Rope_RopeRep<_CharT,_Alloc>* _M_left; + _Rope_RopeRep<_CharT,_Alloc>* _M_right; + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l, + _Rope_RopeRep<_CharT,_Alloc>* __r, + allocator_type __a) + + : _Rope_RopeRep<_CharT,_Alloc>(_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<class _CharT, class _Alloc> +struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> { + public: + char_producer<_CharT>* _M_fn; +# ifndef __GC + bool _M_delete_when_done; // Char_producer is owned by the + // rope and should be explicitly + // deleted when the rope becomes + // inaccessible. +# else + // In the GC case, we either register the rope for + // finalization, or not. Thus the field is unnecessary; + // the information is stored in the collector data structures. + // We do need a finalization procedure to be invoked by the + // collector. + static void _S_fn_finalization_proc(void * __tree, void *) { + delete ((_Rope_RopeFunction *)__tree) -> _M_fn; + } +# endif + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, + bool __d, allocator_type __a) + : _Rope_RopeRep<_CharT,_Alloc>(_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<class _CharT, class _Alloc> +struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT,_Alloc>, + public char_producer<_CharT> { + public: + // XXX this whole class should be rewritten. + _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 + size_t _M_start; + virtual void operator()(size_t __start_pos, size_t __req_len, + _CharT* __buffer) { + switch(_M_base->_M_tag) { + case _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<class _CharT, class _Alloc> + struct _Rope_self_destruct_ptr { + _Rope_RopeRep<_CharT,_Alloc>* _M_ptr; + ~_Rope_self_destruct_ptr() + { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); } +# ifdef __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 _CharT, class _Alloc> +class _Rope_char_ref_proxy { + friend class rope<_CharT,_Alloc>; + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; +# ifdef __GC + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef rope<_CharT,_Alloc> _My_rope; + size_t _M_pos; + _CharT _M_current; + bool _M_current_valid; + _My_rope* _M_root; // The whole rope. + public: + _Rope_char_ref_proxy(_My_rope* __r, size_t __p) + : _M_pos(__p), _M_current_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<class _CharT, class __Alloc> + inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { + _CharT __tmp = __a; + __a = __b; + __b = __tmp; + } +#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 _CharT, class _Alloc> +class _Rope_char_ptr_proxy { + // XXX this class should be rewritten. + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + size_t _M_pos; + rope<_CharT,_Alloc>* _M_root; // The whole rope. + public: + _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy() {} + _Rope_char_ptr_proxy(_CharT* __x) : _M_root(0), _M_pos(0) { + __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<class _CharT2, class _Alloc2> + 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 _CharT, class _Alloc> +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 _CharT, class _Alloc> class _Rope_iterator; + +template<class _CharT, class _Alloc> +class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; + protected: +# 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<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2,_Alloc2> operator- + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT2,_Alloc2>& __x); +#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<class _CharT2, class _Alloc2> + friend bool operator== + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend bool operator< + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend ptrdiff_t operator- + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); +#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 _CharT, class _Alloc> +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<class _CharT2, class _Alloc2> + friend bool operator== + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend bool operator< + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend ptrdiff_t operator- + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2,_Alloc2> operator- + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2,_Alloc2> operator+ + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2,_Alloc2> operator+ + (ptrdiff_t __n, + const _Rope_iterator<_CharT2,_Alloc2>& __x); +#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 _CharT, class _Allocator, bool _IsStatic> +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 _CharT, class _Allocator> +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 <class _CharT, class _Alloc> +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 _CharT, class _Alloc> +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 _CharT, class _Alloc> +class rope : public _Rope_base<_CharT,_Alloc> { + public: + typedef _CharT value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _CharT const_reference; + typedef const _CharT* const_pointer; + typedef _Rope_iterator<_CharT,_Alloc> iterator; + typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator; + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer; + + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_const_iterator<_CharT,_Alloc>; + friend struct _Rope_RopeRep<_CharT,_Alloc>; + friend class _Rope_iterator_base<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + friend struct _Rope_RopeSubstring<_CharT,_Alloc>; + + protected: + typedef _Rope_base<_CharT,_Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; +# 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_iterator> const_reverse_iterator; +# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<const_iterator, value_type, const_reference, + difference_type> 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<class _CharT2, class _Alloc2> + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, + const rope<_CharT2,_Alloc2>& __right); + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, + const _CharT2* __right); + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, _CharT2 __right); +#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<iterator> reverse_iterator; +# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<iterator, value_type, reference, + difference_type> 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 <class _CharT, class _Alloc> +const rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = + (size_type)(-1); + +template <class _CharT, class _Alloc> +inline bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root == __y._M_root); +} + +template <class _CharT, class _Alloc> +inline bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _CharT, class _Alloc> +inline bool operator!= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _CharT, class _Alloc> +inline bool operator> (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template <class _CharT, class _Alloc> +inline bool operator<= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _CharT, class _Alloc> +inline bool operator>= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template <class _CharT, class _Alloc> +inline ptrdiff_t operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template <class _CharT, class _Alloc> +inline _Rope_const_iterator<_CharT,_Alloc> +operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos - __n); +} + +template <class _CharT, class _Alloc> +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template <class _CharT, class _Alloc> +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template <class _CharT, class _Alloc> +inline bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root_rope == __y._M_root_rope); +} + +template <class _CharT, class _Alloc> +inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _CharT, class _Alloc> +inline bool operator!= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _CharT, class _Alloc> +inline bool operator> (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template <class _CharT, class _Alloc> +inline bool operator<= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _CharT, class _Alloc> +inline bool operator>= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template <class _CharT, class _Alloc> +inline ptrdiff_t operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template <class _CharT, class _Alloc> +inline _Rope_iterator<_CharT,_Alloc> +operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos - __n); +} + +template <class _CharT, class _Alloc> +inline _Rope_iterator<_CharT,_Alloc> +operator+(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template <class _CharT, class _Alloc> +inline _Rope_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ +# 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 <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ + __left.append(__right); + return __left; +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + 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 <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + __left.append(__right); + return __left; +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) { + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, &__right, 1)); +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) { + __left.append(__right); + return __left; +} + +template <class _CharT, class _Alloc> +bool +operator< (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) < 0; +} + +template <class _CharT, class _Alloc> +bool +operator== (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) == 0; +} + +template <class _CharT, class _Alloc> +inline bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _CharT, class _Alloc> +inline bool +operator!= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _CharT, class _Alloc> +inline bool +operator> (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template <class _CharT, class _Alloc> +inline bool +operator<= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _CharT, class _Alloc> +inline bool +operator>= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +template <class _CharT, class _Alloc> +inline bool operator!= (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifdef __STL_USE_NEW_IOSTREAMS + template<class _CharT, class _Traits, class _Alloc> + basic_ostream<_CharT, _Traits>& operator<< + (basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r); +#else + template<class _CharT, class _Alloc> + ostream& operator<< (ostream& __o, const rope<_CharT, _Alloc>& __r); +#endif + +typedef rope<char> crope; +typedef rope<wchar_t> wrope; + +inline crope::reference __mutable_reference_at(crope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _CharT, class _Alloc> +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<crope> +{ + size_t operator()(const crope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + + +__STL_TEMPLATE_NULL struct hash<wrope> +{ + size_t operator()(const wrope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +# include <ext/ropeimpl.h> + +# endif /* __SGI_STL_INTERNAL_ROPE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/ext/tree b/libstdc++-v3/include/ext/tree new file mode 100644 index 00000000000..f6faf976e34 --- /dev/null +++ b/libstdc++-v3/include/ext/tree @@ -0,0 +1,23 @@ + +/* + * 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 _CPP_EXT_TREE +#define _CPP_EXT_TREE 1 +#include <bits/stl_tree.h> +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++-v3/include/std/algorithm b/libstdc++-v3/include/std/algorithm new file mode 100644 index 00000000000..eebcdf22977 --- /dev/null +++ b/libstdc++-v3/include/std/algorithm @@ -0,0 +1,3 @@ +#ifndef _CPP_ALGORITHM +#include <bits/std_algorithm.h> +#endif diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset new file mode 100644 index 00000000000..e334ec96451 --- /dev/null +++ b/libstdc++-v3/include/std/bitset @@ -0,0 +1,3 @@ +#ifndef _CPP_BITSET +#include <bits/std_bitset.h> +#endif diff --git a/libstdc++-v3/include/std/cassert b/libstdc++-v3/include/std/cassert new file mode 100644 index 00000000000..bee254d55f1 --- /dev/null +++ b/libstdc++-v3/include/std/cassert @@ -0,0 +1,3 @@ +// This one should not have include guards. +#include <bits/std_cassert.h> + diff --git a/libstdc++-v3/include/std/cctype b/libstdc++-v3/include/std/cctype new file mode 100644 index 00000000000..d888a3f80ed --- /dev/null +++ b/libstdc++-v3/include/std/cctype @@ -0,0 +1,3 @@ +#ifndef _CPP_CCTYPE +#include <bits/std_cctype.h> +#endif diff --git a/libstdc++-v3/include/std/cerrno b/libstdc++-v3/include/std/cerrno new file mode 100644 index 00000000000..5d2cf1f61a4 --- /dev/null +++ b/libstdc++-v3/include/std/cerrno @@ -0,0 +1,3 @@ +#ifndef _CPP_CERRNO +#include <bits/std_cerrno.h> +#endif diff --git a/libstdc++-v3/include/std/cfloat b/libstdc++-v3/include/std/cfloat new file mode 100644 index 00000000000..c6cb35731a8 --- /dev/null +++ b/libstdc++-v3/include/std/cfloat @@ -0,0 +1,3 @@ +#ifndef _CPP_CFLOAT +#include <bits/std_cfloat.h> +#endif diff --git a/libstdc++-v3/include/std/ciso646 b/libstdc++-v3/include/std/ciso646 new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/libstdc++-v3/include/std/ciso646 diff --git a/libstdc++-v3/include/std/climits b/libstdc++-v3/include/std/climits new file mode 100644 index 00000000000..b7614847bbe --- /dev/null +++ b/libstdc++-v3/include/std/climits @@ -0,0 +1,3 @@ +#ifndef _CPP_CLIMITS +#include <bits/std_climits.h> +#endif diff --git a/libstdc++-v3/include/std/clocale b/libstdc++-v3/include/std/clocale new file mode 100644 index 00000000000..6ac636f8786 --- /dev/null +++ b/libstdc++-v3/include/std/clocale @@ -0,0 +1,3 @@ +#ifndef _CPP_CLOCALE +#include <bits/std_clocale.h> +#endif diff --git a/libstdc++-v3/include/std/cmath b/libstdc++-v3/include/std/cmath new file mode 100644 index 00000000000..783e76af1c5 --- /dev/null +++ b/libstdc++-v3/include/std/cmath @@ -0,0 +1,3 @@ +#ifndef _CPP_CMATH +#include <bits/std_cmath.h> +#endif diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex new file mode 100644 index 00000000000..2cc52f5531d --- /dev/null +++ b/libstdc++-v3/include/std/complex @@ -0,0 +1,3 @@ +#ifndef _CPP_COMPLEX +#include <bits/std_complex.h> +#endif diff --git a/libstdc++-v3/include/std/csetjmp b/libstdc++-v3/include/std/csetjmp new file mode 100644 index 00000000000..79531e3607a --- /dev/null +++ b/libstdc++-v3/include/std/csetjmp @@ -0,0 +1,4 @@ + +#ifndef _CPP_CSETJMP +#include <bits/std_csetjmp.h> +#endif diff --git a/libstdc++-v3/include/std/csignal b/libstdc++-v3/include/std/csignal new file mode 100644 index 00000000000..e5c1837a4a5 --- /dev/null +++ b/libstdc++-v3/include/std/csignal @@ -0,0 +1,4 @@ + +#ifndef _CPP_CSIGNAL +#include <bits/std_csignal.h> +#endif diff --git a/libstdc++-v3/include/std/cstdarg b/libstdc++-v3/include/std/cstdarg new file mode 100644 index 00000000000..37b2459f6a5 --- /dev/null +++ b/libstdc++-v3/include/std/cstdarg @@ -0,0 +1,4 @@ + +#ifndef _CPP_CSTDARG +#include <bits/std_cstdarg.h> +#endif diff --git a/libstdc++-v3/include/std/cstddef b/libstdc++-v3/include/std/cstddef new file mode 100644 index 00000000000..fab421423ba --- /dev/null +++ b/libstdc++-v3/include/std/cstddef @@ -0,0 +1,3 @@ +#ifndef _CPP_CSTDDEF +#include <bits/std_cstddef.h> +#endif diff --git a/libstdc++-v3/include/std/cstdio b/libstdc++-v3/include/std/cstdio new file mode 100644 index 00000000000..f2a0135e65a --- /dev/null +++ b/libstdc++-v3/include/std/cstdio @@ -0,0 +1,3 @@ +#ifndef _CPP_CSTDIO +#include <bits/std_cstdio.h> +#endif diff --git a/libstdc++-v3/include/std/cstdlib b/libstdc++-v3/include/std/cstdlib new file mode 100644 index 00000000000..98230261186 --- /dev/null +++ b/libstdc++-v3/include/std/cstdlib @@ -0,0 +1,3 @@ +#ifndef _CPP_CSTDLIB +#include <bits/std_cstdlib.h> +#endif diff --git a/libstdc++-v3/include/std/cstring b/libstdc++-v3/include/std/cstring new file mode 100644 index 00000000000..b6a3bd9b53f --- /dev/null +++ b/libstdc++-v3/include/std/cstring @@ -0,0 +1,3 @@ +#ifndef _CPP_CSTRING +#include <bits/std_cstring.h> +#endif diff --git a/libstdc++-v3/include/std/ctime b/libstdc++-v3/include/std/ctime new file mode 100644 index 00000000000..838fd4360ef --- /dev/null +++ b/libstdc++-v3/include/std/ctime @@ -0,0 +1,3 @@ +#ifndef _CPP_CTIME +#include <bits/std_ctime.h> +#endif diff --git a/libstdc++-v3/include/std/cwchar b/libstdc++-v3/include/std/cwchar new file mode 100644 index 00000000000..2cfc330637c --- /dev/null +++ b/libstdc++-v3/include/std/cwchar @@ -0,0 +1,3 @@ +#ifndef _CPP_CWCHAR +#include <bits/std_cwchar.h> +#endif diff --git a/libstdc++-v3/include/std/cwctype b/libstdc++-v3/include/std/cwctype new file mode 100644 index 00000000000..ccd49086901 --- /dev/null +++ b/libstdc++-v3/include/std/cwctype @@ -0,0 +1,3 @@ +#ifndef _CPP_CWCTYPE +#include <bits/std_cwctype.h> +#endif diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque new file mode 100644 index 00000000000..2215fd02de1 --- /dev/null +++ b/libstdc++-v3/include/std/deque @@ -0,0 +1,3 @@ +#ifndef _CPP_DEQUE +#include <bits/std_deque.h> +#endif diff --git a/libstdc++-v3/include/std/exception b/libstdc++-v3/include/std/exception new file mode 100644 index 00000000000..06653d17e7e --- /dev/null +++ b/libstdc++-v3/include/std/exception @@ -0,0 +1,3 @@ +#ifndef _CPP_EXCEPTION +#include <bits/std_exception.h> +#endif diff --git a/libstdc++-v3/include/std/fstream b/libstdc++-v3/include/std/fstream new file mode 100644 index 00000000000..afe99e98da9 --- /dev/null +++ b/libstdc++-v3/include/std/fstream @@ -0,0 +1,3 @@ +#ifndef _CPP_FSTREAM +#include <bits/std_fstream.h> +#endif diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional new file mode 100644 index 00000000000..700c211ba23 --- /dev/null +++ b/libstdc++-v3/include/std/functional @@ -0,0 +1,3 @@ +#ifndef _CPP_FUNCTIONAL +#include <bits/std_functional.h> +#endif diff --git a/libstdc++-v3/include/std/iomanip b/libstdc++-v3/include/std/iomanip new file mode 100644 index 00000000000..d3c2aa84177 --- /dev/null +++ b/libstdc++-v3/include/std/iomanip @@ -0,0 +1,3 @@ +#ifndef _CPP_IOMANIP +#include <bits/std_iomanip.h> +#endif diff --git a/libstdc++-v3/include/std/ios b/libstdc++-v3/include/std/ios new file mode 100644 index 00000000000..7132eadfa33 --- /dev/null +++ b/libstdc++-v3/include/std/ios @@ -0,0 +1,3 @@ +#ifndef _CPP_IOS +#include <bits/std_ios.h> +#endif diff --git a/libstdc++-v3/include/std/iosfwd b/libstdc++-v3/include/std/iosfwd new file mode 100644 index 00000000000..6a97d3d2d32 --- /dev/null +++ b/libstdc++-v3/include/std/iosfwd @@ -0,0 +1,3 @@ +#ifndef _CPP_IOSFWD +#include <bits/std_iosfwd.h> +#endif diff --git a/libstdc++-v3/include/std/iostream b/libstdc++-v3/include/std/iostream new file mode 100644 index 00000000000..f94fd058a55 --- /dev/null +++ b/libstdc++-v3/include/std/iostream @@ -0,0 +1,5 @@ +#ifndef _CPP_IOSTREAM +#include <bits/std_iostream.h> +#endif + + diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream new file mode 100644 index 00000000000..9594261aa61 --- /dev/null +++ b/libstdc++-v3/include/std/istream @@ -0,0 +1,3 @@ +#ifndef _CPP_ISTREAM +#include <bits/std_istream.h> +#endif diff --git a/libstdc++-v3/include/std/iterator b/libstdc++-v3/include/std/iterator new file mode 100644 index 00000000000..eb22c69746c --- /dev/null +++ b/libstdc++-v3/include/std/iterator @@ -0,0 +1,3 @@ +#ifndef _CPP_ITERATOR +#include <bits/std_iterator.h> +#endif diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits new file mode 100644 index 00000000000..ba86fe0cba7 --- /dev/null +++ b/libstdc++-v3/include/std/limits @@ -0,0 +1,3 @@ +#ifndef _CPP_LIMITS +#include <bits/std_limits.h> +#endif diff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list new file mode 100644 index 00000000000..ea1883639fa --- /dev/null +++ b/libstdc++-v3/include/std/list @@ -0,0 +1,3 @@ +#ifndef _CPP_LIST +#include <bits/std_list.h> +#endif diff --git a/libstdc++-v3/include/std/locale b/libstdc++-v3/include/std/locale new file mode 100644 index 00000000000..5452ae81040 --- /dev/null +++ b/libstdc++-v3/include/std/locale @@ -0,0 +1,3 @@ +#ifndef _CPP_LOCALE +#include <bits/std_locale.h> +#endif diff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map new file mode 100644 index 00000000000..16d24f8ee61 --- /dev/null +++ b/libstdc++-v3/include/std/map @@ -0,0 +1,3 @@ +#ifndef _CPP_MAP +#include <bits/std_map.h> +#endif diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory new file mode 100644 index 00000000000..f905b4d1d51 --- /dev/null +++ b/libstdc++-v3/include/std/memory @@ -0,0 +1,3 @@ +#ifndef _CPP_MEMORY +#include <bits/std_memory.h> +#endif diff --git a/libstdc++-v3/include/std/new b/libstdc++-v3/include/std/new new file mode 100644 index 00000000000..dac53f8e7fc --- /dev/null +++ b/libstdc++-v3/include/std/new @@ -0,0 +1,3 @@ +#ifndef _CPP_NEW +#include <bits/std_new.h> +#endif diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric new file mode 100644 index 00000000000..b3817a838cb --- /dev/null +++ b/libstdc++-v3/include/std/numeric @@ -0,0 +1,3 @@ +#ifndef _CPP_NUMERIC +#include <bits/std_numeric.h> +#endif diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream new file mode 100644 index 00000000000..beed8c58a3d --- /dev/null +++ b/libstdc++-v3/include/std/ostream @@ -0,0 +1,3 @@ +#ifndef _CPP_OSTREAM +#include <bits/std_ostream.h> +#endif diff --git a/libstdc++-v3/include/std/queue b/libstdc++-v3/include/std/queue new file mode 100644 index 00000000000..278270cfdff --- /dev/null +++ b/libstdc++-v3/include/std/queue @@ -0,0 +1,3 @@ +#ifndef _CPP_QUEUE +#include <bits/std_queue.h> +#endif diff --git a/libstdc++-v3/include/std/set b/libstdc++-v3/include/std/set new file mode 100644 index 00000000000..7aa6a388d41 --- /dev/null +++ b/libstdc++-v3/include/std/set @@ -0,0 +1,3 @@ +#ifndef _CPP_SET +#include <bits/std_set.h> +#endif diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream new file mode 100644 index 00000000000..92c57cb46bf --- /dev/null +++ b/libstdc++-v3/include/std/sstream @@ -0,0 +1,3 @@ +#ifndef _CPP_SSTREAM +#include <bits/std_sstream.h> +#endif diff --git a/libstdc++-v3/include/std/stack b/libstdc++-v3/include/std/stack new file mode 100644 index 00000000000..db3771e7adb --- /dev/null +++ b/libstdc++-v3/include/std/stack @@ -0,0 +1,3 @@ +#ifndef _CPP_STACK +#include <bits/std_stack.h> +#endif diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept new file mode 100644 index 00000000000..da75270e682 --- /dev/null +++ b/libstdc++-v3/include/std/stdexcept @@ -0,0 +1,3 @@ +#ifndef _CPP_STDEXCEPT +#include <bits/std_stdexcept.h> +#endif diff --git a/libstdc++-v3/include/std/streambuf b/libstdc++-v3/include/std/streambuf new file mode 100644 index 00000000000..0a58fbdd8ff --- /dev/null +++ b/libstdc++-v3/include/std/streambuf @@ -0,0 +1,3 @@ +#ifndef _CPP_STREAMBUF +#include <bits/std_streambuf.h> +#endif diff --git a/libstdc++-v3/include/std/string b/libstdc++-v3/include/std/string new file mode 100644 index 00000000000..8e3cd42715e --- /dev/null +++ b/libstdc++-v3/include/std/string @@ -0,0 +1,3 @@ +#ifndef _CPP_STRING +#include <bits/std_string.h> +#endif diff --git a/libstdc++-v3/include/std/strstream b/libstdc++-v3/include/std/strstream new file mode 100644 index 00000000000..53267144434 --- /dev/null +++ b/libstdc++-v3/include/std/strstream @@ -0,0 +1,3 @@ +#ifndef _CPP_STRSTREAM +#include <bits/std_strstream.h> +#endif diff --git a/libstdc++-v3/include/std/typeinfo b/libstdc++-v3/include/std/typeinfo new file mode 100644 index 00000000000..26526f33693 --- /dev/null +++ b/libstdc++-v3/include/std/typeinfo @@ -0,0 +1,3 @@ +#ifndef _CPP_TYPEINFO +#include <bits/std_typeinfo.h> +#endif diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility new file mode 100644 index 00000000000..924a85398cb --- /dev/null +++ b/libstdc++-v3/include/std/utility @@ -0,0 +1,3 @@ +#ifndef _CPP_UTILITY +#include <bits/std_utility.h> +#endif diff --git a/libstdc++-v3/include/std/valarray b/libstdc++-v3/include/std/valarray new file mode 100644 index 00000000000..e98bbcef168 --- /dev/null +++ b/libstdc++-v3/include/std/valarray @@ -0,0 +1,3 @@ +#ifndef _CPP_VALARRAY +#include <bits/std_valarray.h> +#endif diff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector new file mode 100644 index 00000000000..c074b77a886 --- /dev/null +++ b/libstdc++-v3/include/std/vector @@ -0,0 +1,3 @@ +#ifndef _CPP_VECTOR +#include <bits/std_vector.h> +#endif |