diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9f6c1b690fed..230d87bae837 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,38 @@ +2002-03-08 Benjamin Kosnik + + * include/std/std_limits.h: Move static const data members out of + generic template, into base class __numeric_limits_base. + * src/limits.cc: Add definitions. + * config/linker-map.gnu: Add __numeric_limits_base. + * testsuite/18_support/numeric_limits.cc: Declare test in scope. + +2002-03-07 Benjamin Kosnik + + * include/bits/stl_alloc.h: Add extern implicit allocator + instantiations. + * include/bits/basic_string.tcc: Tweak. + * include/bits/loqcale_facets.tcc: Remove default args. Add + has_facet, use_facet extern instantiations. + * src/stl-inst.cc: Add explicit instantiation. + * src/locale-inst.cc: Clean. Remove locale member template + instantiations. + + * testsuite/22_locale/operators.cc (test02): Enable. + +2002-03-06 Benjamin Kosnik + Stephen M. Webb + + * include/bits/stl_tree.h (_S_rb_tree_red): Make enum. + (_S_rb_tree_black): Make enum. + Clean. Format. + * include/bits/stl_bvector.h (__WORD_BIT): To _M_word_bit, enum. + * include/bits/stl_algo.h (__stl_chunk_size): _M_chunk_size, enum. + (__stl_threshold): _M_threshold, enum. + * src/stl-inst.cc: Same. + * config/linker-map.gnu: Remove. + + * testsuite/23_containers/vector_bool.cc: New. + 2002-03-08 Phil Edwards * include/bits/basic_string.h (basic_string::_S_construct): Fix @@ -114,6 +149,16 @@ * testsuite/27_io/ios_manip_basefield.cc (test01): Tweak existing tests, add a few more. +2002-02-25 Benjamin Kosnik + + * src/ios.cc (ios_base::~ios_base): Tweak. + (ios_base::_M_call_callbacks): Deal with null __p. + (ios_base::ios_base): Set _M_callbacks. + * include/bits/basic_ios.tcc (basic_ios::init): Adjust comment. + * testsuite/27_io/ios_init.cc (test02): Fix. + + * mkcheck.in (static_fail): Failed links go to output file. + 2002-02-25 Phil Edwards * docs/html/faq/index.html: Update. diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu index e0f3f8800af6..240ca0138eff 100644 --- a/libstdc++-v3/config/linker-map.gnu +++ b/libstdc++-v3/config/linker-map.gnu @@ -33,10 +33,12 @@ GLIBCPP_3.1 { std::__throw_*; std::__basic_file*; std::__num_base*; - std::__timepunct* + std::__timepunct*; + std::__numeric_limits_base* }; # Names not in an 'extern' block are mangled names. + _ZSt9has_facet*; # operator new(unsigned) _Znwj; @@ -82,18 +84,6 @@ GLIBCPP_3.1 { _ZTv*; _ZTc*; - # std::_S_rb_tree_red - _ZSt14_S_rb_tree_red; - - # std::_S_rb_tree_black - _ZSt16_S_rb_tree_black; - - # std::__stl_threshold - _ZSt15__stl_threshold; - - # std::__stl_chunk_size - _ZSt16__stl_chunk_size; - # std::__convert_to_v _ZSt14__convert_to_v*; @@ -113,4 +103,3 @@ CXXABI_1 { local: *; }; - diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index dce9b38fcb49..01a3fe6ea8c6 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -945,7 +945,7 @@ namespace std // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. extern template class basic_string; - extern template + extern template basic_istream& operator>>(basic_istream&, string&); extern template diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 8513f8b17f2e..e08dc363a9d3 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -2061,36 +2061,38 @@ namespace std // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. + extern template class vector; + extern template class moneypunct; extern template class moneypunct; extern template class moneypunct_byname; extern template class moneypunct_byname; - extern template class money_get >; - extern template class money_put >; + extern template class money_get; + extern template class money_put; extern template class moneypunct; extern template class moneypunct; extern template class moneypunct_byname; extern template class moneypunct_byname; - extern template class money_get >; - extern template class money_put >; + extern template class money_get; + extern template class money_put; extern template class numpunct; extern template class numpunct_byname; - extern template class num_get >; - extern template class num_put >; + extern template class num_get; + extern template class num_put; extern template class numpunct; extern template class numpunct_byname; - extern template class num_get >; - extern template class num_put >; + extern template class num_get; + extern template class num_put; extern template class __timepunct; - extern template class time_put >; - extern template class time_put_byname >; - extern template class time_get >; - extern template class time_get_byname >; + extern template class time_put; + extern template class time_put_byname; + extern template class time_get; + extern template class time_get_byname; extern template class __timepunct; - extern template class time_put >; - extern template class time_put_byname >; - extern template class time_get >; - extern template class time_get_byname >; + extern template class time_put; + extern template class time_put_byname; + extern template class time_get; + extern template class time_get_byname; extern template class messages; extern template class messages_byname; extern template class messages; @@ -2103,13 +2105,217 @@ namespace std extern template class collate_byname; extern template class collate; extern template class collate_byname; + + extern template + const codecvt& + use_facet >(const locale&); + + extern template + const collate& + use_facet >(const locale&); + + extern template + const numpunct& + use_facet >(const locale&); + + extern template + const num_put& + use_facet >(const locale&); + + extern template + const num_get& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const money_put& + use_facet >(const locale&); + + extern template + const money_get& + use_facet >(const locale&); + + extern template + const __timepunct& + use_facet<__timepunct >(const locale&); + + extern template + const time_put& + use_facet >(const locale&); + + extern template + const time_get& + use_facet >(const locale&); + + extern template + const messages& + use_facet >(const locale&); + + extern template + const codecvt& + use_facet >(locale const&); + + extern template + const collate& + use_facet >(const locale&); + + extern template + const numpunct& + use_facet >(const locale&); + + extern template + const num_put& + use_facet >(const locale&); + + extern template + const num_get& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const money_put& + use_facet >(const locale&); + + extern template + const money_get& + use_facet >(const locale&); + + extern template + const __timepunct& + use_facet<__timepunct >(const locale&); + + extern template + const time_put& + use_facet >(const locale&); + + extern template + const time_get& + use_facet >(const locale&); + + extern template + const messages& + use_facet >(const locale&); + + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet<__timepunct >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet<__timepunct >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); } // namespace std #endif - - - - - diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index ec9ef2ad818f..a251befd248e 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -1889,7 +1889,7 @@ __result, __binary_pred, _IterType()); * This controls some aspect of the sort routines. * @endmaint */ - extern const int __stl_threshold; + enum { _M_threshold = 16 }; /** * @maint @@ -2016,9 +2016,9 @@ __result, __binary_pred, _IterType()); 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); + if (__last - __first > _M_threshold) { + __insertion_sort(__first, __first + _M_threshold); + __unguarded_insertion_sort(__first + _M_threshold, __last); } else __insertion_sort(__first, __last); @@ -2034,9 +2034,9 @@ __result, __binary_pred, _IterType()); __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); + if (__last - __first > _M_threshold) { + __insertion_sort(__first, __first + _M_threshold, __comp); + __unguarded_insertion_sort(__first + _M_threshold, __last, __comp); } else __insertion_sort(__first, __last, __comp); @@ -2068,7 +2068,7 @@ __result, __binary_pred, _IterType()); { typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; - while (__last - __first > __stl_threshold) { + while (__last - __first > _M_threshold) { if (__depth_limit == 0) { partial_sort(__first, __last, __last); return; @@ -2096,7 +2096,7 @@ __result, __binary_pred, _IterType()); { typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; - while (__last - __first > __stl_threshold) { + while (__last - __first > _M_threshold) { if (__depth_limit == 0) { partial_sort(__first, __last, __last, __comp); return; @@ -2253,7 +2253,7 @@ __result, __binary_pred, _IterType()); __comp); } - extern const int __stl_chunk_size; + enum { _M_chunk_size = 7 }; template void @@ -2289,7 +2289,7 @@ __result, __binary_pred, _IterType()); _Distance __len = __last - __first; _Pointer __buffer_last = __buffer + __len; - _Distance __step_size = __stl_chunk_size; + _Distance __step_size = _M_chunk_size; __chunk_insertion_sort(__first, __last, __step_size); while (__step_size < __len) { @@ -2310,7 +2310,7 @@ __result, __binary_pred, _IterType()); _Distance __len = __last - __first; _Pointer __buffer_last = __buffer + __len; - _Distance __step_size = __stl_chunk_size; + _Distance __step_size = _M_chunk_size; __chunk_insertion_sort(__first, __last, __step_size, __comp); while (__step_size < __len) { diff --git a/libstdc++-v3/include/bits/stl_alloc.h b/libstdc++-v3/include/bits/stl_alloc.h index 7a4d9e9e4a6b..4ff816be5e33 100644 --- a/libstdc++-v3/include/bits/stl_alloc.h +++ b/libstdc++-v3/include/bits/stl_alloc.h @@ -922,6 +922,11 @@ struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > > }; //@} + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. + extern template class allocator; + extern template class allocator; } // namespace std #endif /* __GLIBCPP_INTERNAL_ALLOC_H */ diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index 66c7e2de5944..0d2348e40680 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -63,7 +63,7 @@ namespace std { - extern const int __WORD_BIT; + enum { _M_word_bit = int(CHAR_BIT * sizeof(unsigned long)) }; struct _Bit_reference { unsigned int* _M_p; @@ -106,24 +106,24 @@ struct _Bit_iterator_base : public iterator : _M_p(__x), _M_offset(__y) {} void _M_bump_up() { - if (_M_offset++ == __WORD_BIT - 1) { + if (_M_offset++ == _M_word_bit - 1) { _M_offset = 0; ++_M_p; } } void _M_bump_down() { if (_M_offset-- == 0) { - _M_offset = __WORD_BIT - 1; + _M_offset = _M_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; + _M_p += __n / _M_word_bit; + __n = __n % _M_word_bit; if (__n < 0) { - _M_offset = (unsigned int) __n + __WORD_BIT; + _M_offset = (unsigned int) __n + _M_word_bit; --_M_p; } else _M_offset = (unsigned int) __n; @@ -151,7 +151,7 @@ struct _Bit_iterator_base : public iterator 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; + return _M_word_bit * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset; } @@ -283,7 +283,7 @@ public: protected: unsigned int* _M_bit_alloc(size_t __n) - { return _M_data_allocator.allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + { return _M_data_allocator.allocate((__n + _M_word_bit - 1)/_M_word_bit); } void _M_deallocate() { if (_M_start._M_p) _M_data_allocator.deallocate(_M_start._M_p, @@ -313,7 +313,7 @@ protected: _Alloc_type; unsigned int* _M_bit_alloc(size_t __n) - { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + { return _Alloc_type::allocate((__n + _M_word_bit - 1)/_M_word_bit); } void _M_deallocate() { if (_M_start._M_p) _Alloc_type::deallocate(_M_start._M_p, @@ -380,7 +380,7 @@ template 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_end_of_storage = __q + (__n + _M_word_bit - 1)/_M_word_bit; _M_start = iterator(__q, 0); _M_finish = _M_start + difference_type(__n); } @@ -391,13 +391,13 @@ template ++_M_finish; } else { - size_type __len = size() ? 2 * size() : __WORD_BIT; + size_type __len = size() ? 2 * size() : _M_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_end_of_storage = __q + (__len + _M_word_bit - 1)/_M_word_bit; _M_start = iterator(__q, 0); } } @@ -448,7 +448,7 @@ template __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_end_of_storage = __q + (__len + _M_word_bit - 1)/_M_word_bit; _M_start = iterator(__q, 0); } } @@ -614,7 +614,7 @@ template _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; + _M_end_of_storage = __q + (__n + _M_word_bit - 1)/_M_word_bit; } } @@ -678,7 +678,7 @@ template 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_end_of_storage = __q + (__len + _M_word_bit - 1)/_M_word_bit; _M_start = iterator(__q, 0); } } diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index ef50c9ee38a6..d2ae142e9265 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -90,1207 +90,1373 @@ iterators invalidated are those referring to the deleted node. namespace std { - typedef bool _Rb_tree_Color_type; - extern const _Rb_tree_Color_type _S_rb_tree_red; // false - extern const _Rb_tree_Color_type _S_rb_tree_black; // true + enum _Rb_tree_color { _M_red = false, _M_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) + struct _Rb_tree_node_base { - while (__x->_M_left != 0) __x = __x->_M_left; - return __x; - } - - static _Base_ptr _S_maximum(_Base_ptr __x) - { - while (__x->_M_right != 0) __x = __x->_M_right; - return __x; - } -}; - -template -struct _Rb_tree_node : public _Rb_tree_node_base -{ - typedef _Rb_tree_node<_Value>* _Link_type; - _Value _M_value_field; -}; - - -struct _Rb_tree_base_iterator -{ - typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; - typedef bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; - _Base_ptr _M_node; - - void _M_increment() - { - if (_M_node->_M_right != 0) { - _M_node = _M_node->_M_right; - while (_M_node->_M_left != 0) - _M_node = _M_node->_M_left; - } - else { - _Base_ptr __y = _M_node->_M_parent; - while (_M_node == __y->_M_right) { - _M_node = __y; - __y = __y->_M_parent; - } - if (_M_node->_M_right != __y) - _M_node = __y; - } - } - - void _M_decrement() - { - if (_M_node->_M_color == _S_rb_tree_red && - _M_node->_M_parent->_M_parent == _M_node) - _M_node = _M_node->_M_right; - else if (_M_node->_M_left != 0) { - _Base_ptr __y = _M_node->_M_left; - while (__y->_M_right != 0) - __y = __y->_M_right; - _M_node = __y; - } - else { - _Base_ptr __y = _M_node->_M_parent; - while (_M_node == __y->_M_left) { - _M_node = __y; - __y = __y->_M_parent; - } - _M_node = __y; - } - } -}; - -template -struct _Rb_tree_iterator : public _Rb_tree_base_iterator -{ - typedef _Value value_type; - typedef _Ref reference; - typedef _Ptr pointer; - typedef _Rb_tree_iterator<_Value, _Value&, _Value*> - iterator; - typedef _Rb_tree_iterator<_Value, const _Value&, const _Value*> - const_iterator; - typedef _Rb_tree_iterator<_Value, _Ref, _Ptr> - _Self; - typedef _Rb_tree_node<_Value>* _Link_type; - - _Rb_tree_iterator() {} - _Rb_tree_iterator(_Link_type __x) { _M_node = __x; } - _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; } - - reference operator*() const { return _Link_type(_M_node)->_M_value_field; } - pointer operator->() const { return &(operator*()); } - - _Self& operator++() { _M_increment(); return *this; } - _Self operator++(int) { - _Self __tmp = *this; - _M_increment(); - return __tmp; - } + typedef _Rb_tree_node_base* _Base_ptr; - _Self& operator--() { _M_decrement(); return *this; } - _Self operator--(int) { - _Self __tmp = *this; - _M_decrement(); - return __tmp; - } -}; - -template -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 -inline bool operator==(const _Rb_tree_iterator<_Value, const _Value&, const _Value*>& __x, - const _Rb_tree_iterator<_Value, _Value&, _Value*>& __y) { - return __x._M_node == __y._M_node; -} - -template -inline bool operator==(const _Rb_tree_iterator<_Value, _Value&, _Value*>& __x, - const _Rb_tree_iterator<_Value, const _Value&, const _Value*>& __y) { - return __x._M_node == __y._M_node; -} - -template -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 -inline bool operator!=(const _Rb_tree_iterator<_Value, const _Value&, const _Value*>& __x, - const _Rb_tree_iterator<_Value, _Value&, _Value*>& __y) { - return __x._M_node != __y._M_node; -} - -template -inline bool operator!=(const _Rb_tree_iterator<_Value, _Value&, _Value*>& __x, - const _Rb_tree_iterator<_Value, const _Value&, const _Value*>& __y) { - return __x._M_node != __y._M_node; -} - -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. - -// _Base for general standard-conforming allocators. -template -class _Rb_tree_alloc_base { -public: - typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; - allocator_type get_allocator() const { return _M_node_allocator; } - - _Rb_tree_alloc_base(const allocator_type& __a) - : _M_node_allocator(__a), _M_header(0) {} - -protected: - typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type - _M_node_allocator; - _Rb_tree_node<_Tp>* _M_header; - - _Rb_tree_node<_Tp>* _M_get_node() - { return _M_node_allocator.allocate(1); } - void _M_put_node(_Rb_tree_node<_Tp>* __p) - { _M_node_allocator.deallocate(__p, 1); } -}; - -// Specialization for instanceless allocators. -template -class _Rb_tree_alloc_base<_Tp, _Alloc, true> { -public: - typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; - allocator_type get_allocator() const { return allocator_type(); } - - _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {} - -protected: - _Rb_tree_node<_Tp>* _M_header; - - typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type - _Alloc_type; - - _Rb_tree_node<_Tp>* _M_get_node() - { return _Alloc_type::allocate(1); } - void _M_put_node(_Rb_tree_node<_Tp>* __p) - { _Alloc_type::deallocate(__p, 1); } -}; - -template -struct _Rb_tree_base - : public _Rb_tree_alloc_base<_Tp, _Alloc, - _Alloc_traits<_Tp, _Alloc>::_S_instanceless> -{ - typedef _Rb_tree_alloc_base<_Tp, _Alloc, - _Alloc_traits<_Tp, _Alloc>::_S_instanceless> - _Base; - typedef typename _Base::allocator_type allocator_type; - - _Rb_tree_base(const allocator_type& __a) - : _Base(__a) { _M_header = _M_get_node(); } - ~_Rb_tree_base() { _M_put_node(_M_header); } - -}; - - -template > -class _Rb_tree : protected _Rb_tree_base<_Value, _Alloc> { - typedef _Rb_tree_base<_Value, _Alloc> _Base; -protected: - typedef _Rb_tree_node_base* _Base_ptr; - typedef _Rb_tree_node<_Value> _Rb_tree_node; - typedef _Rb_tree_Color_type _Color_type; -public: - typedef _Key key_type; - typedef _Value value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef _Rb_tree_node* _Link_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - - typedef typename _Base::allocator_type allocator_type; - allocator_type get_allocator() const { return _Base::get_allocator(); } - -protected: - using _Base::_M_get_node; - using _Base::_M_put_node; - using _Base::_M_header; - -protected: - - _Link_type - _M_create_node(const value_type& __x) - { - _Link_type __tmp = _M_get_node(); - try { - _Construct(&__tmp->_M_value_field, __x); - } - catch(...) - { - _M_put_node(__tmp); - __throw_exception_again; - } - return __tmp; - } - - _Link_type _M_clone_node(_Link_type __x) - { - _Link_type __tmp = _M_create_node(__x->_M_value_field); - __tmp->_M_color = __x->_M_color; - __tmp->_M_left = 0; - __tmp->_M_right = 0; - return __tmp; - } - - void - destroy_node(_Link_type __p) - { - _Destroy(&__p->_M_value_field); - _M_put_node(__p); - } - -protected: - size_type _M_node_count; // keeps track of size of tree - _Compare _M_key_compare; - - _Link_type& _M_root() const - { return (_Link_type&) _M_header->_M_parent; } - _Link_type& _M_leftmost() const - { return (_Link_type&) _M_header->_M_left; } - _Link_type& _M_rightmost() const - { return (_Link_type&) _M_header->_M_right; } - - static _Link_type& _S_left(_Link_type __x) - { return (_Link_type&)(__x->_M_left); } - static _Link_type& _S_right(_Link_type __x) - { return (_Link_type&)(__x->_M_right); } - static _Link_type& _S_parent(_Link_type __x) - { return (_Link_type&)(__x->_M_parent); } - static reference _S_value(_Link_type __x) - { return __x->_M_value_field; } - static const _Key& _S_key(_Link_type __x) - { return _KeyOfValue()(_S_value(__x)); } - static _Color_type& _S_color(_Link_type __x) - { return (_Color_type&)(__x->_M_color); } - - static _Link_type& _S_left(_Base_ptr __x) - { return (_Link_type&)(__x->_M_left); } - static _Link_type& _S_right(_Base_ptr __x) - { return (_Link_type&)(__x->_M_right); } - static _Link_type& _S_parent(_Base_ptr __x) - { return (_Link_type&)(__x->_M_parent); } - static reference _S_value(_Base_ptr __x) - { return ((_Link_type)__x)->_M_value_field; } - static const _Key& _S_key(_Base_ptr __x) - { return _KeyOfValue()(_S_value(_Link_type(__x)));} - static _Color_type& _S_color(_Base_ptr __x) - { return (_Color_type&)(_Link_type(__x)->_M_color); } - - static _Link_type _S_minimum(_Link_type __x) - { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); } - - static _Link_type _S_maximum(_Link_type __x) - { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); } - -public: - typedef _Rb_tree_iterator iterator; - typedef _Rb_tree_iterator - const_iterator; - - typedef reverse_iterator const_reverse_iterator; - typedef reverse_iterator reverse_iterator; - -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); - } + _Rb_tree_color _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; -public: - // insert/erase - pair insert_unique(const value_type& __x); - iterator insert_equal(const value_type& __x); - - iterator insert_unique(iterator __position, const value_type& __x); - iterator insert_equal(iterator __position, const value_type& __x); - - template - void insert_unique(_InputIterator __first, _InputIterator __last); - template - void insert_equal(_InputIterator __first, _InputIterator __last); - - void erase(iterator __position); - size_type erase(const key_type& __x); - void erase(iterator __first, iterator __last); - void erase(const key_type* __first, const key_type* __last); - void clear() { - if (_M_node_count != 0) { - _M_erase(_M_root()); - _M_leftmost() = _M_header; - _M_root() = 0; - _M_rightmost() = _M_header; - _M_node_count = 0; - } - } - -public: - // set operations: - iterator find(const key_type& __x); - const_iterator find(const key_type& __x) const; - size_type count(const key_type& __x) const; - iterator lower_bound(const key_type& __x); - const_iterator lower_bound(const key_type& __x) const; - iterator upper_bound(const key_type& __x); - const_iterator upper_bound(const key_type& __x) const; - pair equal_range(const key_type& __x); - pair equal_range(const key_type& __x) const; - -public: - // Debugging. - bool __rb_verify() const; -}; - -template -inline bool -operator==(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) -{ - return __x.size() == __y.size() && - equal(__x.begin(), __x.end(), __y.begin()); -} - -template -inline bool -operator<(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) -{ - return lexicographical_compare(__x.begin(), __x.end(), - __y.begin(), __y.end()); -} - -template -inline bool -operator!=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { - return !(__x == __y); -} - -template -inline bool -operator>(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { - return __y < __x; -} - -template -inline bool -operator<=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { - return !(__y < __x); -} - -template -inline bool -operator>=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) { - return !(__x < __y); -} - - -template -inline void -swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, - _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) -{ - __x.swap(__y); -} - - -template -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) -{ - if (this != &__x) { - // Note that _Key may be a constant type. - clear(); - _M_node_count = 0; - _M_key_compare = __x._M_key_compare; - if (__x._M_root() == 0) { - _M_root() = 0; - _M_leftmost() = _M_header; - _M_rightmost() = _M_header; - } - else { - _M_root() = _M_copy(__x._M_root(), _M_header); - _M_leftmost() = _S_minimum(_M_root()); - _M_rightmost() = _S_maximum(_M_root()); - _M_node_count = __x._M_node_count; - } - } - return *this; -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::_M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Value& __v) -{ - _Link_type __x = (_Link_type) __x_; - _Link_type __y = (_Link_type) __y_; - _Link_type __z; - - if (__y == _M_header || __x != 0 || - _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) { - __z = _M_create_node(__v); - _S_left(__y) = __z; // also makes _M_leftmost() = __z - // when __y == _M_header - if (__y == _M_header) { - _M_root() = __z; - _M_rightmost() = __z; - } - else if (__y == _M_leftmost()) - _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node - } - else { - __z = _M_create_node(__v); - _S_right(__y) = __z; - if (__y == _M_rightmost()) - _M_rightmost() = __z; // maintain _M_rightmost() pointing to max node - } - _S_parent(__z) = __y; - _S_left(__z) = 0; - _S_right(__z) = 0; - _Rb_tree_rebalance(__z, _M_header->_M_parent); - ++_M_node_count; - return iterator(__z); -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::insert_equal(const _Value& __v) -{ - _Link_type __y = _M_header; - _Link_type __x = _M_root(); - while (__x != 0) { - __y = __x; - __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? - _S_left(__x) : _S_right(__x); - } - return _M_insert(__x, __y, __v); -} - - -template -pair::iterator, - bool> -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::insert_unique(const _Value& __v) -{ - _Link_type __y = _M_header; - _Link_type __x = _M_root(); - bool __comp = true; - while (__x != 0) { - __y = __x; - __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)); - __x = __comp ? _S_left(__x) : _S_right(__x); - } - iterator __j = iterator(__y); - if (__comp) - if (__j == begin()) - return pair(_M_insert(__x, __y, __v), true); - else - --__j; - if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) - return pair(_M_insert(__x, __y, __v), true); - return pair(__j, false); -} - - -template -typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator -_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> - ::insert_unique(iterator __position, const _Val& __v) -{ - if (__position._M_node == _M_header->_M_left) { // begin() - if (size() > 0 && - _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) - return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - else - return insert_unique(__v).first; - } else if (__position._M_node == _M_header) { // end() - if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) - return _M_insert(0, _M_rightmost(), __v); - else - return insert_unique(__v).first; - } else { - iterator __before = __position; - --__before; - if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v)) - && _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) { - if (_S_right(__before._M_node) == 0) - return _M_insert(0, __before._M_node, __v); - else - return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - } else - return insert_unique(__v).first; - } -} - -template -typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator -_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc> - ::insert_equal(iterator __position, const _Val& __v) -{ - if (__position._M_node == _M_header->_M_left) { // begin() - if (size() > 0 && - !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) - return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - else - return insert_equal(__v); - } else if (__position._M_node == _M_header) {// end() - if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) - return _M_insert(0, _M_rightmost(), __v); - else - return insert_equal(__v); - } else { - iterator __before = __position; - --__before; - if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node)) - && !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) { - if (_S_right(__before._M_node) == 0) - return _M_insert(0, __before._M_node, __v); - else - return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - } else - return insert_equal(__v); - } -} - -template - template -void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> - ::insert_equal(_II __first, _II __last) -{ - for ( ; __first != __last; ++__first) - insert_equal(*__first); -} - -template - template -void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> - ::insert_unique(_II __first, _II __last) { - for ( ; __first != __last; ++__first) - insert_unique(*__first); -} - -template -inline void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::erase(iterator __position) -{ - _Link_type __y = - (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node, - _M_header->_M_parent, - _M_header->_M_left, - _M_header->_M_right); - destroy_node(__y); - --_M_node_count; -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) -{ - pair __p = equal_range(__x); - size_type __n = distance(__p.first, __p.second); - erase(__p.first, __p.second); - return __n; -} - -template -typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type -_Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc> - ::_M_copy(_Link_type __x, _Link_type __p) -{ - // structural copy. __x and __p must be non-null. - _Link_type __top = _M_clone_node(__x); - __top->_M_parent = __p; - - try { - if (__x->_M_right) - __top->_M_right = _M_copy(_S_right(__x), __top); - __p = __top; - __x = _S_left(__x); - - while (__x != 0) { - _Link_type __y = _M_clone_node(__x); - __p->_M_left = __y; - __y->_M_parent = __p; - if (__x->_M_right) - __y->_M_right = _M_copy(_S_right(__x), __y); - __p = __y; - __x = _S_left(__x); - } - } - catch(...) + static _Base_ptr + _S_minimum(_Base_ptr __x) { - _M_erase(__top); - __throw_exception_again; + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; } - return __top; -} -template -void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::_M_erase(_Link_type __x) -{ - // erase without rebalancing - while (__x != 0) { - _M_erase(_S_right(__x)); - _Link_type __y = _S_left(__x); - destroy_node(__x); - __x = __y; - } -} + static _Base_ptr + _S_maximum(_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } + }; -template -void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::erase(iterator __first, iterator __last) -{ - if (__first == begin() && __last == end()) - clear(); - else - while (__first != __last) erase(__first++); -} - -template -void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::erase(const _Key* __first, const _Key* __last) -{ - while (__first != __last) erase(*__first++); -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) -{ - _Link_type __y = _M_header; // Last node which is not less than __k. - _Link_type __x = _M_root(); // Current node. - - while (__x != 0) - if (!_M_key_compare(_S_key(__x), __k)) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - iterator __j = iterator(__y); - return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? - end() : __j; -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) const -{ - _Link_type __y = _M_header; /* Last node which is not less than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) { - if (!_M_key_compare(_S_key(__x), __k)) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - } - const_iterator __j = const_iterator(__y); - return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? - end() : __j; -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::count(const _Key& __k) const -{ - pair __p = equal_range(__k); - size_type __n = distance(__p.first, __p.second); - return __n; -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::lower_bound(const _Key& __k) -{ - _Link_type __y = _M_header; /* Last node which is not less than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (!_M_key_compare(_S_key(__x), __k)) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - return iterator(__y); -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::lower_bound(const _Key& __k) const -{ - _Link_type __y = _M_header; /* Last node which is not less than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (!_M_key_compare(_S_key(__x), __k)) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - return const_iterator(__y); -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::upper_bound(const _Key& __k) -{ - _Link_type __y = _M_header; /* Last node which is greater than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (_M_key_compare(__k, _S_key(__x))) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - return iterator(__y); -} - -template -typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::upper_bound(const _Key& __k) const -{ - _Link_type __y = _M_header; /* Last node which is greater than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (_M_key_compare(__k, _S_key(__x))) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - return const_iterator(__y); -} - -template -inline -pair::iterator, - typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator> -_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> - ::equal_range(const _Key& __k) -{ - return pair(lower_bound(__k), upper_bound(__k)); -} - -template -inline -pair::const_iterator, - typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::const_iterator> -_Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc> - ::equal_range(const _Key& __k) const -{ - return pair(lower_bound(__k), - upper_bound(__k)); -} - -inline int -__black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) -{ - if (__node == 0) - return 0; - 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 -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; + template + struct _Rb_tree_node : public _Rb_tree_node_base + { + typedef _Rb_tree_node<_Val>* _Link_type; + _Val _M_value_field; + }; - 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); + 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; - 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; + _Base_ptr _M_node; - 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; + 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; + } + } - if (!__L && !__R && __black_count(__x, _M_root()) != __len) - return false; + void + _M_decrement() + { + if (_M_node->_M_color == _M_red + && _M_node->_M_parent->_M_parent == _M_node) + _M_node = _M_node->_M_right; + else if (_M_node->_M_left != 0) + { + _Base_ptr __y = _M_node->_M_left; + while (__y->_M_right != 0) + __y = __y->_M_right; + _M_node = __y; + } + else + { + _Base_ptr __y = _M_node->_M_parent; + while (_M_node == __y->_M_left) + { + _M_node = __y; + __y = __y->_M_parent; + } + _M_node = __y; + } + } + }; + + template + struct _Rb_tree_iterator : public _Rb_tree_base_iterator + { + typedef _Val value_type; + typedef _Ref reference; + typedef _Ptr pointer; + typedef _Rb_tree_iterator<_Val, _Val&, _Val*> iterator; + typedef _Rb_tree_iterator<_Val, const _Val&, const _Val*> + const_iterator; + typedef _Rb_tree_iterator<_Val, _Ref, _Ptr> _Self; + typedef _Rb_tree_node<_Val>* _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; } + + pointer + operator->() const { return &(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 + inline bool + operator==(const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __x, + const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __y) + { return __x._M_node == __y._M_node; } + + template + inline bool + operator==(const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __x, + const _Rb_tree_iterator<_Val, _Val&, _Val*>& __y) + { return __x._M_node == __y._M_node; } + + template + inline bool + operator==(const _Rb_tree_iterator<_Val, _Val&, _Val*>& __x, + const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __y) + { return __x._M_node == __y._M_node; } + + template + inline bool + operator!=(const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __x, + const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __y) + { return __x._M_node != __y._M_node; } + + template + inline bool + operator!=(const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __x, + const _Rb_tree_iterator<_Val, _Val&, _Val*>& __y) + { return __x._M_node != __y._M_node; } + + template + inline bool + operator!=(const _Rb_tree_iterator<_Val, _Val&, _Val*>& __x, + const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __y) + { return __x._M_node != __y._M_node; } + + 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; } - 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; + 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; - return true; -} + 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 = _M_red; + while (__x != __root + && __x->_M_parent->_M_color == _M_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 == _M_red) + { + __x->_M_parent->_M_color = _M_black; + __y->_M_color = _M_black; + __x->_M_parent->_M_parent->_M_color = _M_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 = _M_black; + __x->_M_parent->_M_parent->_M_color = _M_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 == _M_red) + { + __x->_M_parent->_M_color = _M_black; + __y->_M_color = _M_black; + __x->_M_parent->_M_parent->_M_color = _M_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 = _M_black; + __x->_M_parent->_M_parent->_M_color = _M_red; + _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root); + } + } + } + __root->_M_color = _M_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 != _M_red) + { + while (__x != __root && (__x == 0 || __x->_M_color == _M_black)) + if (__x == __x_parent->_M_left) + { + _Rb_tree_node_base* __w = __x_parent->_M_right; + if (__w->_M_color == _M_red) + { + __w->_M_color = _M_black; + __x_parent->_M_color = _M_red; + _Rb_tree_rotate_left(__x_parent, __root); + __w = __x_parent->_M_right; + } + if ((__w->_M_left == 0 || + __w->_M_left->_M_color == _M_black) && + (__w->_M_right == 0 || + __w->_M_right->_M_color == _M_black)) + { + __w->_M_color = _M_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; + } + else + { + if (__w->_M_right == 0 + || __w->_M_right->_M_color == _M_black) + { + if (__w->_M_left) __w->_M_left->_M_color = _M_black; + __w->_M_color = _M_red; + _Rb_tree_rotate_right(__w, __root); + __w = __x_parent->_M_right; + } + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _M_black; + if (__w->_M_right) + __w->_M_right->_M_color = _M_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 == _M_red) + { + __w->_M_color = _M_black; + __x_parent->_M_color = _M_red; + _Rb_tree_rotate_right(__x_parent, __root); + __w = __x_parent->_M_left; + } + if ((__w->_M_right == 0 || + __w->_M_right->_M_color == _M_black) && + (__w->_M_left == 0 || + __w->_M_left->_M_color == _M_black)) + { + __w->_M_color = _M_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; + } + else + { + if (__w->_M_left == 0 || __w->_M_left->_M_color == _M_black) + { + if (__w->_M_right) __w->_M_right->_M_color = _M_black; + __w->_M_color = _M_red; + _Rb_tree_rotate_left(__w, __root); + __w = __x_parent->_M_left; + } + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _M_black; + if (__w->_M_left) + __w->_M_left->_M_color = _M_black; + _Rb_tree_rotate_right(__x_parent, __root); + break; + } + } + if (__x) __x->_M_color = _M_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. + + // _Base for general standard-conforming allocators. + template + class _Rb_tree_alloc_base + { + public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + + allocator_type + get_allocator() const { return _M_node_allocator; } + + _Rb_tree_alloc_base(const allocator_type& __a) + : _M_node_allocator(__a), _M_header(0) {} + + protected: + typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type + _M_node_allocator; + + _Rb_tree_node<_Tp>* _M_header; + + _Rb_tree_node<_Tp>* + _M_get_node() { return _M_node_allocator.allocate(1); } + + void + _M_put_node(_Rb_tree_node<_Tp>* __p) + { _M_node_allocator.deallocate(__p, 1); } + }; + + // Specialization for instanceless allocators. + template + class _Rb_tree_alloc_base<_Tp, _Alloc, true> + { + public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {} + + protected: + _Rb_tree_node<_Tp>* _M_header; + + typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type + _Alloc_type; + + _Rb_tree_node<_Tp>* + _M_get_node() { return _Alloc_type::allocate(1); } + + void + _M_put_node(_Rb_tree_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + }; + + template + struct _Rb_tree_base : public _Rb_tree_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + { + typedef _Rb_tree_alloc_base<_Tp, + _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base; + typedef typename _Base::allocator_type allocator_type; + + _Rb_tree_base(const allocator_type& __a) + : _Base(__a) { _M_header = _M_get_node(); } + ~_Rb_tree_base() { _M_put_node(_M_header); } + }; + + + template > + class _Rb_tree : protected _Rb_tree_base<_Val, _Alloc> + { + typedef _Rb_tree_base<_Val, _Alloc> _Base; + + protected: + typedef _Rb_tree_node_base* _Base_ptr; + typedef _Rb_tree_node<_Val> _Rb_tree_node; + + public: + typedef _Key key_type; + typedef _Val value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Rb_tree_node* _Link_type; + typedef 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: + using _Base::_M_get_node; + using _Base::_M_put_node; + using _Base::_M_header; + + _Link_type + _M_create_node(const value_type& __x) + { + _Link_type __tmp = _M_get_node(); + try + { _Construct(&__tmp->_M_value_field, __x); } + catch(...) + { + _M_put_node(__tmp); + __throw_exception_again; + } + 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); + } + + 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 _Rb_tree_color& + _S_color(_Link_type __x) { return __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 _Rb_tree_color& + _S_color(_Base_ptr __x) { return (_Link_type(__x)->_M_color); } + + static _Link_type + _S_minimum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); } + + static _Link_type + _S_maximum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); } + + public: + typedef _Rb_tree_iterator iterator; + typedef _Rb_tree_iterator + const_iterator; + + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; + + 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,_Val,_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) = _M_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,_Val,_KeyOfValue,_Compare,_Alloc>& + operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x); + + private: + void _M_empty_initialize() + { + _S_color(_M_header) = _M_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,_Val,_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); + } + + // Insert/erase. + pair + insert_unique(const value_type& __x); + + iterator + insert_equal(const value_type& __x); + + iterator + insert_unique(iterator __position, const value_type& __x); + + iterator + insert_equal(iterator __position, const value_type& __x); + + template + void + insert_unique(_InputIterator __first, _InputIterator __last); + + template + void + insert_equal(_InputIterator __first, _InputIterator __last); + + 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; + } + } + + // Set operations. + iterator + find(const key_type& __x); + + const_iterator + find(const key_type& __x) const; + + size_type + count(const key_type& __x) const; + + iterator + lower_bound(const key_type& __x); + + const_iterator + lower_bound(const key_type& __x) const; + + iterator + upper_bound(const key_type& __x); + + const_iterator + upper_bound(const key_type& __x) const; + + pair + equal_range(const key_type& __x); + + pair + equal_range(const key_type& __x) const; + + // Debugging. + bool + __rb_verify() const; + }; + + template + inline bool + operator==(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); + } + + template + inline bool + operator<(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); + } + + template + inline bool + operator!=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + template + inline bool + operator>(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + template + inline void + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { __x.swap(__y); } + + template + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) + { + if (this != &__x) + { + // Note that _Key may be a constant type. + clear(); + _M_node_count = 0; + _M_key_compare = __x._M_key_compare; + if (__x._M_root() == 0) + { + _M_root() = 0; + _M_leftmost() = _M_header; + _M_rightmost() = _M_header; + } + else + { + _M_root() = _M_copy(__x._M_root(), _M_header); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_node_count = __x._M_node_count; + } + } + return *this; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + _M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Val& __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; + // Maintain _M_rightmost() pointing to max node. + if (__y == _M_rightmost()) + _M_rightmost() = __z; + } + _S_parent(__z) = __y; + _S_left(__z) = 0; + _S_right(__z) = 0; + _Rb_tree_rebalance(__z, _M_header->_M_parent); + ++_M_node_count; + return iterator(__z); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_equal(const _Val& __v) + { + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + while (__x != 0) + { + __y = __x; + __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert(__x, __y, __v); + } + + template + pair::iterator, + bool> + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_unique(const _Val& __v) + { + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + bool __comp = true; + while (__x != 0) + { + __y = __x; + __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __x = __comp ? _S_left(__x) : _S_right(__x); + } + iterator __j = iterator(__y); + if (__comp) + if (__j == begin()) + return pair(_M_insert(__x, __y, __v), true); + else + --__j; + if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair(_M_insert(__x, __y, __v), true); + return pair(__j, false); + } + + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + insert_unique(iterator __position, const _Val& __v) + { + if (__position._M_node == _M_header->_M_left) + { + // begin() + if (size() > 0 && + _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + else + return insert_unique(__v).first; + } + else if (__position._M_node == _M_header) + { + // end() + if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_unique(__v).first; + } + else + { + iterator __before = __position; + --__before; + if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v)) + && _M_key_compare(_KeyOfValue()(__v),_S_key(__position._M_node))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + } + else + return insert_unique(__v).first; + } + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_equal(iterator __position, const _Val& __v) + { + if (__position._M_node == _M_header->_M_left) + { + // begin() + if (size() > 0 && + !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + else + return insert_equal(__v); + } + else if (__position._M_node == _M_header) + { + // end() + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_equal(__v); + } + else + { + iterator __before = __position; + --__before; + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node)) + && !_M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + } + else + return insert_equal(__v); + } + } + + template + template + void + _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: + insert_equal(_II __first, _II __last) + { + for ( ; __first != __last; ++__first) + insert_equal(*__first); + } + + template + template + void + _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: + insert_unique(_II __first, _II __last) + { + for ( ; __first != __last; ++__first) + insert_unique(*__first); + } + + template + inline void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(iterator __position) + { + _Link_type __y = + (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node, + _M_header->_M_parent, + _M_header->_M_left, + _M_header->_M_right); + destroy_node(__y); + --_M_node_count; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) + { + pair __p = equal_range(__x); + size_type __n = distance(__p.first, __p.second); + erase(__p.first, __p.second); + return __n; + } + + template + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type + _Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc>:: + _M_copy(_Link_type __x, _Link_type __p) + { + // Structural copy. __x and __p must be non-null. + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; + + try + { + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) + { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); + } + } + catch(...) + { + _M_erase(__top); + __throw_exception_again; + } + return __top; + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::_M_erase(_Link_type __x) + { + // Erase without rebalancing. + while (__x != 0) + { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + destroy_node(__x); + __x = __y; + } + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + erase(iterator __first, iterator __last) + { + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) erase(__first++); + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + erase(const _Key* __first, const _Key* __last) + { + while (__first != __last) + erase(*__first++); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) + { + _Link_type __y = _M_header; // Last node which is not less than __k. + _Link_type __x = _M_root(); // Current node. + + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + iterator __j = iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + find(const _Key& __k) const + { + _Link_type __y = _M_header; // Last node which is not less than __k. + _Link_type __x = _M_root(); // Current node. + + while (__x != 0) + { + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + } + const_iterator __j = const_iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + count(const _Key& __k) const + { + pair __p = equal_range(__k); + size_type __n = distance(__p.first, __p.second); + return __n; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + lower_bound(const _Key& __k) + { + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + lower_bound(const _Key& __k) const + { + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + upper_bound(const _Key& __k) + { + _Link_type __y = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + upper_bound(const _Key& __k) const + { + _Link_type __y = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); + } + + template + inline + pair::iterator, + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator> + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + equal_range(const _Key& __k) + { return pair(lower_bound(__k), upper_bound(__k)); } + + template + inline + pair::const_iterator, + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator> + _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc> + ::equal_range(const _Key& __k) const + { + return pair(lower_bound(__k), + upper_bound(__k)); + } + + inline int + __black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) + { + if (__node == 0) + return 0; + int __sum = 0; + do + { + if (__node->_M_color == _M_black) + ++__sum; + if (__node == __root) + break; + __node = __node->_M_parent; + } + while (1); + return __sum; + } + + template + bool + _Rb_tree<_Key,_Val,_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 == _M_red) + if ((__L && __L->_M_color == _M_red) + || (__R && __R->_M_color == _M_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; + } } // namespace std -#endif /* __GLIBCPP_INTERNAL_TREE_H */ - -// Local Variables: -// mode:C++ -// End: +#endif diff --git a/libstdc++-v3/include/std/std_limits.h b/libstdc++-v3/include/std/std_limits.h index 91125ef94954..d2b57e39cc75 100644 --- a/libstdc++-v3/include/std/std_limits.h +++ b/libstdc++-v3/include/std/std_limits.h @@ -908,140 +908,52 @@ namespace std // // The primary class traits // - template - struct numeric_limits - { - static const bool is_specialized = false; + struct __numeric_limits_base + { + static const bool is_specialized = false; + 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 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 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 + struct numeric_limits : public __numeric_limits_base + { static _Tp min() throw() { return static_cast<_Tp>(0); } static _Tp max() throw() { return static_cast<_Tp>(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 _Tp epsilon() throw() { return static_cast<_Tp>(0); } static _Tp round_error() throw() { return static_cast<_Tp>(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 _Tp infinity() throw() { return static_cast<_Tp>(0); } static _Tp quiet_NaN() throw() { return static_cast<_Tp>(0); } static _Tp signaling_NaN() throw() { return static_cast<_Tp>(0); } static _Tp denorm_min() throw() { return static_cast<_Tp>(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 - const bool - numeric_limits<_Tp>::is_specialized; - - template - const int - numeric_limits<_Tp>::digits; - - template - const int - numeric_limits<_Tp>::digits10; - - template - const bool - numeric_limits<_Tp>::is_signed; - - template - const bool - numeric_limits<_Tp>::is_integer; - - template - const bool - numeric_limits<_Tp>::is_exact; - - template - const int - numeric_limits<_Tp>::radix; - - template - const int - numeric_limits<_Tp>::min_exponent; - - template - const int - numeric_limits<_Tp>::min_exponent10; - - template - const int - numeric_limits<_Tp>::max_exponent; - - template - const int - numeric_limits<_Tp>::max_exponent10; - - template - const bool - numeric_limits<_Tp>::has_infinity; - - template - const bool - numeric_limits<_Tp>::has_quiet_NaN; - - template - const bool - numeric_limits<_Tp>::has_signaling_NaN; - - template - const float_denorm_style - numeric_limits<_Tp>::has_denorm; - - template - const bool - numeric_limits<_Tp>::has_denorm_loss; - - template - const bool - numeric_limits<_Tp>::is_iec559; - - template - const bool - numeric_limits<_Tp>::is_bounded; - - template - const bool - numeric_limits<_Tp>::is_modulo; - - template - const bool - numeric_limits<_Tp>::traps; - - template - const bool - numeric_limits<_Tp>::tinyness_before; - - template - const float_round_style - numeric_limits<_Tp>::round_style; - // Now there follow 15 explicit specializations. Yes, 15. Make sure - // you get the count right. - + // you get the count right. template<> struct numeric_limits { diff --git a/libstdc++-v3/mkcheck.in b/libstdc++-v3/mkcheck.in index c65a144c2c88..b104244dba61 100755 --- a/libstdc++-v3/mkcheck.in +++ b/libstdc++-v3/mkcheck.in @@ -362,8 +362,8 @@ test_file() else # the file did not compile/link. printf "\n" >> $LOG_FILE -# `cat compile.out >> $LOG_FILE` -# rm compile.out + `cat compile.out >> $LOG_FILE` + rm compile.out RESULT="-b" TEXT="0" DATA="0" diff --git a/libstdc++-v3/src/limits.cc b/libstdc++-v3/src/limits.cc index 3fc3dcb8fb30..294673ea1869 100644 --- a/libstdc++-v3/src/limits.cc +++ b/libstdc++-v3/src/limits.cc @@ -1,6 +1,6 @@ // Static data members of -*- C++ -*- numeric_limits classes -// Copyright (C) 1999, 2001 Free Software Foundation, Inc. +// Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -38,6 +38,29 @@ namespace std { + const bool __numeric_limits_base::is_specialized; + const int __numeric_limits_base::digits; + const int __numeric_limits_base::digits10; + const bool __numeric_limits_base::is_signed; + const bool __numeric_limits_base::is_integer; + const bool __numeric_limits_base::is_exact; + const int __numeric_limits_base::radix; + const int __numeric_limits_base::min_exponent; + const int __numeric_limits_base::min_exponent10; + const int __numeric_limits_base::max_exponent; + const int __numeric_limits_base::max_exponent10; + const bool __numeric_limits_base::has_infinity; + const bool __numeric_limits_base::has_quiet_NaN; + const bool __numeric_limits_base::has_signaling_NaN; + const float_denorm_style __numeric_limits_base::has_denorm; + const bool __numeric_limits_base::has_denorm_loss; + const bool __numeric_limits_base::is_iec559; + const bool __numeric_limits_base::is_bounded; + const bool __numeric_limits_base::is_modulo; + const bool __numeric_limits_base::traps; + const bool __numeric_limits_base::tinyness_before; + const float_round_style __numeric_limits_base::round_style; + // bool const bool numeric_limits::is_specialized; const int numeric_limits::digits; diff --git a/libstdc++-v3/src/locale-inst.cc b/libstdc++-v3/src/locale-inst.cc index 324b07e93698..9e449e66bda8 100644 --- a/libstdc++-v3/src/locale-inst.cc +++ b/libstdc++-v3/src/locale-inst.cc @@ -43,126 +43,124 @@ namespace std { - typedef ostreambuf_iterator obuf_iterator; - typedef istreambuf_iterator ibuf_iterator; - typedef ostreambuf_iterator wobuf_iterator; - typedef istreambuf_iterator wibuf_iterator; - // moneypunct, money_get, and money_put template class moneypunct; template class moneypunct; template class moneypunct_byname; template class moneypunct_byname; - template class money_get; - template class money_put; + template class money_get >; + template class money_put >; #ifdef _GLIBCPP_USE_WCHAR_T template class moneypunct; template class moneypunct; template class moneypunct_byname; template class moneypunct_byname; - template class money_get; - template class money_put; + template class money_get >; + template class money_put >; #endif // numpunct, numpunct_byname, num_get, and num_put template class numpunct; template class numpunct_byname; - template class num_get; - template class num_put; + template class num_get >; + template class num_put >; template - obuf_iterator - num_put:: - _M_convert_int(obuf_iterator, ios_base&, char, char, char, long) const; + ostreambuf_iterator + num_put >:: + _M_convert_int(ostreambuf_iterator, ios_base&, char, char, char, + long) const; template - obuf_iterator - num_put:: - _M_convert_int(obuf_iterator, ios_base&, char, char, char, + ostreambuf_iterator + num_put >:: + _M_convert_int(ostreambuf_iterator, ios_base&, char, char, char, unsigned long) const; #ifdef _GLIBCPP_USE_LONG_LONG template - obuf_iterator - num_put:: - _M_convert_int(obuf_iterator, ios_base&, char, char, char, + ostreambuf_iterator + num_put >:: + _M_convert_int(ostreambuf_iterator, ios_base&, char, char, char, long long) const; template - obuf_iterator - num_put:: - _M_convert_int(obuf_iterator, ios_base&, char, char, char, + ostreambuf_iterator + num_put >:: + _M_convert_int(ostreambuf_iterator, ios_base&, char, char, char, unsigned long long) const; #endif template - obuf_iterator - num_put:: - _M_convert_float(obuf_iterator, ios_base&, char, char, double) const; + ostreambuf_iterator + num_put >:: + _M_convert_float(ostreambuf_iterator, ios_base&, char, char, + double) const; template - obuf_iterator - num_put:: - _M_convert_float(obuf_iterator, ios_base&, char, char, + ostreambuf_iterator + num_put >:: + _M_convert_float(ostreambuf_iterator, ios_base&, char, char, long double) const; #ifdef _GLIBCPP_USE_WCHAR_T template class numpunct; template class numpunct_byname; - template class num_get; - template class num_put; + template class num_get >; + template class num_put >; template - wobuf_iterator - num_put:: - _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char, long) const; + ostreambuf_iterator + num_put >:: + _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, char, + char, long) const; template - wobuf_iterator - num_put:: - _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char, - unsigned long) const; + ostreambuf_iterator + num_put >:: + _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, char, + char, unsigned long) const; #ifdef _GLIBCPP_USE_LONG_LONG template - wobuf_iterator - num_put:: - _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char, - long long) const; + ostreambuf_iterator + num_put >:: + _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, char, + char, long long) const; template - wobuf_iterator - num_put:: - _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char, - unsigned long long) const; + ostreambuf_iterator + num_put >:: + _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, char, + char, unsigned long long) const; #endif template - wobuf_iterator - num_put:: - _M_convert_float(wobuf_iterator, ios_base&, wchar_t, char, + ostreambuf_iterator + num_put >:: + _M_convert_float(ostreambuf_iterator, ios_base&, wchar_t, char, double) const; template - wobuf_iterator - num_put:: - _M_convert_float(wobuf_iterator, ios_base&, wchar_t, char, + ostreambuf_iterator + num_put >:: + _M_convert_float(ostreambuf_iterator, ios_base&, wchar_t, char, long double) const; #endif // time_get and time_put template class __timepunct; - template class time_put; - template class time_put_byname; - template class time_get; - template class time_get_byname; + template class time_put >; + template class time_put_byname >; + template class time_get >; + template class time_get_byname >; #ifdef _GLIBCPP_USE_WCHAR_T template class __timepunct; - template class time_put; - template class time_put_byname; - template class time_get; - template class time_get_byname; + template class time_put >; + template class time_put_byname >; + template class time_get >; + template class time_get_byname >; #endif // messages @@ -198,18 +196,7 @@ namespace std #endif // use_facet - template - const numpunct& - use_facet >(const locale&); - - template - const num_put& - use_facet >(const locale&); - - template - const num_get& - use_facet >(const locale&); - + // NB: use_facet is specialized template const codecvt& use_facet >(const locale&); @@ -218,6 +205,18 @@ namespace std const collate& use_facet >(const locale&); + template + const numpunct& + use_facet >(const locale&); + + template + const num_put& + use_facet >(const locale&); + + template + const num_get& + use_facet >(const locale&); + template const moneypunct& use_facet >(const locale&); @@ -226,23 +225,31 @@ namespace std const moneypunct& use_facet >(const locale&); + template + const money_put& + use_facet >(const locale&); + + template + const money_get& + use_facet >(const locale&); + template const __timepunct& use_facet<__timepunct >(const locale&); + template + const time_put& + use_facet >(const locale&); + + template + const time_get& + use_facet >(const locale&); + + template + const messages& + use_facet >(const locale&); + #ifdef _GLIBCPP_USE_WCHAR_T - template - const numpunct& - use_facet >(const locale&); - - template - const num_put& - use_facet >(const locale&); - - template - const num_get& - use_facet >(const locale&); - template const codecvt& use_facet >(locale const&); @@ -251,6 +258,18 @@ namespace std const collate& use_facet >(const locale&); + template + const numpunct& + use_facet >(const locale&); + + template + const num_put& + use_facet >(const locale&); + + template + const num_get& + use_facet >(const locale&); + template const moneypunct& use_facet >(const locale&); @@ -258,72 +277,147 @@ namespace std template const moneypunct& use_facet >(const locale&); + + template + const money_put& + use_facet >(const locale&); + + template + const money_get& + use_facet >(const locale&); template const __timepunct& use_facet<__timepunct >(const locale&); + + template + const time_put& + use_facet >(const locale&); + + template + const time_get& + use_facet >(const locale&); + + template + const messages& + use_facet >(const locale&); #endif // has_facet + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + template bool has_facet >(const locale&); + template bool has_facet >(const locale&); + template bool has_facet >(const locale&); + template bool - has_facet >(const locale&); + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet<__timepunct >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); #ifdef _GLIBCPP_USE_WCHAR_T + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + template bool has_facet >(const locale&); + template bool has_facet >(const locale&); + template bool has_facet >(const locale&); + template bool - has_facet >(const locale&); + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet<__timepunct >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); + + template + bool + has_facet >(const locale&); #endif - // // iterator - // typedef vector vec_pfacet; - template - void - vec_pfacet:: - insert(vec_pfacet::iterator, vec_pfacet::size_type, - const vec_pfacet::value_type&); - template - void - vec_pfacet:: - _M_fill_insert(vec_pfacet::iterator, vec_pfacet::size_type, - const vec_pfacet::value_type&); + template class vector; + template class __normal_iterator >; + template class __normal_iterator >; - - // // locale - // - typedef istreambuf_iterator > istreambuf_iter; - typedef ostreambuf_iterator > ostreambuf_iter; - -#ifdef _GLIBCPP_USE_WCHAR_T - typedef istreambuf_iterator > wistreambuf_iter; - typedef ostreambuf_iterator > wostreambuf_iter; -#endif - - template - bool - locale::operator()(const string&, const string&) const; - template char* __add_grouping(char*, char, char const*, char const*, @@ -344,12 +438,6 @@ namespace std streamsize, streamsize, const bool); #ifdef _GLIBCPP_USE_WCHAR_T - template - bool - locale::operator()(const wstring&, const wstring&) const; - - typedef ostreambuf_iterator wostreambuf_iter; - template wchar_t* __add_grouping(wchar_t*, wchar_t, char const*, char const*, diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index 43e910333e9d..d2fd76316031 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -63,7 +63,7 @@ namespace std const size_t locale::_S_num_categories; const size_t locale::_S_num_facets; - // Definitions for locale::id of standard facets. + // Definitions for locale::id of standard facets that are specialized. locale::id ctype::id; locale::id codecvt::id; diff --git a/libstdc++-v3/src/stl-inst.cc b/libstdc++-v3/src/stl-inst.cc index 43cef9e6d2ce..94d26b33d237 100644 --- a/libstdc++-v3/src/stl-inst.cc +++ b/libstdc++-v3/src/stl-inst.cc @@ -34,16 +34,11 @@ #include #include #include -#include -#include namespace std { - const int __stl_threshold = 16; - const int __stl_chunk_size = 7; - const int __WORD_BIT = int(CHAR_BIT*sizeof(unsigned int)); - const _Rb_tree_Color_type _S_rb_tree_red = false; - const _Rb_tree_Color_type _S_rb_tree_black = true; + template class allocator; + template class allocator; template class __malloc_alloc_template<0>; @@ -55,5 +50,4 @@ namespace std void vector:: _M_insert_aux(vector::iterator, unsigned int const &); - } // namespace std diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits.cc b/libstdc++-v3/testsuite/18_support/numeric_limits.cc index 6cbeacb4d03b..bf9d9e0c35d5 100644 --- a/libstdc++-v3/testsuite/18_support/numeric_limits.cc +++ b/libstdc++-v3/testsuite/18_support/numeric_limits.cc @@ -55,6 +55,7 @@ DEFINE_EXTREMA(long double, LDBL_MIN, LDBL_MAX); template void test_extrema() { + bool test = true; VERIFY( extrema::min == std::numeric_limits::min() ); VERIFY( extrema::max == std::numeric_limits::max() ); } @@ -73,6 +74,7 @@ template<> void test_extrema() { typedef long double T; + bool test = true; VERIFY( (extrema::min - std::numeric_limits::min()) < std::numeric_limits::epsilon() ); VERIFY( (std::numeric_limits::min() - extrema::min) @@ -92,6 +94,7 @@ void test_extrema() void test_sign() { + bool test = true; VERIFY( std::numeric_limits::is_signed == char_is_signed ); VERIFY( std::numeric_limits::is_signed == true ); VERIFY( std::numeric_limits::is_signed == false ); @@ -230,9 +233,3 @@ int main() return 0; } - - - - - - diff --git a/libstdc++-v3/testsuite/22_locale/operators.cc b/libstdc++-v3/testsuite/22_locale/operators.cc index 9037dd872be2..f0e40d4a1165 100644 --- a/libstdc++-v3/testsuite/22_locale/operators.cc +++ b/libstdc++-v3/testsuite/22_locale/operators.cc @@ -1,6 +1,6 @@ // 2000-09-11 Benjamin Kosnik -// Copyright (C) 2000, 2001 Free Software Foundation +// Copyright (C) 2000, 2001, 2002 Free Software Foundation // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -47,9 +47,9 @@ void test01() } // bool operator()(const string_type&, const string_type&) const -typedef std::collate ccollate; long gnu_count; -class gnu_collate: public ccollate + +class gnu_collate: public std::collate { protected: virtual int @@ -79,7 +79,7 @@ void test02() int main () { test01(); - + test02(); return 0; }